2012

FFmpeg

Ffmpeg is a workhorse video encoder/transcoder, capable of complex transforms but not especially user friendly (when using advanced options anyway)

ffmpeg -i infile.vob -vcodec libx264
-crf 17 -preset slower -tune animation
-acodec libfaac -ab 160k -ac 2
Example Full command
-vf yadif=3
Deinterlace a video. Yadif by itself does a good job, but I've had the best results when set to 3. Remember the order matters. For instance, you probably want to deinterlace before resizing a movie.
-vf lutyuv=y=val*1.3
Not a common problem, but you can change the brightness during encoding

MP4

-acodec libfaac -ab 160k -ac 2
Encode audio using the aac codec. This uses the faac library which which is not licenced under the GPL.
Nothing special about -ac (audio channels), but I've had ffmpeg get confused and barf without it.
-af 'volume=0.5'
Adjust volume (1 = current volume)
-acodec libfdk_aac -vbr 4 -afterburner 1 -ac 2
Use the Fraunhofer (if supported). This may be the highest quality encoder supported by ffmpeg, but has proprietary licencing.
vbr is variable bitrate. Supported range is 1 to 5. Default is 3.
1about 32 kbs/channel
2about 40 kbs/channel
3about 48-56 kbs/channel
4about 64 kbs/channel
5about 80-96 kbs/channel
At any range -afterburner 1 is "improved quality" mode. This increases the file size slightly.
-profile: a aac_he
Use high efficency AAC codec instead of the default "low complexity". High efficiency can improve quality at low bitrates, with little or no benefit none at high bitrates. flash player supports AAC-HE version 1, but not 2.
-profile:a aac_he_v2
HE-AAC Version 2. May offer improvments over V1 at very low bitrates. I've had mixed results but generally favor it at low bitrates compared to AAC-HE. A good rule of thumb: LC over 80kbs, HE-AACv1 over 48kbs and HE-AACv2 under 48kbs.
-vcodec libx264 -crf 17
crf is "constant rate factor" or variable bitrate. Enncoding is based on arbitrary quality (not size). The range is from 0 to 51 with 0 being the highest, and 23 being the default. Crf is the best option for 1 pass encoding.
-preset slower
x264 presets trade quality (and size) for encoding speed. Supported settings are: ultrafast, superfast, veryfast, faster, fast, medium, slow, slower, veryslow, placebo. The default is medium. Use the slowest setting you can tolerate. For me that's "slower".
-tune animation
Options are: film, animation, grain, stillimage, psnr, ssim, fastdecode, zerolatency. "film" means live action in this case (not animated).

Hard Burning Subtitles

Sometimes I struggle transcoding MKV files with audio/video going out of sync. If I can see the video, can't I transcode it? That's possible using named pipes; feeding one output to another.

So:   {player} -→ {named-pipe} -→ {encoder}

Named pipes are essentially the same as command line pipes, but given a name on the filesystem. One program writes information to the named pipe file, while another reads it. The OS handles the details. You create a named pipe using the mkfifo command. While this can be named anything, ffmpeg behaves a certain way depending on the file extension, so the pipe name is important.

Mplayer works, but how well it works is another matter. It fully supports yuv4mpeg, which gives the header information for the encoder, so stuff like color space, frame rate, and resolution are all passed along (unlike raw video). By default mplayer will write to "stream.y4m", so a named pipe of this name must be made before encoding. (-ac null means mplayer won't process the sound)

mplayer $file -noframedrop -ac null -ao null -really-quiet -vo yuv4mpeg &

Mpv is my current choice of player, which handles subtitles well, however I couldn't get yuv4mpeg to work. (What the man page claims does not work for me.) So the output must be raw video, meaning the encoder needs to know what kind of data it's getting: framerate/resolution/etc. This also produces substantially more data. 10 seconds of video can be 1Gb of data, so the only workable way to do this is through a named pipe. The pipe name matters. Make sure the extension of the pipe is ".yuv".

mpv $file -o pipe.yuv --really-quiet --no-audio --oautofps --oneverdrop &

flv audio with image

ffmpeg -i pic.png -loop_input -r 1 -time 0:0x:00 ${audio_options} output.flv
ffmpeg can use a sequence of images, but -loop_input will reuse the same image over and over. Note: because the image loop never ends, ffmpeg will never stop encoding, therefore you need to set the -time argument to the length of the song.
Because there is only a picture a frame rate isn't required, however the default default framerate of 25 is obviously inefficent. You can use a rate of 1 frame per movie with -r to 1/(time), 1/9999, etc. Seeking however is tied to keyframes, so this has the side effect of disabling any skipping around in the file (for most media players). Thus I've had better success with a framrate of 1 fps (-r 1).
-ar 44100
Explicitly setting the audio rate (example 22050) can save space. Flv encoding will sometimes barf if this isn't explicitly set.
FFmpeg