Vicente González Ruiz
September 12, 2016
Contents
Chapter 1
Introduction
1.1 FFMPEG vs Libav
1.2 Free sofware and patents
- Both, FFMPEG and Libav contains more than 100 codecs. Many codecs
that compress information have been claimed by patent holders. Such
claims may be enforceable in countries like the United States which have
implemented software patents, but are considered unenforceable or void
in countries that have not implemented patents.
2.1 FFMPEG
- In Debian/Ubuntu this is the preferable way because: (1) is the most general –
it could be used in any distribution without significative modifications –, (2)
uses the lastest software and (3) produces the most efficient machine
code.
mkdir ~/src
cd ~/src
# libx264
wget http://download.videolan.org/pub/x264/snapshots/last_x264.tar.bz2
tar xjvf last_x264.tar.bz2
cd x264-snapshot*
PATH="$PATH:$HOME/bin" ./configure --prefix="$HOME/ffmpeg_build" --bindir="$HOME/bin" --enable-static --disable-opencl
PATH="$PATH:$HOME/bin" make
make install
make distclean
cd ..
# libfdk-aac (make sure "libtool" is installed)
wget -O fdk-aac.zip https://github.com/mstorsjo/fdk-aac/zipball/master
unzip fdk-aac.zip
cd mstorsjo-fdk-aac*
autoreconf -fiv
./configure --prefix="$HOME/ffmpeg_build" --disable-shared
make
make install
make distclean
cd ..
# libmp3lame (make sure "nasm" is installed)
wget http://downloads.sourceforge.net/project/lame/lame/3.99/lame-3.99.5.tar.gz
tar xzvf lame-3.99.5.tar.gz
cd lame-3.99.5
./configure --prefix="$HOME/ffmpeg_build" --enable-nasm --disable-shared
make
make install
make distclean
cd ..
# libopus
wget http://downloads.xiph.org/releases/opus/opus-1.1.tar.gz
tar xzvf opus-1.1.tar.gz
cd opus-1.1
./configure --prefix="$HOME/ffmpeg_build" --disable-shared
make
make install
make distclean
cd ..
# libvpx (VP8/VP9)
wget http://webm.googlecode.com/files/libvpx-v1.3.0.tar.bz2
tar xjvf libvpx-v1.3.0.tar.bz2
cd libvpx-v1.3.0
PATH="$PATH:$HOME/bin" ./configure --prefix="$HOME/ffmpeg_build" --disable-examples
PATH="$PATH:$HOME/bin" make
make install
make clean
cd ..
# libogg
wget http://downloads.xiph.org/releases/ogg/libogg-1.3.1.tar.gz
tar xvf libogg-1.3.1.tar.gz
cd libogg-1.3.1
./configure --prefix="$HOME/ffmpeg_build" --disable-shared
make
make install
make distclean
cd ..
# libvorbis
wget http://downloads.xiph.org/releases/vorbis/libvorbis-1.3.3.tar.gz
tar xvf libvorbis-1.3.3.tar.gz
cd libvorbis-1.3.3
./configure --prefix="$HOME/ffmpeg_build" --disable-shared
make
make install
make distclean
cd ..
# libtheora (make sure "texlive-fonts-recommended" and "doxygen" are installed)
wget http://downloads.xiph.org/releases/theora/libtheora-1.1.1.tar.bz2
tar xjvf libtheora-1.1.1.tar.bz2
cd libtheora-1.1.1
./configure --prefix="$HOME/ffmpeg_build" --disable-shared --with-ogg="$HOME/ffmpeg_build"
make
make install
make distclean
cd ..
# ffmpeg (make sure "libass-dev", "libasound2-dev", "libsdl1.2-dev"
# and "libx11-dev" are installed)
git clone git://source.ffmpeg.org/ffmpeg.git ffmpeg
cd ffmpeg
PATH="$PATH:$HOME/bin" PKG_CONFIG_PATH="$HOME/ffmpeg_build/lib/pkgconfig" ./configure \
--prefix="$HOME/ffmpeg_build" \
--extra-cflags="-I$HOME/ffmpeg_build/include" \
--extra-ldflags="-L$HOME/ffmpeg_build/lib" \
--bindir="$HOME/bin" \
--enable-gpl \
--enable-libass \
--enable-libfdk-aac \
--enable-libfreetype \
--enable-libmp3lame \
--enable-libopus \
--enable-libtheora \
--enable-libvorbis \
--enable-libvpx \
--enable-libx264 \
--enable-nonfree \
--extra-libs=-lasound \
--enable-x11grab
# Note: at the moment of writting this document, there is a bug in the
# "x11grab" code (libxcb). If it persits, remove this option.
make
make install
make distclean
hash -r
2.2 Libav
2.2.1 Ubuntu
sudo apt-get install x264 # H.264
sudo apt-get install libav-tools # avconv
Chapter 3
Tools and help
3.1 FFMPEG/Libav command line tools
- ffmpeg/avconv: encodes and transcodes.
- ffplay/avplay: playbacks a video.
- ffprobe/avprobe: gathers information from multimedia streams.
- ffserver/avserver: a streaming server for both audio and video
3.2 manual
3.3 Built-in help
ffmpeg -help
avconv -help
3.4 Synopsis
ffmpeg/aconv [global_options] {[input_file_options] -i input_file} ... {[output_file_options] output_file} ...
wget http://www.hpca.ual.es/~vruiz/videos/coastguard_352x288x30x420x300.avi
ffmpeg -i /tmp/coastguard_352x288x30x420x300.avi
# or ...
ffprobe /tmp/coastguard_352x288x30x420x300.avi
Chapter 5
Capturing
5.1 Recognized devices
ffmpeg -devices
avconv -formats
# Record 30 seconds, stereo, CD quality, from the ALSA mic
ffmpeg -f alsa -ac 2 -ar 44100 -i default -t 30 out.wav
ffmpeg -f alsa -ac 2 -ar 44100 -i hw:0 -t 30 out.wav
avconv -f alsa -ac 2 -ar 44100 -i hw:0 -t 30 out.wav
- Video4Linux (V4L) is a part of the Linux Kernel which provides an unified
API for video capture (such as a WebCam). At this moment, it is as a
subsystem of the LinuxTV Project (V4L2, Analog TV, DVB and Remote
Controllers).
ffmpeg -f video4linux2 -s 640x480 -r 30 -i /dev/video0 /tmp/1.avi # (/dev/video0 = WebCam)
avconv -f video4linux2 -s 640x480 -r 30 -i /dev/video0 /tmp/1.avi
# Grab CIF region from origin:
ffmpeg -f x11grab -framerate 25 -video_size cif -i :0.0 -f mpegts - | ffplay -
# ^ ^
# | |
# | +-----+
# | |
# :server.display
# Grab from coordinates (10, 20):
ffmpeg -f x11grab -show_region 1 -framerate 25 -video_size cif -i :0.0+10,20 -f mpegts - | ffplay -
avconv -f x11grab -show_region 1 -framerate 25 -video_size cif -i :0.0+10,20 -f mpegts - | avplay -
# Grab following the mouse (centered in the captured window):
ffmpeg -f x11grab -show_region 1 -follow_mouse centered -framerate 25 -video_size cif -i :0.0 -f mpegts - | ffplay -
avconv -f x11grab -show_region 1 -follow_mouse centered -framerate 25 -video_size cif -i :0.0 -f mpegts - | avplay -
# Capture the full screen, with audio, and produce a file:
ffmpeg -framerate 25 -f x11grab -i :0.0 -f alsa -ac 2 -i default output.flv
Chapter 6
Converting
ffmpeg -formats # List formats (containers)
ffmpeg -codecs # List codecs (algorithms)
- FFMPEG/Libav does not provide a native encoder for H.264 but wraps
x264.
6.2.1 Presets and Tunes
- As it can be seen with:
x264 --help
presets are ultrafast, uperfast, veryfast, faster, fast, medium, slow,
slower, veryslow and placebo. From left to right, the compression ratio
grows although you more computational resources are needed (roughtly
speaking, twice as slow as the previous). Tunings are film, animation,
grain (used for very grainy or old content), stillimage, psnr (Peak
Signal-to-Noise Ratio), ssim (Structural SIMilarity), fastdecode and
zerolatency.
- Tunings and presets can be mixed and matched, e.g. -preset fast -tune
film.
6.2.2 Example
ffmpeg -f video4linux2 -s 640x480 -r 30 -i /dev/video0 -c:v libx264 -tune zerolatency -preset medium -b:v 800k -f mpegts - | ffplay -
avconv -f video4linux2 -s 640x480 -r 30 -i /dev/video0 -c:v libx264 -tune zerolatency -preset medium -b:v 800k -f mpegts - | avplay -
- Profiles enforce a standard, ensuring compatibility with specific targets by
restricting the encoding features used. Nowadays most decoders support
the high profile, so this setting could be ignored.
# Highest compatibility (-profile:v baseline -level 3.0)
ffmpeg -f video4linux2 -s 640x480 -r 30 -i /dev/video0 -pix_fmt yuv420p -c:v libx264 -profile:v high -level:v 4.0 -b:v 800k -f mpegts - | ffplay -
# Full compatibility (-profile:v baseline -level 30
ffmpeg -f video4linux2 -s 640x480 -r 30 -i /dev/video0 -pix_fmt yuv420p -c:v libx264 -profile:v baseline -level:v 30 -b:v 800k -f mpegts - | ffplay -
ffmpeg -f video4linux2 -s 640x480 -r 30 -i /dev/video0 -pix_fmt yuv420p -c:v libx264 -profile:v baseline -level:v 3.0 -b:v 800k -f mpegts - | ffplay -
avconv -f video4linux2 -s 640x480 -r 30 -i /dev/video0 -pix_fmt yuv420p -c:v libx264 -profile:v baseline -level:v 30 -b:v 800k -f mpegts - | avplay -
# Apple Devices from 2010 (-profile:v main -level 3.1)
ffmpeg -f video4linux2 -s 640x480 -r 30 -i /dev/video0 -pix_fmt yuv420p -c:v libx264 -profile:v high -level:v 3.1 -b:v 800k -f mpegts - | ffplay -
avconv -f video4linux2 -s 640x480 -r 30 -i /dev/video0 -pix_fmt yuv420p -c:v libx264 -profile:v high -level:v 31 -b:v 800k -f mpegts - | avplay -
# Apple Ipad2 and AppleTV 3 (-profile:v high -level 4.1)
ffmpeg -f video4linux2 -s 640x480 -r 30 -i /dev/video0 -pix_fmt yuv420p -c:v libx264 -profile:v baseline -level:v 41 -b:v 800k -f mpegts - | ffplay -
avconv -f video4linux2 -s 640x480 -r 30 -i /dev/video0 -pix_fmt yuv420p -c:v libx264 -profile:v baseline -level:v 41 -b:v 800k -f mpegts - | avplay -
6.2.4 Quality control
- This mode compress the video using a constant quality along time.
Therefore, it provides the maximun quality although we don’t have control
on the bit-rate (the only we know, as rule of thumb, is that every increase
pf the quantization value by 5 halves the bitrate, 0 being lossless encoding).
ffmpeg -f video4linux2 -s 640x480 -r 30 -i /dev/video0 -c:v libx264 -crf 38 -crf_max 42 -f mpegts - | ffplay -
avconv -f video4linux2 -s 640x480 -r 30 -i /dev/video0 -c:v libx264 -crf 38 -crf_max 42 -f mpegts - | avplay -
- You can control the maximun and minimun bit-rates, and the maximum buffer
size. In this case, the quantization value could change although his value can be
also controlled. Example:
ffmpeg -f video4linux2 -s 640x480 -r 30 -i /dev/video0 -c:v libx264 -crf 38 -crf_max 42 -maxrate 4M -bufsize 2M -f mpegts - | ffplay -
avconv -f video4linux2 -s 640x480 -r 30 -i /dev/video0 -c:v libx264 -crf 38 -crf_max 42 -maxrate 4M -bufsize 2M -f mpegts - | avplay -
6.2.5 Bit-rate control
6.2.6 Lossless encoding
- Setting -crf or -qp to 0 forces x264 in lossless mode. In this case, the
-preset settings then impact just the speed/size.
- Fastest encoding:
avconv -i input -c:v libx264 -preset superfast -qp 0 -c:a copy out.mkv
- Smallest filesize:
avconv -i input -c:v libx264 -preset veryslow -qp 0 -c:a copy out.mkv
6.3 HEVC
# H.264 lossless:
wget http://www.hpca.ual.es/~vruiz/videos/coastguard_352x288x30x420x300.avi
# Lossy encode:
ffmpeg -i coastguard_352x288x30x420x300.avi -c:v hevc coastguard_352x288x30x420x300.mp4
# Get info:
ffprobe coastguard_352x288x30x420x300.mp4
# Play it:
ffprobe coastguard_352x288x30x420x300.mp4
# Download a SBS 3D video:
youtube-dl https://www.youtube.com/watch?v=YWWbZLl2evE
# Change the name:
mv Hang Gliding With The GoPro - 3D Side by Side (SBS)-YWWbZLl2evE.mp4 sbs.mp4
# Convert from SBS to "Red cyan gray/monochrome" anaglyph:
ffmpeg -i sbs.mp4 -vf stereo3d=sbs2l:arcg -acodec copy anaglyph.mp4
Chapter 7
Editing
7.1 Extracting and inserting images
wget http://www.hpca.ual.es/~vruiz/videos/coastguard_352x288x30x420x300.avi
# Extracting the images of a (color) video
ffmpeg -i coastguard_352x288x30x420x300.avi coastguard_%3d.png
avconv -i coastguard_352x288x30x420x300.avi coastguard_%3d.png
animate *.png
# Creating a video with a collection of images
ffmpeg -i coastguard_%3d.png coastguard.avi
avconv -i coastguard_%3d.png coastguard.avi
mplayer coastguard.avi
7.2 Creating two videos in parallel
# Creating two videos (with two different formats) in parallel
ffmpeg -i coastguard_352x288x30x420x300.avi -map 0 1.mkv -map 0 2.mp4
ffmpeg -i 1.mkv
ffmpeg -i 2.mp4
avconv -i coastguard_352x288x30x420x300.avi -map 0 1.mkv -map 0 2.mp4
avconv -i 1.mkv
avconv -i 2.mp4
7.3 Copy and paste
wget http://www.hpca.ual.es/~vruiz/videos/mobile_352x288x30x420x300.avi
ffmpeg -i coastguard_352x288x30x420x300.avi
ffmpeg -i mobile_352x288x30x420x300.avi
# Concatenate two videos
ffmpeg -i "concat:coastguard_352x288x30x420x300.avi|mobile_352x288x30x420x300.avi" -y -map 0 -c copy concat.avi
vlc concat.avi
# Paste two videos
ffmpeg -i coastguard_352x288x30x420x300.avi -i mobile_352x288x30x420x300.avi -c copy -map 0:0 -map 1:0 concat.avi
vlc concat.avi
Chapter 8
Transcoding
8.1 Bit-rate
# What’s inside a file:
ffmpeg -i input.mkv
# Set the video bitrate of the output file to 64 kbit/s:
$ ffmpeg -i input.avi -b:v 64k -bufsize 32k output.avi
8.2 Frame-rate
# Force the frame rate of the output file to 24 fps:
ffmpeg -i input.avi -r 24 output.avi
# Force the frame rate of the input file (valid for raw formats
# only) to 1 fps and the frame rate of the output file to 24 fps:
ffmpeg -r 1 -i input.m2v -r 24 output.avi
Chapter 9
Streaming
9.1 One-to-one unicast
# Sender:
## UDP:
ffmpeg -f alsa -i hw:0,0 -acodec mp2 -f video4linux2 -s 640x480 -r 30 -i /dev/video0 -f mpegts udp://localhost:8888 # Runme first!
## TCP:
ffmpeg -f video4linux2 -s 640x480 -r 30 -i /dev/video0 -f mpegts tcp://localhost:8888 # Runme last!
## RTP/RTSP
ffmpeg -f video4linux2 -s 640x480 -r 30 -i /dev/video0 -f rtsp -rtsp_transport tcp rtsp://localhost:8888/live.sdp # Runme last!
# Receiver:
## UDP:
ffplay -i udp://localhost:8888 # Runme last!
## TCP:
ffplay -i tcp://localhost:8888?listen # Runme first!
## RTP/RTSP
ffplay -rtsp_flags listen rtsp://localhost:8888/live.sdp?tcp # Runme first!
9.2 Multicast
# Sender:
## UDP:
ffmpeg -f video4linux2 -s 640x480 -r 30 -i /dev/video0 -f mpegts udp://236.0.0.1:8888 # Runme first!
# Receiver:
## UDP:
ffplay -i udp://236.0.0.1:8888 # Runme last!
9.3 One-to-many unicast
cat > ffserver.conf << EOF
Port 8090
# bind to all IPs aliased or not
BindAddress 0.0.0.0
# max number of simultaneous clients
MaxClients 1000
# max bandwidth per-client (kb/s)
MaxBandwidth 10000
# Suppress that if you want to launch ffserver as a daemon.
NoDaemon
<Feed feed1.ffm>
File /tmp/feed1.ffm
FileMaxSize 5M
</Feed>
# FLV output - good for streaming
<Stream test.flv>
# the source feed
Feed feed1.ffm
# the output stream format - FLV = FLash Video
Format flv
VideoCodec flv
# this must match the ffmpeg -r argument
VideoFrameRate 15
# generally leave this is a large number
VideoBufferSize 80000
# another quality tweak
VideoBitRate 200
# quality ranges - 1-31 (1 = best, 31 = worst)
VideoQMin 1
VideoQMax 5
VideoSize 352x288
# this sets how many seconds in past to start
PreRoll 0
# wecams don’t have audio
Noaudio
</Stream>
# ASF output - for windows media player
<Stream test.asf>
# the source feed
Feed feed1.ffm
# the output stream format - ASF
Format asf
VideoCodec msmpeg4
# this must match the ffmpeg -r argument
VideoFrameRate 15
# generally leave this is a large number
VideoBufferSize 80000
# another quality tweak
VideoBitRate 200
# quality ranges - 1-31 (1 = best, 31 = worst)
VideoQMin 1
VideoQMax 5
VideoSize 352x288
# this sets how many seconds in past to start
PreRoll 0
# wecams don’t have audio
Noaudio
</Stream>
##################################################################
# SDP/multicast examples
#
# If you want to send your stream in multicast, you must set the
# multicast address with MulticastAddress. The port and the TTL can
# also be set.
#
# An SDP file is automatically generated by ffserver by adding the
# ’sdp’ extension to the stream name (here
# http://localhost:8090/test1-sdp.sdp). You should usually give this
# file to your player to play the stream.
#
# The ’NoLoop’ option can be used to avoid looping when the stream is
# terminated.
<Stream test1-sdp.mpg>
Format rtp
Feed feed1.ffm
#File "/usr/local/httpd/htdocs/test1.mpg"
MulticastAddress 224.124.0.1
MulticastPort 5000
MulticastTTL 16
NoLoop
</Stream>
EOF
xterm -e "ffserver -f ./ffserver.conf" &
xterm -e "ffmpeg -f alsa -i hw:0,0 -acodec mp2 -f video4linux2 -s 640x480 -r 30 -i /dev/video0 http://localhost:8090/feed1.ffm" &
mplayer http://localhost:8090/test.asf