8-millimeter video tapes seem to slowly fade to 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’ve understood that it wasn’t the right tool for the task. It crashed with a cryptic error message every time I’ve tried to encode H.264 video, and it seemed that it best suited for real time encoding. Doing real time encoding, is sub-optimal as I can’t reach high quality encoding is a reasonable bit rate.
So I looked for another tool and recalled ffmpeg. While ffmpeg provided everything I looked: 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 preform 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 capturing device /dev/video0
. The -t
flag allows you to restrict the video capturing 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 a predefind presets that control (among other things) the quality of the encoded value. I used max
, other presets include hq
and normal
. -threads 0
tells ffmpeg
to spawn as many threads it deems necessary. -b 2100k
tells it to target a bit rate of 2100kbps for video encoding. -pass 1 allows you to perform the first pass out 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 that this file already exists. As ffmpeg
can’t tell the format of the file by it’s 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 similiar 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 effected by the preset that you chose. 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.