8-millimeter video tapes seem to be slowly fading into oblivion. In order to save old family videos recorded in this format, I’ve decided to digitize them.
After a quick try with vlc, I understood that it wasn’t the right tool for the task. It crashed with a cryptic error message every time I tried to encode H.264 video, and it seemed that it was best suited for real-time encoding. Doing real-time encoding is sub-optimal, as I can’t achieve high-quality encoding at a reasonable bit rate.
So I looked for another tool and recalled ffmpeg. While ffmpeg provided everything I was looking for – high-quality video encoding using H.264 and stability – it wasn’t an easy start. ffmpeg’s defaults are notoriously ill-chosen. After hours of going through man pages, I’ve managed to capture and convert video tapes into high-quality (encoded) digital video.
Basically, the process involved capturing the raw video into a temporary file and then performing a two-pass encoding using H.264.
Capturing the raw video
ffmpeg -i /dev/video0 -t 1:30:00 -vcodec copy /tmp/video.mpg
The -vcodec copy tells ffmpeg to copy the raw codec data as is. It allows you to make an identical copy of the video from the capture device /dev/video0. The -t flag allows you to restrict the video capture duration.
Performing the first encoding pass
ffmpeg -i /tmp/video.mpg -vcodec libx264 -vpre max -threads 0
-b 2100k -pass 1 -f mp4 -y /dev/null
The -vcodec libx264 tells ffmpeg to encode the video using H.264 encoding. The -vpre flag allows you to set predefined presets that control, among other things, the quality of the encoded video. I used max; other presets include hq and normal. -threads 0 tells ffmpeg to spawn as many threads as it deems necessary. -b 2100k tells it to target a bit rate of 2100 kbps for video encoding. -pass 1 allows you to perform the first pass out of two in a 2-pass encoding. In the first pass, ffmpeg will collect statistics and write them to a special log. When doing the second pass, ffmpeg can use this special log to better distribute the bit rate so it will achieve a constant quality at the specified average bit rate. The output of the first pass isn’t important, so it’s directed to /dev/null. The -y switch tells ffmpeg to ignore the fact that this file already exists. As ffmpeg can’t tell the format of the file by its name (/dev/null), we specify it manually using -f mp4.
Performing the final encoding pass
ffmpeg -i /tmp/video.mpg -vcodec libx264 -vpre max -threads 0
-b 2100k -pass 2 ~/Videos/video-200108-200201-r1.mp4
This one is similar to the last command, except that we finally save the video. The -pass 2 tells ffmpeg to perform the second and final pass. It will use the statistics log created by the previous command in order to optimize the encoding. The -f flag isn’t necessary, as the format is indicated by the output file’s name.
The encoding time is greatly affected by the preset that you choose. The max preset is very slow, which wasn’t a problem for me in this case, but is something worth remembering. See Julian Simon’s x264 presets comparison for more information regarding the different presets available.
Ha! That’s awesome. I remember compiling ffmpeg from source about eight months ago, looking for docs, getting completely dismal explanations and throwing it to the curb in a search for gui tools. As it turns out, VLC crashes for me too. Now that I think about it, ffmpeg reminds me of imagemagick.
P.S. I started following your blog because I did a search for programming blogs using the Journalist wordpress template. It paid off 😀
I’m glad you find the blog interesting.
ffmpeg, together with imagemagick, pdftk and couple of others are great examples for excellent (once you learn how to use them) tools that outperform most GUI programs in their field.
I do this
ffmpeg -i input.mp4 -vcodec libx264 output.mp4
or
ffmpeg -i input.mp4 -vcodec h264 output.mp4
so it says “Unknown encoder libx264” or “Unknown encoder h264”
What should I do now :(??.. I want to convert videos’ codec to h264 🙁
Do you have libx264 installed? It looks like you don’t have it.