A few times before I have imported my short clips from the Sony HDR-CX106 camcoder directly using iMovie camera import features. Now, that I had a bit longer videos on the camera, I got to thinking why it takes so long and how come it reports that 60 GB of my hard drive will fit only 1 hour or so full-quality video. It turns out that by importing, iMovie probably converts all the clips into HDV compliant format, thus MPEG2 and thus resulting in wasting my hard drive space.
What about AVCHD?
This was the question I asked myself and by googling around I found out that as of yet, iMovie does not directly support AVCHD format. But it does not have any problems with the H.264 encoded videostream in the file nor with AC-3 encoded audio stream.So – obvious solution was to repackage the file into another format using FFmpeg.
First up was ofcourse MP4, but as it turns out, AC-3 audio is not officially supported and iMovie refuses to import such a file. So I installed also libfaac to encode AAC, which is MP4’s default audio encoding and run:
ffmpeg -i 0001.MTS -vcodec copy -acodec libfaac -ar 48000 -ac 2 -ab 320k 0001.mp4
Unfortunately this method was a bit slow, as it reencodes the whole audio stream, so as I was not limited to MP4 format and iMovie is more than happy with MOV files, I could instead just copy both streams into a MOV container:
ffmpeg -i 0001.MTS -vcodec copy -acodec copy 0001.mov
Now I can just drag these files to iMovie and only have to wait for it to update thumbnails. And most important – disk usage is kept normal, not increased tenfold as with direct import.
Automated batch conversion
The above command can be turned into a script that takes output folder as argument and list of files as input:
# Created by Laas Toom on 17.03.10.
# Copyright (c) 2010 Laas Toom, All Rights Reserved.
if [[ -z "$ffmpeg_bin" ]]; then ffmpeg_bin=$(which ffmpeg); fi
if [[ -z "$growl" ]]; then growl=$(which growlnotify); fi
if [[ -z "$vcodec" ]]; then vcodec="copy"; fi
if [[ -z "$acodec" ]]; then acodec="copy"; fi
if [[ -z "$ofmt" ]]; then ofmt="mov"; fi
if [[ -z "$output_dir" ]]; then output_dir=~/Desktop; fi
while read movie
if [[ -f "$movie" ]]
$growl -H localhost --image "$mypath/ffmpeg.png" -s -d "$base" -m "mts2mov: Transcoding: $movie ..."
ls -la "$movie"
# somehow ffmpeg steals the input of this shell and so we have to fake input to ffmpeg
echo "" | $ffmpeg_bin -i "$movie" -vcodec $vcodec -acodec $acodec "$ofile"
test -f $growl && $growl -H localhost --image "$mypath/ffmpeg.png" -d "$base" -m "mts2mov: Transcoding: $movie ... Done"
test -f $growl && $growl -H localhost --image "$mypath/ffmpeg.png" -m "mts2mov: All Done"
NOTE: the script is written on a Mac and uses Growl to give feedback. If you don’t want/have them, just comment out all lines with growlnotify in them and you should be OK.
I turned the above script into an Automator Action and that action in turn into a Finder Service, so that I can use it conveniently from the finder window.
Bot of them can be found at my Automator page.