Sunday, May 24, 2009

ffmpeg cheat sheet

This reference is based on the great howto by Howard Pritchett. It is by no means complete but it can serve as a useful starting point to learn to manipulate your audio and video files from the power of a Unix command line. Another useful video tutorial by Linux Journal.

ffplay

$ ffplay options... inputfile
-x width -y height
Force displayed width and/or height.
-ss position
Seek to a given position in seconds.

ffmpeg

$ ffmpeg options... outputfile
-i inputfile
Use this option alone to identify and display information about inputfile.
-formats
Give a list of the codecs and formats ffmpeg can work with.

Audio

-acodec audiocodec
copy
No transcoding of the audio.
mp2
MPEG-1 Audio Layer II (lossy, extension .mp2).
libmp3lame
MPEG-1 Audio Layer III (lossy, extension .mp3).
pcm_uX
Pulse Code Modulated, uncompressed with X-bit samples (X=8,16) (extension .wav).
vorbis
Completely open, patent-free (lossy, extension .ogg).

-ab audiobitrate

E.g. 64k, 192k that is kbit/s for mp2/3.

-aq audioquality

From 0, used with VBR (Variable Bitrate Length) codecs e.g. 60 for vorbis ~ 160k.

-ar audioresample

E.g. 22050 that is Hz, half of CD quality.

-ac audiochannels

Allows down and up mixing, e.g. 1 for mono, 2 for stereo.

Video

-target standardformat
Warning: After recoding in a standard format check the real bandwidth used by the codec bitrate against the selected output format bitrate. If the first is much lesser you can get a smaller file by overriding the video bitrate (-b) and/or audio codec used and its parameters (-acodec, -ar, -ab). If size matters it may be better not to use --target at all and set all parameters manually to achieve the best compromise between size and quality, e.g. use efficient video and audio codec as MPEG4 and mp3 with appropriately reduced parameters, as picture size, frame rate, video bitrate, sampling rate and audio bitrate.
ntsc-dvd
MPEG2 video (extension .mpg, yuv420p color encoding, 720x480 pixel image size, 6 mbit/s bit rate, 29.97 frames per seconds, admissible quality levels q=2-31, 2 is the best), AC3 audio (48 KHz sampling rate, mono at 448 kbit/s) commonly used on DVD video. Standard audio and video parameters can be overriden.
pal-dvd
... ditto .... 720x576 ... ditto ...

-vcodec videocodec


copy
No transcoding of the video.
flv
Flash Video (extension .flv).
mpeg2
MPEG-2 (extension .mpg).
mpeg4
MPEG-4 (extension .mpg, more efficient than mpeg2).
msmpeg4v2
MsMPEG4v2 (extension .avi).

-aspect aspectratio

For codecs that support anamorphic display (e.g. MPEG2) sets the default aspect ratio, that is the width divided by the height of the physical picture displayed on-screen. If necessary the image will be stretched (usually only along its width or height) such that its aspect ratio is as specified. E.g. 4:3 (1.333...) is the old TV format which is narrower than the 16:9 (1.777...) of widescreen (cinema) format.


-croptop pixels
-cropbottom pixels

Slice the given number of pixels off the top and the bottom of the image respectively. Useful for narrowing an image with an aspect ratio that's too low, e.g. for conversion from 4/3 to 16/9. The number of pixels to slice off must be an even number.


-cropleft pixels
-cropright pixels

Slice the given number of pixels off the top and the bottom of the image respectively. Useful for narrowing an image with an aspect ratio that's too high, e.g. for conversion from 16/9 to 4/3. The number of pixels to slice off must be an even number.


-padleft pixels
-padright pixels

Slap the given number of extra pixels on the left and the right of the image respectively. Useful for widening an image with an aspect ratio that's too low, e.g. for conversion from 4/3 to 16/9. However, the number of pixels specified in the "-padleft" and "-padright" options has to be an even number (they not need to be equals).


-padtop pixels
-padbottom pixels

Slap the given number of extra pixels on the top and the bottom of the image respectively. Useful for padding an image with an aspect ratio that's too high, e.g. for conversion from 16/9 to 4/3. However, the number of pixels specified in the "-padleft" and "-padright" options has to be an even number (they not need to be equals).

-padcolor color

Set the color of the padding bands. The argument given is a color expressed as three hex bytes (Hex 000000 thru FFFFFF) just like in HTML (but without the leading "#" sign).

-b bitrate

Video bitrate, e.g. 2000k, 300k (k are kbits/s).

-s widthxheight

Picture size, e.g. 320x240, 480x270, 720x480.

-r rate

Frame rate, e.g. 10, 15.

-f format

Selects the container format, e.g. avi.

-ss position

Seek to given time position in seconds. "hh:mm:ss[.xxx]" syntax is also supported.

-t duration

Restrict the transcoded/captured video sequence to the duration specified in seconds. "hh:mm:ss[.xxx]" syntax is also supported.

Examples

Aspect ratio conversion from 4:3 to 16:9

