How to run a regular bat file on Apple Script (ffmpeg)

I’m such a noobie when it comes to AppleScript and OS. But Ive been working with Windows for work and all works smoothly when I create bat files. But now we recently got into Apple Macbook. Now im re-learning the codes for AppleScript. I do have ffmpeg installed and updated on this MacBook. Here’s a simple bat file on what I do on Windows.

echo on
forfiles /p D:\eze-ffmpeg\cvt /m . /c “CMD /C ffmpeg -i @file -c:v libx264 -vf scale=1920:1080 -aspect:v 16:9 -b:v 6M -c:a aac -b:a 192k D:\eze-ffmpeg\cvt\@fname-CVT.mp4

It’s just a simple redo or resize of an MP4 that is in that folder.

Since you have the bat file using hard coded paths for the input files and output files, do you have specific paths you intend to use on the Mac?

Also, the analogous thing to a Windows bat script is a Unix shell script, usually written in BASH. I believe ffmpeg being a command-line program will have continuous output going to the command prompt (or terminal in Unix). AppleScript does not have that capability when executing command-line commands. So it would have to send the command-line program to the background and have it’s continuous output sent to /dev/null or to a text file.

Hello! Well yes - Id change the path to a specific folder on the mac.

Also, FYI, i prefer HandBrakeCLI over ffmpeg

Do you have examples of the Folders you would want to use?
And what kind of file is the input file?

Here is a script I got working so far on a hard-coded mkv file.

use AppleScript version "2.4" -- Yosemite (10.10) or later
use scripting additions

on run
	do shell script "/usr/local/bin/ffmpeg -i ~/Star.Trek.Lower.Decks.S04E07.mkv -c:v libx264 -vf scale=1920:1080 -aspect:v 16:9 -b:v 6M -c:a aac -b:a 192k ~/Star.Trek.Lower.Decks.S04E07-CVT.mp4 > ~/ffmpeg-output.txt 2>&1 &"
	set progress description to "ffmpeg progress… (file \"" & "Star.Trek.Lower.Decks.S04E07.mkv" & "\")"
	set progress total steps to -1
	repeat while "ffmpeg" is in paragraphs of (do shell script "ps -u " & (short user name of (system info)) & " -c -o comm=")
		repeat 10 times
			set lastLine to do shell script "tail -n 1 ~/ffmpeg-output.txt"
			set myLine to paragraphs of lastLine
			if (count myLine) > 0 then
				set progress additional description to last item of myLine
			end if
			delay 1
		end repeat
		do shell script "> ~/ffmpeg-output.txt" -- clear out the output file so it doesn't grow too large
	end repeat
end run

It currently monitors the progress file and displays the last line in the Progress Bar
I Just have to add the looping for multiple files in a folder

Here is a version that loops thru a folder to find only video files and puts them in a sub-folder called “Converted-Movies”

use AppleScript version "2.4" -- Yosemite (10.10) or later
use scripting additions

on run
	local inFolder, outFolder, fileNames, fileExts, myFiles, OutFile, myLine, lastLine, tid
	set inFolder to "G-Speed:"
	set outFolder to POSIX path of (inFolder & "Converted-Movies:")
	set myFiles to {}
	tell application "System Events" to set {fileNames, fileExts} to {name, name extension} of disk items of folder inFolder
	
	repeat with i from 1 to count fileNames
		if item i of fileExts is in {"avi", "mp4", "m4v", "mov", "mkv", "mpg", "mpeg"} then
			set end of myFiles to item i of fileNames --, item i of fileExts}
		end if
	end repeat
	set tid to text item delimiters
	set text item delimiters to "."
	set inFolder to POSIX path of inFolder
	repeat with aFile in myFiles
		set OutFile to ((text items 1 thru -2 of aFile) as text) & ".mp4"
		do shell script "/usr/local/bin/ffmpeg -y -i " & (quoted form of (inFolder & aFile)) & " -c:v libx264 -vf scale=1920:1080 -aspect:v 16:9 -b:v 6M -c:a aac -b:a 192k " & (quoted form of (outFolder & OutFile)) & " > ~/ffmpeg-output.txt 2>&1 &"
		set progress description to "ffmpeg progress… (file \"" & aFile & "\")"
		set progress total steps to -1
		repeat while "ffmpeg" is in paragraphs of (do shell script "ps -u " & (short user name of (system info)) & " -c -o comm=")
			repeat 10 times
				set lastLine to do shell script "tail -n 1 ~/ffmpeg-output.txt"
				set myLine to paragraphs of lastLine
				if (count myLine) > 0 then
					set progress additional description to last item of myLine
				end if
				delay 1
			end repeat
			do shell script "> ~/ffmpeg-output.txt" -- clear out the output file so it doesn't grow too large
		end repeat
	end repeat
	set text item delimiters to tid
