[Index]
PART I – Introduction (revised 02-jul-2012)
PART II – Parameters and recipes (revised 02-jul-2012)
PART III – Encoding in H.264 (revised 02-jul-2012)
PART IV – FFmpeg for streaming (revised 02-jul-2012)
PART V – Advanced usage (revised, 19-oct-2012)
PART VI – Filtering (new, 19-oct-2012)
(because of the success of this series I have decided to revise the content of the articles, update the syntax of command lines to recent api changes and extend the series with a fifth part, good reading!)
Second part
After the short introduction of the previous article, now it’s time to see FFmpeg in action. This post is dedicated to the most important parameters and ends with an example of transcoding to H.264. FFmpeg supports hundreds of AV formats and codecs as input and output (for a complete list type ffmpeg -formats and ffmpeg -codecs) but you know that nowadays the most important output format is without doubt H.264.
H.264 is supported by Flash (99% of computers + mobile), iOS, Android, BlackBerry, low-end mobile devices, STBs and Connected TVs. So why target different formats ? A streaming professional has primarily to master H.264. Other formats are marginal, even Google’s VP8 which is still in a too early phase of adoption.
FFmpeg is vast subject, so I’ll focus on what I think to be the most important options and a useful selection of command lines. But first of all, how to find a build of FFmpeg to start managing your video?
The shortest path if you don’t want to built from source code is to visit Zeranoe’s FFmpeg builds. Remember that there are several libraries that can be included or excluded in the build and so if you need something special or a fine control onthe capabilities of your build, the longest path is the best.
KEY PARAMETERS
This is the base structure of an FFmpeg invocation:
ffmpeg -i input_file […parameter list…] output_file
Input_file and output_file can be defined not only as file system objects but a number of protocols are supported: file, http, pipe, rtp/rtsp, raw udp, rtmp. I’ll focus on the possiblity to use RTMP as input and/or output in the fourth part of this series, while in the following examples I’ll use only the local file option.
FFmpeg supports litterally hundreds of parameters and options. Very often, FFmpeg infers the parameters from the context, for example the input or output format from the file extention and it also applies default values to unspecified parameters. Sometimes it is instead necessary to specify some important parameters to avoid errors or to optimize the encoding.
Let’s start with a selection of the most important, not codec related, parameters:
-formats print the list of supported file formats
-codecs print the list of supported codecs (E=encode,D=decode)
-i set the input file. Multiple -i switchs can be used
-f set video format (for the input if before of -i, for output otherwise)
-an ignore audio
-vn ignore video
-ar set audio rate (in Hz)
-ac set the number of channels
-ab set audio bitrate
-acodec choose audio codec or use “copy” to bypass audio encoding
-vcodec choose video codec or use “copy” to bypass video encoding
-r video fps. You can also use fractional values like 30000/1001 instead of 29.97
-s frame size (w x h, ie: 320x240)
-aspect set the aspect ratio i.e: 4:3 or 16:9
-sameq ffmpeg tries to keep the visual quality of the input
-t N encode only N seconds of video (you can use also the hh:mm:ss.ddd format)
-croptop, -cropleft, -cropright, -cropbottom crop input video frame on each side
-y automatic overwrite of the output file
-ss select the starting time in the source file
-vol change the volume of the audio
-g Gop size (distance between keyframes)
-b Video bitrate
-bt Video bitrate tolerance
-metadata add a key=value metadata
SYNTAX UPDATE (*)
The syntax of some commands have changed. Commands like -b (is the bitrate related to audio or video?) have now a different syntax:
Use:
-b:a instead of -ab to set audio bitrate
-b:v instead of -b to set video bitrate
-codec:a or -c:a instead of -acodec
-codec:v or -c:v instead of -vcodec
Most of these parameters allow also a third optional number to specify the index of the audio or video channel to use.
Es: -b:a:1 to specify the bitrate of the second audio stream (the index is 0 based).
Read official documentation for more info: http://ffmpeg.org/ffmpeg.html
COMMAND LINES EXAMPLES
And now let’s combine these parameters to manipulate AV files:
1. Getting info from a video file
ffmpeg -i video.mpg
Useful to retrieve info from a media file like audio/video codecs, fps, frame size and other params. You can parse the output of the command line in a script redirecting the stderr channel to a file with a command like this:
ffmpeg –i inputfile 2>info.txt
2. Encode a video to FLV
ffmpeg –i input.avi –r 15 –s 320×240 –an video.flv
By default FFmpeg encodes flv files in the old Sorenson’s Spark format (H.263). This can be useful today only for compatibility with older systems or if you wanto to encode for a Wii (which supports only Flash Player 7).
Before the introduction of H.264 in Flash Player I was used to re-encode the FLVs recorded by FMS with a command like this:
ffmpeg –i input.flv –acodec copy –sameq output.flv
(ffmpeg –i input.flv –codec:a copy –sameq output.flv)
This produced a file 40-50% smaller with the same quality of the input, preserving at the same time the Nellymoser ASAO audio codec which was not supported by FFmpeg in such days and therefore not encodable in something else.
Today you can easily re-encode to H.264 and also transcode ASAO or Speex to something else.
VP6 codec (Flash Player 8+) is officially supported only in decoding.
3. Encode from a sequence of pictures
ffmpeg -f image2 -i image%d.jpg –r 25 video.flv
Build a video from a sequence of frame with a name like image1.jpg,image2.jpg,..,imageN.jpg
Is it possible to use different naming conventions like image%3d.jpeg where FFmpeg search for file with names like image 001.jpeg, image002.jpg, etc…The output is an FLV file at 25Fps.
4. Decode a video into a sequence of frames
ffmpeg -i video.mp4 –r 25 image%d.jpg
Decodes the video in a sequence of images (25 images per second) with names like image1, image2, image 3, … , imageN.jpg. It’s possible to change the naming convention.
ffmpeg –i video.mp4 –r 0.1 image%3d.jpg
Decodes a picture every 10 seconds (1/0.1=10). Useful to create a thumbnail gallery for your video. In this case the putput files have names like image001, image002, etc.
ffmpeg –i video.mp4 –r 0.1 –t 20 image%3d.jpg
Extracts 2-3 images from the first 20 seconds of the source.
5. Extract an image from a video
ffmpeg -i video.avi -vframes 1 -ss 00:01:00 -f image2 image-%3d.jpg
(ffmpeg -i video.avi -frames:v 1 -ss 00:01:00 -f image2 image-%3d.jpg)
This is a more accurate command for image extraction. It extracts only 1 single frame (-vframes 1) starting 1min from the start of the video. The thumbnail will have the name image-001.jpg.
ffmpeg -i video.avi -r 0.5 -vframes 3 -ss 00:00:05 -f image2 image-%3d.jpg
(ffmpeg -i video.avi -r 0.5 -frames :v 3 -ss 00:00:05 -f image2 image-%3d.jpg)
In this case FFmpeg will extract 3 frames, each every 1/0.5=2seconds, starting from time 5s. Useful for video CMS where you want to offer a selection of thumbnails and a backend user choose the best one.
6. Extract only audio track without re-encoding
ffmpeg -i video.flv -vn -c:a copy audio.mp3
Here I assume that the audio track is an mp3. Use audio.mp4 if it is AAC or audio.flv if it is ASAO or Speex. Similarly you can extract the video track without re-encoding.
7. Extract audio track with re-encoding
ffmpeg -i video.flv -vn -ar 44100 -ac 2 -ab 128k -f mp3 audio.mp3
This command extract audio and transcode to MP3. Useful when the video.flv is saved by FMS and has an audio track encoded with ASAO or Speex.
ffmpeg –i video.flv –vn –c:a libaac –ar 44100 –ac 2 –ab 64k audio.mp4
The same as above but encoded to AAC.
8. Mux audio + video
ffmpeg -i audio.mp4 -i video.mp4 output.mp4
Depending by the content of the input file you may need to use the map setting to choose and combine the audio video tracks correctly. Here I suppose to have an audio only and video only input files.
9. Change container
ffmpeg –i input.mp4 –c:a copy –c:v copy output.flv
I use this to put h.264 in FLV container, sometimes it is useful. This kind of syntax will come back when we will talk about FFmpeg and RTMP.
10. Grab from a webcam
On Linux it is easy to use an audio or video grabbing device as input to FFmpeg:
ffmpeg -f oss -i /dev/dsp -f video4linux2 -i /dev/video0 out.flv
On windows it is possible to use vfwcap (only video) or direct show (audio and video):
ffmpeg -r 15 -f vfwcap -s 320×240 -i 0 -r 15 -f mp4 webcam.mp4
ffmpeg -r 15 -f dshow -s 320×240 -i video=”video source name”:audio=”audio source name” webcam.flv
Notice here that the parameters –r –f –s are setted before –i.
11. Extract a slice without re-encoding
ffmpeg -i input -ss 00:01:00 -t 00:01:00 -c:a copy -c:v copy output.mp4
Extract 1min of video starting from time 00:01:00. Be aware that putting the -ss and -t parameters before or after -i may have different effects.
12. Make a video file from a single frame
ffmpeg -loop_input -frames:v 1 -i frame.jpg -t 10s -r 25 output.mp4
Generate a video with 25Fps and length 10s from a single frame. Playing with -vframes it is possible to loop a sequence of frames (not video). Note: -loop_input is deprecated in favor of -loop (filter option).
13. Add metadata
ffmpeg -i input.flv -c:v copy -c:a copy -metadata title=”MyVideo” output.flv
Useful to change or add metadata like resolution, bitarate or other info
14. Encode to H.264
Let’s conclude this second part of the series with an example of encoding to H.264 + AAC. In the example above I have used, for simplicity sake, FLV or MP4 output. But to encode to H.264 you have to explicitly set the output codec and some required parameters.
ffmpeg -y -i input.mov -r 25 -b 1000k -c:v libx264 -pass 1 -vpre fastfirstpass -an output.mp4
ffmpeg -y -i input.mov -r 25 -b 1000k -c:v libx264 -pass 2 -vpre hq -acodec libfaac -ac 2 -ar 44100 -ab 128k output.mp4
This first example tells FFmpeg to use the libx264 to produce a H.264 output. We are using a two pass encoding (-pass 1 generate only a stat file that will be used by a second pass). The -vpre option tells FFmpeg to use the preset file “fastfirstpass” that its found in the preset folder of the FFmpeg installation directory. The second line performs the second pass using a more accurate preset (-vpre hq) and adds the audio encoding.
FFmpeg use a dedicated remapping of the most important parameters of libx264. x264 has an high number of parameters and if you know what you are doing you can also set each of them individually instead of using a predefined preset. This is an example of two pass encoding without preset:
ffmpeg -y -i input -r 25 -b 1000k -c:v libx264 -pass 1 -flags +loop -me_method dia -g 250 -qcomp 0.6 -qmin 10 -qmax 51 -qdiff 4 -bf 3 -b_strategy 1 -i_qfactor 0.71 -cmp +chroma -subq 1 -me_range 16 -coder 1 -sc_threshold 40 -flags2 -bpyramid-wpred-mixed_refs-dct8x8+fastpskip -keyint_min 25 -refs 3 -trellis 0 -directpred 1 -partitions -parti8x8-parti4x4-partp8x8-partp4x4-partb8x8 -an output.mp4
ffmpeg -y -i input -r 25 -b 1000k -c:v libx264 -pass 2 -flags +loop -me_method umh -g 250 -qcomp 0.6 -qmin 10 -qmax 51 -qdiff 4 -bf 3 -b_strategy 1 -i_qfactor 0.71 -cmp +chroma -subq 8 -me_range 16 -coder 1 -sc_threshold 40 -flags2 +bpyramid+wpred+mixed_refs+dct8x8+fastpskip -keyint_min 25 -refs 3 -trellis 1 -directpred 3 -partitions +parti8x8+parti4x4+partp8x8+partb8x8 -acodec libfaac -ac 2 -ar 44100 -ab 128k output.mp4
IN THE NEXT PART
In this second part of the series we have taken a look at the most important “not codec related” features of FFmpeg.
The next part will entirely dedicated to how encode to H.264 using FFmpeg and libx264.
[Index]
PART I – Introduction (revised 02-jul-2012)
PART II – Parameters and recipes (revised 02-jul-2012)
PART III – Encoding in H.264 (revised 02-jul-2012)
PART IV – FFmpeg for streaming (revised 02-jul-2012)
PART V – Advanced usage (revised, 19-oct-2012)
PART VI – Filtering (new, 19-oct-2012)