I have found two problems with video recorded from my iPhone 4s.
- File sizes are very large.
The iPhone records H.264 at 1920x1080 with a bitrate of 24.0Mbps. A one minute video is 180MB.
- Video playback is sometimes upside down or rotated 90 degrees CW or CCW.
The iPhone records all video with the volume buttons side down. This means nearly all landscape videos will be upside-down as the Volume-Up button is the start/stop recording trigger. Portrait videos will appear to be rotated 90° counter-clockwise if they were recorded with the Home button at the bottom. The iPhone embeds meta data within the video that tells the player how to rotate the video to make it right-side-up for playback. While QuickTime and others respect that meta data, my preferred player, VLC, does not. Since I will be sharing my videos and I do not know which players my audience will be using, I want to correct the video stream to be right-side-up regardless of the meta data.
The first problem is very easy to deal with, compress the video with something like Handbrake. I've also noticed that the 1080p video can be grainy, so I can further reduce the filesize and not lose too much quality by downscaling to 720p.
The second problem is more complex. Unfortunately HandBrake (or at least the GUI) does not offer a way to rotate video. The HandBrake CLI does have a "rotate" option, however I found it is not a true rotation. Rather, it simply flips on an axis. The documentation is poor, but I found that a value of 1 flips on X, 2 flips on Y, and 3 flips on X and Y. So using a value of 3 is the same as doing a 180° rotation, which is useful for videos that are upside down, but not for videos that are sideways. After a bit of hunting I discovered that mencoder can do proper rotation. I didn't want to spend the time trying to compile my own mencoder binary, so I found some precompiled mac binaries that others had done. I couldn't find a Mac OS X mencoder binary that has both faad support (to decode source aac which the iPhone uses for audio) and x264 (to encode h264). I settled on one I found at stefpause.com which can read aac and outputs to raw. The solution I came up with was to use mencoder to rotate the video, and have it output raw video and pcm audio. I then pass that raw input into the HandBrake CLI to do the downscaling and compressing. The raw temp files are stores in /tmp, and they do get very large. This isn't a problem for me as most of my videos are under a few minutes. If you are going to be doing anything much longer you probably want to find a better mencoder binary that can do it all for you so you don't need to do raw to handbrake step.
The following direction are known to work on OS X 10.7.2:
- Create a directory for this project.
- Download the HandBrake CLI from http://handbrake.fr/downloads2.php. I grabbed the 64 bit version 0.9.5. Mount the disk image and move HandBrakeCLI into your project directory.
- Download mencoder.zip from http://stefpause.com/apple/mac/mplayer-os-x-10rc1-and-mencoder-binaries/ . Copy mencoder into your project directory.
- Using TextEdit, or your plain text editor of choice, create a file named "iPhoneFlipVertical.sh" in the project directory. Copy the following contents into this file.
# used to flip iPhone videos that are upside-down in landscape right-side-up. Takes iPhone 4s 1920*1080 video, compresses and outputs at 1280x720 # $1 is input file # $2 is output file, should end with .m4v # https://trac.handbrake.fr/wiki/CLIGuide width=1280 #height will be scaled to preserve aspect ratio audioBitrate=128 #AAC kbps constantQualityRF=22 #https://trac.handbrake.fr/wiki/ConstantQuality 22 looks good for iPhone start="started at `date`" # advanced options from HandBrake preset x264Advanced="ref=2:bframes=2:subq=6:mixed-refs=0:weightb=0:8x8dct=0:trellis=0" # rotate, 1 flips on x, 2 flips on y, 3 flips on both (equivalent of 180 degree rotation) ./HandBrakeCLI -i "$1" -o "$2" -e x264 -O -B $audioBitrate -q $constantQualityRF -w $width --denoise="weak" --rotate=3 -x $x264Advanced echo $start echo "finished at " `date`
- The string for the x264Advanced variable can be obtained from the "Advanced" tab in the HandBrake GUI. Shown above is the string from the "Normal" preset.
- Create another file named "iPhoneRotate90CW.sh". Copy the following contents into this file.
# used to rotate iPhone portrait videos 90 degrees clockwise. Compresses and outputs at 720x1280. Note on the iPhone the side with the volume buttons is always "down" in videos. # $1 is input file # $2 is output file, should end with .m4v # https://trac.handbrake.fr/wiki/CLIGuide # http://git.mplayerhq.hu/DOCS/man/en/mplayer.1.html #couldn't find a mac os x mencoder binary that has both faad (to decode source aac) and x264 (to encode h264). Settled on this one which can read aac and outputs to raw. Uses a lot of disk space! start="started at `date`" tmpRaw="/tmp/`date +%s`.raw" #./mencoder -vf rotate=1 -ovc x264 -oac pcm "$1" -o "$2"#this is what we'd do with a better mencoder binary (x264 support) ./mencoder -vf rotate=1 -ovc raw -oac pcm "$1" -o "$tmpRaw" height=1280 #width will be scaled to preserve aspect ratio, 720x1280 for vertical iPhone audioBitrate=128 #AAC kbps constantQualityRF=22 #https://trac.handbrake.fr/wiki/ConstantQuality 22 looks good for iPhone x264Advanced="ref=2:bframes=2:subq=6:mixed-refs=0:weightb=0:8x8dct=0:trellis=0" ./HandBrakeCLI -i "$tmpRaw" -o "$2" -e x264 -O -B $audioBitrate -q $constantQualityRF --height $height --denoise="weak" -x $x264Advanced rm "$tmpRaw" echo $start echo "finished at " `date`
- In Terminal, cd into the project directory and make sure the permissions looks like this. You'll probably need to run chmod 744 *.sh
-rwxr-xr-x@ 1 Thom staff 16765320 Jan 3 2011 HandBrakeCLI -rwxr--r--@ 1 Thom staff 843 Jan 4 21:49 iPhoneFlipVertical.sh -rwxr--r--@ 1 Thom staff 1252 Jan 4 21:50 iPhoneRotate90CW.sh -rwxr-xr-x@ 1 Thom staff 8090416 Sep 7 2008 mencoder
To flip a video upside down, execute the following command in Terminal (within the context of your project directory). Change the first argument to the path of your input file, and the second argument to the path of your desired output file, which should end in ".m4v".
./iPhoneFlipVertical.sh ~/Desktop/IMG_0095.MOV ~/Desktop/IMG_0095.m4v
To flip a video 90° clockwise, execute the following command in Terminal (within the context of your project directory). Change the first argument to the path of your input file, and the second argument to the path of your desired output file, which should end in ".m4v".
./iPhoneRotate90CW.sh ~/Desktop/IMG_0112.MOV ~/Desktop/IMG_0112.m4v
If you know of a better mencoder binary, please let me know about it in the comments!