Programming is a wonderful mix of art and science; source code is both a poem and a math problem. It should be as simple and elegant as it is functional and fast. This blog is about that (along with whatever else I feel like writing about).

Wednesday, December 14, 2005

HandBrake Wrapper Script

I've been encoding my DVD's lately using HandBrake for Linux. As far as I can tell, there isn't a GUI for the Linux version, though there is a very nice one for OS X. However, you don't need the GUI at all.

Once you have compiled HandBrake from source, you have everything you need. Except that the default options in the CLI program (HBTest) aren't exactly the greatest in the world. So every time you want to encode a movie, you have to type a long string of command line options which aren't strictly necessary, since they're the same every time. (I'm assuming you encode all your movies the same way, because that's what I do ... and who wants to worry about encoding each movie differently?)

I encode the video using the x264 codec at 700 kbps, and the audio using the faac codec at 96 kbps. I find that this gives a high enough quality rip that the artifacts aren't typically very apparent. In most cases, my encoded version is indistinguishable from the MPEG-2 version on the DVD, except for the small size.

Normally, I would have to type:
/home/sean/Desktop/HandBrake-0.7.0/HBTest -e x264 -E faac -2 -b 700 -B 96 -w 512 -i /dev/dvd -o This\ is\ the\ movie\ title.mp4

That's a lot of typing, especially considering the fact that all of it is the same every time except for the -o argument.

To save myself some time (it's a valuable couple of seconds!), I wrote a wrapper script in Python to use my defaults instead of HandBrake's.

Here it is.

Now all I have to type is:
./ 'This is the movie title.mp4'

Which of course is a lot faster.

I also decided that I might at some point forget to type a title for the movie, but I'd still want the movie to be ripped and encoded, and I could name it later. So my solution was that if nothing is passed in at the command line, it would get the current timestamp and use that as the filename. That should be unique enough that I'd be able to repeatedly encode things without setting a title and be able to go back and set their names later. It has the added bonus of keeping the files in chronological order, according to when they're ripped.

The next step is to take more command line options than just the movie title, so that the defaults can be changed if necessary. The first addition would be the ability to set the title to rip, in case you're ripping a TV show, or a movie where the main feature is (for whatever dastardly reason) not the first title.

This is a very simple script, but it makes my video encoding life a little simpler, and a little more pleasant. Hopefully it does the same for you.


Anonymous said...

thats an awesome script man, as looking for something just like that..was going to use bash but python is mucho better! thanks again

jeffc said...

Sean; oddly enough about the same time as this post was apparently made, I came to the same conclusion: handbrake for linux needed a python wrapper. I took a slightly different route (divx) but the core concepts are similar. First, I wrapped the basic defaults to rip a single track in a shell script, then wrote a python module to analyze a track to determine if it was a movie (65+ mins), a show (35-55 mins), a cartoon (17-25 mins) or a "special feature" (4-20 mins). Then I wrote a script to read the output of lsdvd, create an array of "tracks", then let the user select what they wanted (movie: 1st largest track only, show: all tracks meeting the show definition, cartoon: all tracks meeting the cartoon definition, and so on). It then used the disc title as the default although that can be overridden and rips everything. Movies come out as [disc_title].avi, shows come out as [disc_title_tracknum].avi.

The end result is I have one script that can almost automatically rip movies, episodic shows, special features discs and more. Oh and I added a "recordable" mode since stuff I burn from a stand-alone player tends to show twice as many tracks as there actually are.

Two areas of improvement that I am currently working on are having it automatically pick the english track (for anime subs) and as a refinement to the recordable issue but also as a fix for the case of discs like the recent Heroes Season 1 release, filtering out duplicate tracks.

Anyhow, my code is dodgy but it works reliably and is easy to extend if you want a copy write me at jeffc at love to compare notes. I also recently bought a book on GTK and am thinking of writing a GUI for Handbrake on linux. What would really knock this out of the ballpark is to find a way to use something like ndiswrapper on AnyDVD which would then (to me) represent the complete soup-to-nuts solution. AnyDVD is the only reason I still have any microsoft anything laying around....