end run

Just out of curiosity, what file format are the input video files that you are converting?

Wow thank you for the reply.

Ow this is generally for work where as I would need to convert some clips when sometimes they are 4k, to bring them down. Or even when they are HD, to bring up the scale. Sometimes I would get multiple clips but would need to convert them to the proper resolution without losing the data rate.

I’ve tried the codes above but seems to not be working? I would have to edit the paths, correct?

Of course. Or we can add a dialog to the script asking for a folder. Is there a file format I’m missing that you need?

That would be great! Nope - just that file format above.

You didn’t tell me the file extensions of the files you are converting?
I looked above and couldn’t find any. Am i missing something?

Here is the version that will ask for a folder of videos, and then create a subfolder called “Converted-Movies”.

use AppleScript version "2.4" -- Yosemite (10.10) or later
use scripting additions

on run
	local inFolder, outFolder, fileNames, fileExts, myFiles, OutFile, tid
	set inFolder to (choose folder "Choose a folder of video files you want to convert…") as text
	set outFolder to inFolder & "Converted-Movies:"
	
	set myFiles to {}
	tell application "System Events" to set {fileNames, fileExts} to {name, name extension} of disk items of folder inFolder
	repeat with i from 1 to count fileNames
		if item i of fileExts is in {"avi", "mov", "mkv", "mpg", "mpeg"} then
			set end of myFiles to item i of fileNames --, item i of fileExts}
		end if
	end repeat
	set cf to count myFiles
	if cf > 0 then
		try
			alias outFolder -- tests if folder exists already
		on error -- folder doesn't exist, so create it
			try
				tell application "System Events" to make new folder with properties {name:"Converted-Movies"} at folder inFolder
			on error
				return false
			end try
		end try
		set inFolder to POSIX path of inFolder
		set outFolder to POSIX path of outFolder
		set tid to text item delimiters
		set text item delimiters to "."
		repeat with i from 1 to cf
			set aFile to item i of myFiles
			set OutFile to ((text items 1 thru -2 of aFile) as text) & ".mp4"
			--set shellCommand to "/usr/local/bin/ffmpeg -i " & (quoted form of (inFolder & aFile)) & " -c:v libx264 -vf scale=1920:1080 -aspect:v 16:9 -b:v 6M -c:a aac -b:a 192k " & (quoted form of (outFolder & OutFile)) & " > ~/ffmpeg-output.txt 2>&1 &"
			do shell script "/usr/local/bin/ffmpeg -y -i " & (quoted form of (inFolder & aFile)) & " -c:v libx264 -vf scale=1920:1080 -aspect:v 16:9 -b:v 6M -c:a aac -b:a 192k " & (quoted form of (outFolder & OutFile)) & " > ~/ffmpeg-output.txt 2>&1 &"
			set progress description to "ffmpeg progress… (file \"" & aFile & "\") " & i & " of " & cf
			set progress total steps to -1
			repeat while "ffmpeg" is in paragraphs of (do shell script "ps -u " & (short user name of (system info)) & " -c -o comm=")
				repeat 10 times
					set lastLine to do shell script "tail -n 1 ~/ffmpeg-output.txt"
					set myLine to paragraphs of lastLine
					if (count myLine) > 0 then
						set progress additional description to last item of myLine
					end if
					delay 1
				end repeat
				do shell script "> ~/ffmpeg-output.txt" -- clear out the output file so it doesn't grow too large
			end repeat
		end repeat
		set text item delimiters to tid
		do shell script "rm ~/ffmpeg-output.txt"
	end if
