14 May, 2009

FFmpeg Ninja Moves - part 2

In part 1 we showed how to access the help info by specifying the -h command line argument. Paying special attention to the first line shows both the input and output files allow options:


.
.
usage: ffmpeg [[infile options] -i infile]... {[outfile options] outfile}...
Hyper fast Audio and Video encoder
.
.


Note that both the input and output files allow for options. Many typical uses of FFMpeg will not require input options as they can often be implicitly determined from the input file (e.g. frame rate, codec, . . .).

Let's start with 'The Duke', as any warm-blooded American can't help but love this 'one eyed fat-man'.


FFMpeg shows the encoder used is mpeg4, video dimensions of 720x480 and a 30 fps frame rate with mp2 audio. This information is available by specifying an input file with no output file options as follows:

$ ffmpeg -i /tmp/video.avi
FFmpeg version SVN-rUNKNOWN, Copyright (c) 2000-2004 Fabrice Bellard
configuration: --enable-gpl --enable-pp --enable-pthreads --enable-vorbis --enable-libogg --enable-a52 --enable-dts --enable-libgsm --enable-dc1394 --disable-debug --enable-shared --prefix=/usr
libavutil version: 0d.49.0.0
libavcodec version: 0d.51.11.0
libavformat version: 0d.50.5.0
built on Mar 26 2007 14:28:38, gcc: 4.1.2 20061115 (prerelease) (Debian 4.1.1-21)

Seems that stream 0 comes from film source: 30000.00 (30000/1) -> 29.97 (30000/1001)
Input #0, avi, from '/tmp/video.avi':
Duration: 00:00:57.3, start: 0.000000, bitrate: 7104 kb/s
Stream #0.0: Video: mpeg4, yuv420p, 720x480, 29.97 fps(r)
Stream #0.1: Audio: mp2, 48000 Hz, stereo, 64 kb/s
Must supply at least one output file


We can re-encode this video into an alternative codec such as MS-MPEG4. First, since each FFMpeg installation relies on the available codecs we need to examine what video encoders are available to make our selection:

$ ffmpeg -formats | egrep "Codecs:|EV"
FFmpeg version SVN-rUNKNOWN, Copyright (c) 2000-2004 Fabrice Bellard
configuration: --enable-gpl --enable-pp --enable-pthreads --enable-vorbis --enable-libogg --enable-a52 --enable-dts --enable-libgsm --enable-dc1394 --disable-debug --enable-shared --prefix=/usr
libavutil version: 0d.49.0.0
libavcodec version: 0d.51.11.0
libavformat version: 0d.50.5.0
built on Mar 26 2007 14:28:38, gcc: 4.1.2 20061115 (prerelease) (Debian 4.1.1-21)
Codecs:
DEV D asv1
DEV D asv2
DEV D dvvideo
DEV D ffv1
DEVSD ffvhuff
DEVSD flv
DEV D h261
DEVSDT h263
EV h263p
DEVSD huffyuv
EV jpegls
EV ljpeg
DEV D mjpeg
DEVSDT mpeg1video
DEVSDT mpeg2video
DEVSDT mpeg4
DEVSD msmpeg4
DEVSD msmpeg4v1
DEVSD msmpeg4v2

DEV pam
DEV pbm
DEV pgm
DEV pgmyuv
DEV png
DEV ppm
DEV rawvideo
DEV D rv10
DEV D rv20
DEV snow
DEV D svq1
DEVSD wmv1
DEVSD wmv2
DEV D zlib


This installation supports MS-MPEG4 versions 1 & 2. We can therefore re-encode the source video into MS-MPEG4 format, a commonly available codec for Windows (boo, hiss) platforms. You can convert the source video into MS-MPEG4v2 format as follows:

$ ffmpeg -i /tmp/video.avi -vcodec msmpeg4v2 -sameq ~/video.avi

$ ffmpeg -i ~/video.avi
FFmpeg version SVN-rUNKNOWN, Copyright (c) 2000-2004 Fabrice Bellard
configuration: --enable-gpl --enable-pp --enable-pthreads --enable-vorbis --enable-libogg --enable-a52 --enable-dts --enable-libgsm --enable-dc1394 --disable-debug --enable-shared --prefix=/usr
libavutil version: 0d.49.0.0
libavcodec version: 0d.51.11.0
libavformat version: 0d.50.5.0
built on Mar 26 2007 14:28:38, gcc: 4.1.2 20061115 (prerelease) (Debian 4.1.1-21)
Input #0, avi, from '/home/lipeltgm/video.avi':
Duration: 00:00:57.3, start: 0.000000, bitrate: 6663 kb/s
Stream #0.0: Video: msmpeg4v2, yuv420p, 720x480, 29.97 fps(r)
Stream #0.1: Audio: mp2, 48000 Hz, stereo, 64 kb/s
Must supply at least one output file


By specifying the -vcodec argument, you can force the output file to use the codec you specify. Specifying -vcodec msmpeg4v2 therefore forces the output file to be encoded using MS-MPEG4v2 codec. You should notice that the resultant image is now encoded using msmpeg4v2. You may also notice that the conversion command line specified a -sameq argument which we haven't discussed. Simply put, you may find this argument useful if you wish to retain the source videos quality. The -sameq argument simply applies the 'same quality' as the input video. By not constraining the video quality of the output video the standard defaults will apply which may give you a smaller file size, but a video stream of lesser quality.

In typical use, you'll employ an iterative process of processing an input file, examine the output file results, and re-process the input file until you finally arrive at the desired results. That said, in many cases you'll respecify the same command line, tailoring the options as you see fit. This brings us to the point, FFMpeg will prompt the user for over-write permissions if you specify an output file that already exists. You're prompted for a y/n response when the output file is detected. You can respond 'y' to continue, or if you'd rather not be bothered with the prompts you can specify the -y option which will force overwrite of any existing output file without user prompt.
For example, without specifying the -y argument:


$ ffmpeg -i /tmp/video.avi -vcodec msmpeg4v2 -sameq /var/tmp/video.avi
FFmpeg version SVN-rUNKNOWN, Copyright (c) 2000-2004 Fabrice Bellard
configuration: --enable-gpl --enable-pp --enable-pthreads --enable-vorbis --enable-libogg --enable-a52 --enable-dts --enable-libgsm --enable-dc1394 --disable-debug --enable-shared --prefix=/usr
libavutil version: 0d.49.0.0
libavcodec version: 0d.51.11.0
libavformat version: 0d.50.5.0
built on Mar 26 2007 14:28:38, gcc: 4.1.2 20061115 (prerelease) (Debian 4.1.1-21)

Seems that stream 0 comes from film source: 30000.00 (30000/1) -> 29.97 (30000/1001)
Input #0, avi, from '/tmp/video.avi':
Duration: 00:00:57.3, start: 0.000000, bitrate: 7104 kb/s
Stream #0.0: Video: mpeg4, yuv420p, 720x480, 29.97 fps(r)
Stream #0.1: Audio: mp2, 48000 Hz, stereo, 64 kb/s
File '/var/tmp/video.avi' already exists. Overwrite ? [y/N]

Alternatively, you can force overwrite by:

$ ffmpeg -y -i /tmp/video.avi -vcodec msmpeg4v2 -sameq /var/tmp/video.avi

No comments: