Using ffmpeg on Ubuntu to convert DV videos for video sharing websites
To begin with, this is the problem that I had. I had recorded a short clip using my Panasonic NV-GS330 camcorder. I had to upload it to Vimeo, my video sharing website of choice.
From the camcorder to the computer
Importing the video from the camcorder to the laptop was not much of a problem. I plugged in the camcorder to my laptop using a firewire card. Then I used Kino to position the tape (the camcorder uses mini dv tapes) just before the beginning of the clip I wanted to import and hit the capture button. Soon, the dv capture file for the clip was lying in my home directory.
Figuring out the output format
What is your format of choice for uploading to the video sharing website? Regardless of the format you use, all video sharing website will re-encode it to the video standard(or quality) that they use to serve the clips to the viewers. To avoid changing too many things in this re-encoding, which decreases quality, it is always better to go with the recommendations of the video sharing website. Luckily, vimeo has quite a detailed page about the characteristics of the video they would like their users to upload. This makes it easy for me, so I note it down:
-
They want the h.264 codec.
-
They don’t care much for your frame rate if it is a regular video(and not HD) - so I can keep my video in PAL.
-
They would like a keyframe every 30 frames - umm, this will make the videos larger, but let me go ahead with this anyway.
-
They would like a max video bitrate of 1800kb/s. That is a bit too much for the kind of video I have, so I will keep it down to 900kbps for now (actually you can probably go down to 500). The lower this rate is, the lesser is the size of the video that you will have to upload, but unfortunately lower is the quality.
-
Size recommended in 640x480 (4:3 ratio) - I tried uploading my 16:9 video anyway, but they squished it down to 4:3 and it looked terrible. So I resolved to keep the output video size to 640x480 to prevent any scaling during re-encoding.
-
Do I want de-interlacing? I checked my camcorder manual, and yes, the video is interlaced. Actually it seems most non-professional camcorders have interlaced video anyway, so you would most possibly need to enable this.
-
Audio quality recommended is 128kbps. Since my audio is regular day-to-day conversation and noises(as opposed to music or audio where quality is more critical), I am ok with 64kbps (anything to keep the file size low). Actually, even if I had gone down to 32kbps, I don’t think anyone will notice.
-
Vimeo recommends AAC as the audio format, but somehow vlc had this problem playing audio for the generated videos. So I decided to go with mp3 as the output audio format instead. However, this has it’s own problem in Ubuntu - ffmpeg doesn’t come with mp3 support in Ubuntu due to it’s licencing restrictions. Using the medibuntu repository, as described in this life saving tip, helped me get a version of ffmpeg which encodes mp3 files.
Using ffmpeg
Now comes the tough part - using the non-linear video editor ffmpeg and it’s millions of knobs 😄 . Actually, in it’s simplest form ffmpeg is really really easy to use! Just using ffmpeg -i input.dv -vcodec h264 output.avi
will do the job for you. But it is not going to give you the requirements that you had just drawn up. For one, the default bitrate is 200kbps, which will give you terrible video. Also, I have video in 16:9 format, as my camcorder records in widescreen, and I have to convert the video into 4:3 640x480 format. The right way to do it, so that you don’t have to crop off any video data, is to convert the video into a letterbox form, which ffmpeg can do very effectively.
Resizing video from 16:9 to 4:3 (letterboxing) using ffmpeg
ffmpeg has a -s (width)x(height)
parameter which can let you resize the video. To preserve the aspect ratio for my video in the 4:3 format with 640 being the final width of the video, my video would first need to be scaled to the required width as it is the larger of the two dimensions. Then black bars would be added to the height to make it add up to 480. The magic resizing size is 640x360 (-s 640x360
), with 40 pixels each, above and below the video (-padtop 60 -padbottom 60
), to reach 480 in the vertical dimension. The padding color is usually black (-padcolor 000000
) but you can also go with white to make the video merge into the usually white background of the websites. Black, to me, gives quite a retro feel to the video ;) and so I would go with that.
The actual command line
There is a huge list of switches that can be used in ffmpeg to get the video of your choice. The advanced ones require you to understand intimately how video compression works. A lot of optimization is possible which can get you the best results for the nature of the video. However, I decided to keep my learning curve as short as I could and came up with a configuration which works for me.
/usr/bin/ffmpeg -threads 2 -f dv -i input.dv -vcodec h264 -g 30 -deinterlace -b 900k -s 640x360 -padtop 60 -padbottom 60 -padcolor 000000 -aspect 4:3 -acodec mp3 -ab 64k output.avi
An easier way
Of course, there are numbers here that you would like to tweak for your needs, and therefore I have created this little bash wrapper script to make it really easier for you to tweak it. Edit the config values at the top of the script to suit your taste. You can also configure the metadata (like author name, copyright, etc.) of your videos. Remember to at least change these, unless you want me to own the copyrights to your uploaded videos ;).
This is the advantage of using a linear video editing tool like ffmpeg. It is so easy to script it for regular uses!
Tweaking your file size and quality
With the configuration values earlier, I was able to convert a 28MB DV file(about 8 seconds in duration, these files are big!) to an excellent 1MB AVI file. With a video bitrate of 500kbps however, this came down to about 600kb and an acceptable video quality. You should tweak with the video bit rate to see which one gives you the best trade off for your video.