A little while ago I approached the subject of scripting automated encoding for HTML5 video formats. I started using the process regularly as I built the Blogsmith Bundle video site. Pretty soon I got some help from friend and TUAW editor Mike Rose, and working together we refined the script and improved the speed tremendously. It was built for use on Mac OS X, but with just a few lines modified, it should work on any *NIX system.
What it does
The script is specifically designed to take an MPEG-4, H.264 file, move it to a new folder based on the filename, create WEBM and OGV versions of it in the new folder, and upload the whole folder to a server using
rsync. SSH information and target directories are specified in the config at the top of the script. At the end, it takes what it knows about the files and filenames and creates a TextMate Markdown blog template, inserts the video shortcode for the VideoJS WordPress plugin (which is common syntax for other plugins as well) and opens it for editing in TextMate. The
rsync command really needs keyless SSH login for this to be considered fully-automated.
If you run this script with Hazel, you can just render an H.264 video (
.mov files that pass the H.264 test1 will automatically be renamed to
.mp4) to that folder from your screen-recording application of choice, sit back for a few minutes (or start writing the post) and wait for the pre-populated TextMate blog post to pop open. Then type or paste your text in, hit Control-Command-P (assuming you’re set up for TextMate->WordPress blogging) and your video is posted.
The first thing that happened in this rewrite was a major simplification of the WEBM encoding process, which now only takes a third of the time it did before and the files are not significantly larger in most cases. They may even look better. The old command involved two passes, one of them turning out to be unnecessary;
ffmpeg is smarter than I thought. The new command (using the variables from the script) is just
/usr/local/bin/ffmpeg -i "$FILENAME" -b 614400 -s $MAXSIZE -aspect 16:9 "$BASENAME".webm.
I also added better logging, optional progress reports with Growl, batch file handling and a few other refinements. The logging, if enabled in the config at the top, will output information including processing time for each file and total processing time to STDOUT (command line) and to the system log where you can watch it from Console. If you enable growl notifications, the messages at the beginning and end of each conversion will be “growled” on your screen.
Using the script
You’ll need a couple of additional utilities to do the conversions.
To run the script and do the encoding, you’ll need
ffmpeg2theora. You can install
ffmpeg from Homebrew (
brew install ffmpeg) quite easily, if you’re set up for that. You can also pull the binary out of ffmpegX with a few simple steps. You can, of course, build your own if you have the developer tools installed.
ffmpeg2theora (needed for OGV conversion) no longer appears to be available from
brew, but there are OS X binaries (and source) available for download.
The script is below. You’ll want to modify the information in the configuration section at the top, and modify the template output at the bottom to suit your needs. Anything between
POSTTEMPLATE is freeform text that you can edit in any way you like, including the use of $variables. If you’d rather do something such as copy a shortcode to your clipboard and show a Growl message, just use
growlnotify. You could also just comment out the template part and let Hazel tell you when it’s done, if you want to handle things more manually. I’ll let you work out the details on that.
Command line usage
To use the script from the command line, save it as “html5encode.sh” somewhere in your path, change to its parent folder in Terminal and run
chmod a+x html5encode.sh. The you can run it on any h.264 .mov or .mp4 file and it will handle the rest. It also handles batches, so you can specify multiple targets or use
*.mp4 to run it on all .mp4 files in a folder. It will process them one by one, creating new folders for each.
If you want to run it with Hazel, you can follow the same procedure and set up a rule that runs a shell script when a .mov or .mp4 is detected in a watch folder. The script can then be run as a command or be pasted in its entirety into the Hazel script editor within the rule.
You should be able to pull off using this with OS X Folder Actions, as well, but I haven’t played with that yet.
Bonus tip: If you name your original .mov or .mp4 file with a CamelCased name, it will break apart the filename and create the title of your post based on it. Not an essential feature, but kind of nifty. Well, I think so anyway.
Hopefully this will make a few people’s lives easier. Mike and I have battle tested it and it seems to be a pretty great fit for our needs. If you modify it for your own needs, please share (with credit) so that it can become as well-rounded as possible!
The script runs a quick check using
mdlsto look for the h.264 codec. It will skip the file if it doesn’t match the criteria. It doesn’t check for AAC, but assumes that you know what you’re doing to some extent. If you’re running Hazel, just check for the specific extension you’re rendering to (
.mp4) to avoid any hassle from the start.↩