The purpose of this long, arduous venture was to find a way to simply reduce the size of video files recorded with a Canon ELPH 330 HS digicam. This camera, and surely others, records 720p, 30fps video at a bitrate of 24Mbps, which is at least twice as much as should be necessary. Remember this is a consumer level point-&-shoot whose main draws were: 10x optical zoom; pocketable. This high bitrate results in a 6 minute video being over 1GB. Too much.
Initially done manually with QuickTime 7 Pro, I was able to get the bitrate down to 9600kbps while being nearly visually identical. Literally close enough to be well worth it. Unfortunately QuickTime does not let you export your custom encode settings. So even though it is easy enough to open a video and choose “Use last settings” from the dialog, anytime another option was chosen, all was lost. Not only that, you cannot even use AppleScript to tell QuickTime how to encode a video. Boo!
Enter FFmpeg. What an amazing tool that is. It goes well beyond my simple need. The problem I encountered with it is I could not get a visually identical file from it. Color, brightness, gamma- something was always off, despite it having some serious options for altering the output. I’m not going to call it impossible to achieve what I wanted, but it was obviously arcane magic I of finite patience found irritating. Back to QuickTime.
On a whim I dusted off Handbrake to see if it would be able to get me a decently small, visually acceptable encoding. I knew it would let you save your export settings, so this was a plus. Of course, it does have a more typical usage, so I hadn’t really thought of it. Luckily I did, because it worked like a charm. It will make even smaller files than QuickTime and still be just as nearly visually identical as I had been encoding before. Wonderful! Now to AppleScript it. But wait, there’s more?
There is a command line tool for Handbrake called, oddly enough, handbrakecli. Now we’re talking. It can use it’s own pre-set encoding settings, your own settings saved through the Handbrake GUI, and it takes command line options for decoding and encoding videos. While not as robust as ffmpeg (one glaring omission is the ability to copy such a basic thing as the create date in the movie header atom), it fills my needs just fine.
Remember, this is written for files recorded with a Canon PowerShot digicam which creates MP4 files in the .MOV container. The encoding options may not be suitable for other cameras.
BE AWARE that due to handbrakecli’s limitation of not copying the video create date you will want to find another way to get that information back. A companion script to do just this is here: Copy video create date from original file
(* http://strawhousepig.net
This script will ask for a video to re-encode with the goal being to reduce the bit rate and thus file size.
Uses the HandBrakeCLI engine and libx264 and aac codecs.
See 'handbrakecli -help' for more info on the options.
The new video file will be put inside a folder in the directory of the original. This folder will be created if it does not yet exist.
Unfortunately, and unlike ffmpeg, handbrakecli does not offer a way to copy metadata. Not even such rudimentary data as create time in the movie header atom, and the devs are apparently not interested in including it. WTF?
Thankfully 'exiftool' can achieve this. And if file system times are your jam, 'touch' for mod dates with a side of 'setfile' for create date will do that trick.
*)
set enc_options to " -E ca_aac -B 160 -O -e x264 -q 17 --encoder-preset slow" -- Leading space here.
set enc_dir to my name -- Name of folder that will be made and/or used in the directory containing the chosen video. [my name] will return the name of this script.
tell application "Finder"
try
set old_file to choose file with prompt "Select a video to re-encode."
set out_dir to (container of old_file as text) & enc_dir
if not (exists folder out_dir) then make new folder at (container of old_file) with properties {name:enc_dir}
set new_file to out_dir & ":" & name of old_file
tell application "Terminal" to do script "/usr/local/bin/handbrakecli -i " & quoted form of POSIX path of old_file & " -o " & quoted form of POSIX path of new_file & enc_options
end try
end tell