Sunday, September 28, 2008

H264 encoding for video iPod

The below commands will use FFMPEG to create a video suitable for playback within both iTunes and on a video iPod.

You will need a source file as input and a filename for the resulting output. My source file came from the rendered output of a Cinelerra project that I had just completed. The output was a DVD resolution MPEG program stream, created from directions in my Beginner's Guide to Exporting Video from Cinelerra.

A Two-Step Process
Below are two sets of FFMPEG commands. These two commands encapsulate a "two pass" encoding method. On the first pass, FFMPEG examines the file to be encoded and creates an optimization index. On the second pass, FFMPEG renders the output file based on the optimizations present in the index file.

In the below example, I am encoding a typical DVD resolution (720x480, 1.5 aspect ratio) to the following container format, using the following codecs:
- MPEG4 container
- H264 video codec
- AAC audio codec

For HDV fans, if you wish to reduce your videos to an iPod compatible size, you may use a resolution of 720x400 in order to keep the aspect ratio similar to that of 720P content (1.78 aspect ratio). Though the 720x400 resolution exceeds Apples' recommendations, I've found that iTunes and the iPod will still accept videos encoded to this size.

1) First pass (create index of optimizations)
ffmpeg -y -i sourceFileName.ext -an -v 1 -threads 8 -vcodec h264 -b 500k -bt 175k -refs 1 -loop 1 -deblockalpha 0 -deblockbeta 0 -parti4x4 1 -partp8x8 1 -me full -subq 1 -me_range 21 -chroma 1 -slice 2 -bf 0 -level 30 -g 300 -keyint_min 30 -sc_threshold 40 -rc_eq 'blurCplx^(1-qComp)' -qcomp 0.7 -qmax 51 -qdiff 4 -i_qfactor 0.71428572 -maxrate 768k -bufsize 2M -cmp 1 -s 720x480 -f mp4 -pass 1 /dev/null

This first pass will create a file called x264_2pass.log that will be used as an implicit input to the second pass.

2) Second pass (render the output file)
ffmpeg -y -i sourceFileName.ext -v 1 -threads 8 -vcodec h264 -b 500k -bt 175k -refs 1 -loop 1 -deblockalpha 0 -deblockbeta 0 -parti4x4 1 -partp8x8 1 -me full -subq 6 -me_range 21 -chroma 1 -slice 2 -bf 0 -level 30 -g 300 -keyint_min 30 -sc_threshold 40 -rc_eq 'blurCplx^(1-qComp)' -qcomp 0.7 -qmax 51 -qdiff 4 -i_qfactor 0.71428572 -maxrate 768k -bufsize 2M -cmp 1 -s 720x480 -acodec aac -ab 160k -ar 48000 -ac 2 -f mp4 -pass 2 -threads 8 outputFileName.ext

I found that the file resulting from the above commands was a bit large, so I lowered the bitrate (-b) from 500 to 250. Also, I lowered the maximum instantaneous bitrate spike (-maxrate) from 768 to 450. As this was a music video and I am a bit of an audiofile, I kept the audio bitrate (-ab) at 160k. Doing this, my file size dropped by 33%, from 450MB to 300MB. This is for a video with a duration of 1hr and 39min. Impressive! Replaying both files in mplayer and xine, I noticed that there was very little appreciable loss in video quality with the lowered bitrates. Go H264!!

Here are the final two commands I used to get that 300MB file:
ffmpeg -y -i sourceFileName.ext -an -v 1 -threads 8 -vcodec h264 -b 250k -bt 175k -refs 1 -loop 1 -deblockalpha 0 -deblockbeta 0 -parti4x4 1 -partp8x8 1 -me full -subq 1 -me_range 21 -chroma 1 -slice 2 -bf 0 -level 30 -g 300 -keyint_min 30 -sc_threshold 40 -rc_eq 'blurCplx^(1-qComp)' -qcomp 0.7 -qmax 51 -qdiff 4 -i_qfactor 0.71428572 -maxrate 450k -bufsize 2M -cmp 1 -s 720x480 -f mp4 -pass 1 /dev/null

ffmpeg -y -i sourceFileName.ext -v 1 -threads 8 -vcodec h264 -b 250k -bt 175k -refs 1 -loop 1 -deblockalpha 0 -deblockbeta 0 -parti4x4 1 -partp8x8 1 -me full -subq 6 -me_range 21 -chroma 1 -slice 2 -bf 0 -level 30 -g 300 -keyint_min 30 -sc_threshold 40 -rc_eq 'blurCplx^(1-qComp)' -qcomp 0.7 -qmax 51 -qdiff 4 -i_qfactor 0.71428572 -maxrate 450k -bufsize 2M -cmp 1 -s 720x480 -acodec aac -ab 160k -ar 48000 -ac 2 -f mp4 -pass 2 -threads 8 outputFileName.ext

Results
As this encoding work was completed on my Fedora editing box, I SCP'd the file over to my MacBook Pro. I dragged the file over onto the Movies section within iTunes and iTunes accepted it without error. In order to verify that the file played correctly, I double-clicked on it and Quicktime played the file back. Hooray!

The moment of truth came when I plugged in my iPod and sync'd it to my iTunes Library. Normally, iTunes will immediately display an error if it doesn't like the new file. Thankfully, iTunes didn't show any errors and uploaded the file to my iTouch. As the file was about 300MB, this took about two minutes. I then started playback and was very happy to see my video on the beautiful, but small iTouch screen.

If you'd like to see the end result, load up one of these videos and don't mind a bit of loud rock musicians doing their thing, you could try loading my band's video podcast:
http://www.stormpigs.com/vodcast.xml

One anomaly I noticed was that when you fast forward to a different section within the movie on the iPod, the video will speed up for a second until the timeline catches up to the requested moment. Not a big deal, just something I didn't expect.

Hope this helps intrepid open source folks looking for a way into the walled garden of Apple's iTunes.

The Mule

Reference
https://help.ubuntu.com/community/iPodVideoEncoding#H.264%20Encoding