Do shell script - How to use AppleScript variables & stringing commands together

Goal:
Create an app via AppleScript that utilizes ffmpeg to concatenate multiple .mp4 files into a single .mp4 file.
•••••••••••

I need a little help with the workflow here.
I currently have found terminal commands that accomplish what I want to do but now I need to wrap it into an app that an end user can work with.

Working Terminal Commands

  1. Provide file path to .mp4 files

cd path/to/files

  1. Create an ffmpeg friendly formatted .txt file containing a list of .mp4 files found in this directory

for f in *.MP4; do
echo “file ‘$f’” >> list.txt
done

  1. Have ffmpeg read the files from the list in step 2, concatenate them into a single file (in the same directory)

ffmpeg -f concat -safe 0 -i list.txt -c copy output.mp4

•••••••••••••

So I have the general steps figured out from a basic command line perspective.
I’ve never written a shell script or used do shell script in Script Debugger so I need help with the steps

I assume the steps to create an app for an end user go as follows.

  1. Prompt the user to locate the folder containing the clips they want to merge.
set loc to choose folder with prompt "-- Choose the folder containing your source media --" --sets the source directory
  1. Prompt the user to name the merged clip
set fileName to text returned of (display dialog "Enter the Name of the Merged Clip" default answer "" with title "Name the Merged Clip") & ".mp4" --sets name of merged clip with .mp4 extension
  1. Execute Shell Script that does the following
    A) Change Directory to path user provided in step 1 of the AppleScript app
    B) Creates list.txt file as outlined in working terminal command number 2
    C) Runs working terminal command number 3 while replacing output.mp4 to the variable, fileName

I am lost on how to use do Shell Script to make step 3 work
I believe I would need to provide the shell script the quoted form of the POSIX path of the variable, loc which I have done with

set pLoc to quoted form of POSIX path of loc as string -- converts loc to POSIX

Script Debugger gives me no user feedback when I run

do shell script "cd " & pLoc

Script Debugger gives me a compile error “Expected end of line, etc. but found unknown token” if I run

do shell script "cd " & pLoc ; pwd --trying to see  what directory I'm in, I've also tried echo

I’ve been trying to figure this out for a while with little success.

Can someone please share how to write the do shell script command to change the directory to the variable pLoc? Also, I will then want to run the other two terminal commands. How do I string multiple commands together?

I thought you used “;” to do that, but I was getting a compile error when trying that earlier.

Thank You in advance. - Ben Brodbeck

I have the following working for me.

set fileName to text returned of (display dialog "Enter the Name of the Merged Clip" default answer "Merged Clip Name Here" with title "Name the Merged Clip") & ".mp4" --sets name of merged clip with .mp4 extension
set pLoc to quoted form of POSIX path of loc as string -- converts loc to POSIX
do shell script "cd " & pLoc & "; for f in *.MP4; do
echo “file ‘$f’” >> list.txt
done

Now when I try to add the following line to my do shell script it no longer works.

; ffmpeg -f concat -safe 0 -i list.txt -c copy " & fileName

I get the following error

I know I have ffmpeg installed, because I’ve been running it in Terminal.
I’m guessing I need to put all of this into an executable .sh file so that the shell is defined as I can’t see any other reason that error would come up.

Any advice would be helpful. Thank You.

do shell script doesn’t source your $PATH. You need to specify the full path to the executable, such as /usr/local/bin/ffmpeg.

See Technical Note TN2065: do shell script in AppleScript for details.

Thanks,

I found the ffmpeg command at: /usr/local/Cellar/ffmpeg/4.4.1_2/bin/ffmpeg
now if I call ffmpeg with the full path I get an error about my list.txt file that reads “Invalid data found when processing input”. If I run the same commands in terminal I don’t have this issue. I’m not sure what I should be troubleshooting at this point. Any thoughts would be appreciated. Thank You.

That path is specific to that version of ffmpeg & will break when it is updated. If you’re using homebrew, the path I gave is likely the path you should use (it’s symlinked to the correct version). You can enter which ffmpeg in Terminal to get the path you should use.

Your code isn’t formatted correctly in Markdown, so it makes it difficult to read, especially for quoting issues. Use triple backticks for code blocks.

I check and that is the correct location. Here’s what my script currently looks like.

