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.
1 | about 32 kbs/channel |
2 | about 40 kbs/channel |
3 | about 48-56 kbs/channel |
4 | about 64 kbs/channel |
5 | about 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.