Here’s a little trick I learned and wanted to share. As it’s not complete, comments and additional hints are welcome!
The problem
I have a Canon HDV camcorder with many hours of HDV video. HDV is mpeg2-compressed video with a bitrate of about 25 Mbps.
I also have a MacOS X computer where I can run iMovie, Apple’s consumer-grade video editing application.
The camcorder video can be easily imported to FreeBSD using the built-in fwcontrol tool. It generates MPEG-TS files (mostly like IP TV channels) which read nicely in vlc, mplayer and other video tools. It’s easy and reliable.
The video can also be imported directly from the camcorder to iMovie, but it is painful and not adapted to easy archiving of the rushes. The import process is slow and buggy and you often have to rewind the tape and restart it.
I wanted to get the best of both worlds — fwcontrol’s easy import followed with iMovie editing.
But iMovie doesn’t know how to directly import MPEG-TS files. It can only import video from .mov (Quicktime) or .mp4 (MPEG4) containers. It’s difficult to know which video codecs are supported by iMovie but it seems to accept MPEG2, which means it can losslessly import HDV files, it’s just a matter of converting their container format from MPEG-TS to Quicktime.. It saves us from the slow, error-prone, lossy and painful process of transcoding.
So how do you do that?
The (mostly complete) solution
Here’s the incantation that mostly works for me. input.mpg is my MPEG-TS file; it can come from a fwcontrol import or from a IPTV capture (Freebox file for example); output.mov is the resulting Quicktime-container file:
ffmpeg -i input.mpg -acodec copy -vcodec copy output.mov
On my server (a double-core Intel Atom D525 processor with SATA disks, ie not a very fast machine) it converts at about 80-100 frames per second (3x to 4x real time), which is very fair (IO bound probably) and 12 to 20 times faster than transcoding the video.
From an IPTV capture you may have to explicitly transcode audio to AAC using -acodec libvo_aacenc instead.
Your second-best bet if the above doesn’t work is to let ffmpeg make a (much slower) almost-lossless transcoding to MPEG4, using option -sameq, yielding a bigger file (was almost twice as big as the original in my trials):
ffmpeg -i input.mpg -acodec copy -sameq output.mov
It works, but…
Why do I say it mostly works? Because there are two remaining gotchas:
- the original video timestamps (date and time of the video) are lost and set to the date and time of the conversion process — it’s constant and doesn’t even increment throughout the file duration. It is probably a ffmpeg bug. I tweaked the import with -copyts option but this apparently handles the time index from the camcorder (duration from the beginning of the tape). This may (or may not) be related to the following error message from ffmpeg: [NULL @ 0x806c1d920] start time is not set in av_estimate_timings_from_pts
- iMovie doesn’t seem to grok huge files. It works for a couple hundred megabytes, but not for a couple gigabytes. So you may have to split files take by take, and I don’t know how to do that easily, especially given the above regarding broken timestamps.
Thanks to Benjamin Sonntag for the excellent idea of using ffmpeg for this 😉
Comments and especially clues/solutions more than welcome 😉