set loc to choose folder with prompt "-- Choose the folder containing your source media --" --sets the source directory
set fileName to text returned of (display dialog "Enter the Name of the Merged Clip" default answer "Merged Clip Name Here" with title "Name the Merged Clip") & ".mp4" --sets name of merged clip with .mp4 extension
set pLoc to quoted form of POSIX path of loc as string -- converts loc to POSIX
set ffMPEG to quoted form of "/usr/local/bin/ffmpeg"
do shell script "cd " & pLoc & "; for f in *.MP4; do
echo “file ‘$f’” >> list.txt
done" & "; " & ffMPEG & " -f concat -safe 0 -i list.txt -c copy " & fileName

When I step through this script I get an error on the do shell script.CleanShot 2021-11-10 at 15.49.35
However, the list.txt file is successfully created and looks just like the list.txt file I would get when I run these commands from Terminal.

I don’t know Markdown outside of making something bold. I apologize for making things difficult.

See here: Markdown Cheatsheet · adam-p/markdown-here Wiki · GitHub

You can use triple backticks (no need to specify language).

1 Like

The script you posted has some curly quotes in the shell script that won’t parse correctly. Make sure these are standard straight quotes.

Also, the final line should end with & quoted form of fileName to handle spaces in the file name.

Once you fix up the quotes, I can have another look, but the echo “file ‘$f’” >> list.txt looks suspicious for quoting issues. It’s likely inserting the literal word file into your list.txt.

1 Like

I want the word file in my list.

If I had a folder with

clip 1.mp4
clip 2.mp4

The list.txt file that I create should read

“file ‘clip 1.mp4’”
“file ‘clip 2.mp4’”

I really appreciate the help.
Kids are getting home now. I’ll have another look in the morning and see what I can figure out.
Again, big thanks for the help.

No problem. You will likely need something like this (you need to escape the double quotes).

echo \"file '$f'\" >> list.txt

Thank You so much for mentioning the curly quotes! I’m not sure how those got in there. I was doing a lot of copy/pasting yesterday & then my 6-year-old daughter was crawling all over me so I probably passed the human test on that one.

Also, escaping the echo line…
echo \"file '$f'\" >> list.txt
…that was spot on.
I now have a working version of my script where I get a concatenated .mp4 file which is awesome.

So now I have a few objectives I want to add from a fit and finish perspective.

1.) I would like to make the list.txt file hidden from the user & delete it after the concatenated file is created.
• I know how to do that in the command line, so I imagine I just add that to my do shell script commands.

2.) Make a progress bar appear so the user knows that the concatenation is happening and where they are in the process.
• I have no idea how to do that so any guidance/suggestions are appreciated

Thank You again!

For #1, you can do that within the shell script by creating the file in a different folder (specify the full path – the temporary folder would be a good place), or by naming it will a leading period, and then rming it.

For #2, AppleScript has special progress variables that will automatically show a progress bar if you set them. Note that these only appear as a window for applets. See Mac Automation Scripting Guide: Displaying Progress.

I completed item 1 using the leading period and rm command, so we’re good there.
For item 2, the progress bar didn’t really give the user any idea of where they were in the process. It stayed at what looked like 2% complete the whole time, didn’t say how long there was left and then just disappeared. I feel like I need a better solution here. I was looking at this post here: Example of "Application enhanced" progress bar - AppleScript - Late Night Software Ltd.
I like that this one seems to give the user feedback. I’m just not clear on how to incorporate it into my script. Any thoughts on how I could incorporate that?

Thank You.

The problem you’re likely to have is that there’s no good way for ffmpeg to report its progress to AppleScript (do shell script only returns when the shell script is complete; there is no easy way for it to report its progress).

A potential workaround is to automate Terminal with AppleScript, using its do script command and have ffmpeg report its progress to the user in a Terminal window.

to doShellScriptInTerminal(script_text)
	
	tell application "Terminal"
		run
		set tab_reference to do script script_text
		activate
		return tab_reference
	end tell
	
end doShellScriptInTerminal

Which you would call with your existing shell script:

my doShellScriptInTerminal("SHELL SCRIPT HERE")
1 Like

This topic was automatically closed 24 hours after the last reply. New replies are no longer allowed.