end run

Here is a version that uses HandBrakeCLI. It has better options (for me at least) than ffmpeg

use AppleScript version "2.4" -- Yosemite (10.10) or later
use scripting additions

on run
	local inFolder, outFolder, fileNames, fileExts, myFiles, OutFile, scriptOptions, tid
	set inFolder to (choose folder "Choose a folder of video files you want to convert…") as text
	set outFolder to inFolder & "Converted-Movies:"
	
	set myFiles to {}
	tell application "System Events" to set {fileNames, fileExts} to {name, name extension} of disk items of folder inFolder
	repeat with i from 1 to count fileNames
		if item i of fileExts is in {"avi", "mp4", "mov", "mkv", "mpg", "mpeg"} then
			set end of myFiles to item i of fileNames --, item i of fileExts}
		end if
	end repeat
	set cf to count myFiles
	if cf > 0 then
		try
			alias outFolder
		on error
			try
				tell application "System Events" to make new folder with properties {name:"Converted-Movies"} at folder inFolder
			on error
				return false
			end try
		end try
		set inFolder to POSIX path of inFolder
		set outFolder to POSIX path of outFolder
		set tid to text item delimiters
		set text item delimiters to "."
		repeat with i from 1 to cf
			set aFile to item i of myFiles
			set OutFile to ((text items 1 thru -2 of aFile) as text) & ".mp4"
			set scriptOptions to "/usr/local/bin/HandBrakeCLI -e x264 -q 22.0 -E ca_aac -6 dpl2 -B 192 -R 44.1 -X 1920"
			set scriptOptions to scriptOptions & " --crop-mode auto --non-anamorphic --no-comb-detect --no-deinterlace --no-decomb --no-detelecine --no-hqdn3d --no-chroma-smooth --no-unsharp --no-lapsharp --no-deblock --no-grayscale"
			set scriptOptions to scriptOptions & " -F -x Unparse: level=4.1:ref=4:direct=auto:subme=8:trellis=2:vbv-bufsize=78125:vbv-maxrate=62500:rc-lookahead=50"
			set scriptOptions to scriptOptions & " -i " & (quoted form of (inFolder & aFile)) & " -o " & (quoted form of (outFolder & OutFile)) & " > ~/hbcli-output.txt 2>&1 &"
			do shell script scriptOptions
			set progress description to "HandBrakeCLI progress… (file \"" & aFile & "\") " & i & " of " & cf
			set progress total steps to -1
			repeat while "HandBrakeCLI" is in paragraphs of (do shell script "ps -u " & (short user name of (system info)) & " -c -o comm=") --"ffmpeg"
				repeat 10 times
					set lastLine to do shell script "tail -n 1 ~/hbcli-output.txt"
					set myLine to paragraphs of lastLine
					if (count myLine) > 0 then
						set progress additional description to last item of myLine
					end if
					delay 1
				end repeat
				do shell script "> ~/hbcli-output.txt" -- clear out the output file so it doesn't grow too large
			end repeat
		end repeat
		do shell script "rm ~/hbcli-output.txt"
		set text item delimiters to tid
	end if
end run

HandBrakeCLI is a command-line executable too.

2 Likes

It’s neither here nor there but FYI, handbrake uses ffmpeg to do most under-the-hood things. While handbrake may be easier to work with for many purposes, one way or another you’re using ffmpeg.