A movie aspect ratio is 4:3. It's size is X:Y, where the proportion X:Y=4:3 holds. We want to give it a widescreen aspect ratio.
First solution: deforme
Its new height H should be: X:H=16:9; H=X/(16/9)=Y/(4/3) pixels instead of Y. Note that H<Y. If we simply resize the image in order to squash it vertically, the picture will be deformed (e.g. faces will look goofy).
$ ffmpeg -i inputfile -target pal-dvd \
-aspect 16:9 outfile
Second solution: crop
The only thing we can do in order to stop the picture from going anamorphic is to trim off parts of it, or to "crop" it. The picture is Y-H pixels too "tall" so let's shave (Y-H)/2 pixels off the top and off the bottom, then convert the result to a 16:9 PAL or NTSC DVD:
$ ffmpeg -i inputfile -croptop (Y-H)/2 \
-cropbottom (Y-H)/2 -target pal-dvd \
-aspect 16:9 outfile
If Y-H is not even (i.e. (Y-H)%2 == 1) to respect the constraint of even cropping numbers, you can subtract 1 from croptop and add 1 to cropbottom to compensate (or viceversa). Note the various "-crop" options must act BEFORE any resizing takes place. They crop the specified number of pixels off the ORIGINAL image.
Third solution: pad
"Letterboxed" means that we keep the whole image and put bars on the right and left so that the resulting bar-image-bar sandwich has the 16/9 aspect ratio. What you get is not a real widescreen video, though. This is why is called letterbox format. Let W be the new width. We have: X:Y=4:3, W:Y=16:9, W=Y*(16/9)=X*(4/3)
$ ffmpeg -i inputfile -aspect 16:9 \
-padleft (W-X)/2 -padright (W-X)/2 \
-padcolor 000000 -target pal-dvd outfile
If W-X is not even, use (W-X+1)/2 for left and (W-X-1)/2 for right or viceversa. Note the various "-pad" options are applied AFTER resizing has taken place. They add the specified number of pixels to the RESIZED image.

Aspect ratio conversion from 16:9 to 4:3

Left as an exercise to the reader. After reading how to perform conversion from 4:3 to 16:9 it should be easy do the opposite. Hints: when using the deforme method, skinny looking faces will result. Cropping must be done left and right while padding on the top and bottom.

Cutting a video file

I have recorded a television program to an MPEG file and I want to cut some parts in order to get rid of commercials. This task is better performed with a non-linear video editor. ffmpeg is not exactly one of these, it is only a video encoding and conversion tool but I can cope with it. Here's how. To find out the seek points and durations with great precision I use the following mplayer(1) keyboard controls. BTW mplayer is a featureful and fast command line movie player for Linux based on ffmpeg, of course.
<- and -> Seek backward/forward 10 seconds.
up and down Seek forward/backward 1 minute.
pgup and pgdown Seek forward/backward 10 minutes.
[ and ] Decrease/increase current playback speed by 10%.
{ and } Halve/double current playback speed.
Backspace Reset playback speed to normal
p / SPACE Pause (pressing again unpauses).
. Step forward. Pressing once will pause movie, every consecutive press will play one frame and then go into pause mode again (any other key unpauses).
o Toggle onscreen display (OSD) states: none / seek / seek + timer / seek + timer + total time.
q / ESC Stop playing and quit.
Then using ffmpeg I extract each sequence of the program into a separate MPEG file:
ffmpeg -i input.mpg -vcodec copy \
-acodec copy -ss sequence_start \
-t sequence_duration output1.mpg
To join these pieces of video I can just use cat(1) because the MPEG files allows concatenation:
cat output1.mpg output2.mpg \
... outputN.mpg >output.mpg
If you want something more simple and interactive you can use MPlayer EDL's (Edit Decision Lists):
mplayer -edlout input.edl input.mpg
Press i to set the start or end of a skip block. You can use all the backward/forward seek commands described in the table above. Timings will be written to the specified human-readable text file, which is easy to fine-tune with a simple ASCII text editor. Review your cutted video with:
mplayer -edl input.edl input.mpg
If you are satisfied, you can assemble your video with:
mencoder -oac copy -ovc copy \
-edl input.edl input.mpg -o output.mpg
Note I avoid recoding which takes more time and causes a loss of quality, especially for TV programs. If the format used does not allow concatenation, I prefer to keep the pieces in separate files.

1 comment:

wolfgang grinfeld said...

I found mplayer to have a different time-keeping scheme when compared to mencoder. At least with an HD TS stream.
And in case of H264, it has trouble resolving I-frames.

Therefore my solution for these type of streams goes in the form of:
./mencoder -forceidx -ni -oac copy -ovc copy -nosound -o $output \n \$in\ -ss 01:01:27 -frames 1 -lavdopts skipframe=nonkey \n \$in\ -ss 01:01:27 -frames 33260 \n \$in\ -ss 05:03:00 -frames 1 -lavdopts skipframe=nonkey \n \$in\ -ss 05:03:00 -frames 33480 \n
./mplayer.exe $output

add the sound, as required;
use endpos, if preferred to frames.