Using FFmpeg to Convert and Encode Video and Audio

This document details a set of common commands for encoding video and audio using FFmpeg, a "cross-platform solution to record, convert and stream audio and video".

Video Bitrate Calculator for ffmpeg Encoding

Use the calculators to work out the bitrate or calculate a target file size for the video.

Calculate Video Bitrate

Bitrate = 1241Kb

Calculate Video File Size

File Size = 1000MB

*Note, to include the audio in the calculations, subtract the audio bitrate from the video bitrate.

Converting a DVD to MP4

Extract the VOBs from the DVD
Join the vobs together:
cat *.VOB > mymovie.vob

Find the audio/video streams:
ffmpeg -i mymovie.vob

Extract the audio stream using the FFmpeg installed codecs
Extract the audio stream with the same volume level as the original:
ffmpeg -i mymovie.vob -map 0:1 -c:a aac -b:a 256k -strict experimental -cutoff 22000 mymovie.aac
Extract audio stream with volume level double the original the as audio is quiet:
ffmpeg -i mymovie.vob -map 0:1 -c:a aac -b:a 256k -strict experimental -cutoff 22000 -vol 512 mymovie.aac

Extract the audio stream using FFmpeg compiled with the FDK non free AAC Codec:
Extract the audio stream with the same volume level as the original:
ffmpeg -i mymovie.vob -c:a libfdk_aac -map 0:1 -b:a 256k -vn mymovie.m4a
With the -vol* switch to double the volume level:
ffmpeg -i mymovie.vob -c:a libfdk_aac -map 0:1 -b:a 192k -vol 512 -vn mymovie.m4a
*For newer versions of FFmpeg use the 'volume' switch, for example, '-af volume=2.000000' replaces '-vol 512'.

Extract the video stream
High Quality, larger file size:
ffmpeg -i mymovie.vob -c:v libx264 -an -preset slow -crf 18 mymovie.mp4
Standard quality, in reality very hard to detect the difference and can be as little as half the file size of the high quality option if the video is a 'clean' with little noise:
ffmpeg -i mymovie.vob -c:v libx264 -an mymovie.mp4

Join audio and video with FFmpeg's installed codecs:
ffmpeg -i mymovie.aac -i mymovie.mp4 -c:v copy -c:a copy -bsf:a aac_adtstoasc mymovie_complete.mp4

Join audio and video using FFmpeg compiled with the FDK non free AAC Codec:
ffmpeg -i mymovie.m4a -i mymovie.mp4 -c:v copy -c:a copy -metadata title='My New Movie' mymovie_complete.mp4

Occasionally the aspect ratio of the joined video file may not be correct, the following may be useful in these cases:
ffmpeg -i mymovie.m4a -i mymovie.mp4 -c:v copy -c:a copy -metadata title='My New Movie' -aspect 16:9 mymovie_complete.mp4
					

Converting DVD to MKV format

ffmpeg -i mymovie.vob -c:v libx264 -map 0:1 -c:a libfdk_aac -b:a 192k -map 0:4 mymovie.mkv
					

Converting DVD to MKV format and map and re-encode multiple audio streams

The following copies the codec of the first audio (5.1 - 0:2) stream and re-ecodes the second (0:3) stereo audio stream.

ffmpeg -fflags genpts -i mymovie.vob -map 0:1 -c:v libx264 -map 0:2 -c:a:0 copy -map 0:3 -c:a:1 libfdk_aac -b:a 192k -metadata title="My Movie" mymovie.mkv

Converting DVD to MKV format with subtitles

ffmpeg -analyzeduration 100000k -probesize 100000k -i mymovie.vob -c:v libx264 -map 0:1 -c:a libfdk_aac -b:a 192k -metadata:s:a:0 language=eng -map 0:4 -c:s copy -map 0:6 mymovie.mkv

In the event FFmpeg hangs, try experimenting with the -analyzeduration and -probesize values. These are useful for finding subtitle streams.

ffmpeg -analyzeduration 100000k -probesize 100000k -i mymovie.vob

A robust variant minimising errors and giving higher quality.

ffmpeg -fflags genpts -analyzeduration 100000k -probesize 100000k -i mymovie.vob -c:v libx264 -map 0:1 -c:a libfdk_aac -b:a 192k -metadata:s:a:0 language=eng -map 0:2 -c:s copy -map 0:5 -preset slow -crf 18 -metadata title="My Movie with Subtitles" mymovie_with_subs.mkv

Two pass encoding

This can be useful for video with fast changing content between frames, for example pop videos. Or for video that is grainy or noisy such as old black and white movies.

Separate out the audio stream as above and process the video:
ffmpeg -i mymovie.vob -pass 1 -an -vcodec libx264 -b 1200k my_new_movie.mp4; ffmpeg -i mymovie.vob -pass 2 -an -vcodec libx264 -b 1200k my_new_movie_2pass.mp4
Join audio and video:
ffmpeg -i mymovie.m4a -i my_new_movie_2pass.mp4 -c:v copy -c:a copy -metadata title='my_new_movie' my_new_movie.mp4

Include subtitles in the video

The mkv container is the most widely supported container for players to display subtitles.

ffmpeg -fflags genpts -i mymovie.mp4 -sub_charenc ISO-8859-1 -i mymovie.srt -c:v copy -c:a copy -c:s srt -metadata:s:s:0 language=eng -metadata title="My Movie" mymovie_with_subs.mkv

Or:

ffmpeg -fflags genpts -i mymovie.mp4 -i mymovie.srt -map 0:v -map 0:a -c copy -map 1 -c:s:0 srt -metadata:s:s:0 language=eng mymovie_with_subs.mkv

For problems embedding subtitles in video an alternate method using -vf or -filter:v may help.

ffmpeg -i mymovie.mp4 -filter:v subtitles=mymovie.srt -c:v h264 -preset slow -crf 20 -c:a copy -metadata title="My Movie" mymovie_with_subs.mkv

Embed .ass format subtitles.

ffmpeg -i mymovie.mp4 -vf ass=mymovie.ass -metadata title="My Movie" mymovie_with_subs.mkv

Convert .srt subtitles to .ass format.

ffmpeg -i input.srt subtitles.ass

Bitmap subtitles1. In the example below the video is the first stream.

ffmpeg -i mymovie.mp4 -i mymovie.sub -filter_complex "[0:0:s][0:v]overlay" -c:v libx264 -crf 20 -preset slow -c:a copy -c:s copy -metadata title="My Movie" mymovie.mkv

A Wiki with more detailed explanation of the subtitle options.

1For including external IDX + SUB subtitles using Mkvmerge may be an easier alternative.

mkvmerge -o output_video.mkv --default-language 'eng' --title 'My Video' input_video.avi subtitles.idx

Include two external subtitle streams in the video

Include two external subtitles and metadata into the output video file. The example below includes English (default) and Swedish subtitles.

ffmpeg -fflags genpts -i mymovie.mp4 -i mymovie_eng.srt -i mymovie_swe.srt -map 0:0 -map 0:1 -map 1:0 -map 2:0 -c:a copy -c:v copy -c:s srt -metadata:s:s:0 language=eng -metadata:s:s:1 language=swe -metadata title="My Movie" mymovie.mkv

Add two external audio streams and a subtitle stream to a video file

This adds a 5.1 audio stream (-map 1:a:0) and a stereo stream (-map 2:a:0) from different audio files, both French language. An external english subtitle stream (-map 3:0) is also added.

ffmpeg -fflags genpts -i video_file.mkv -i audio_51_stream.m4a -i audio_stereo_stream.m4a -i my_movie.srt -c:v copy -c:a copy -c:a copy -c:s:0 srt -map 0:v:0 -map 1:a:0 -map 2:a:0 -map 3:0 -metadata:s:a:0 language=fre -metadata:s:a:1 language=fre -metadata:s:s:0 language=eng -metadata title="My New Movie" mymovie_with_audio_and_subs.mkv

Batch converting video to mkv and embed subtitles

The following Linux batch script converts mp4 video container to mkv and includes subtitles. The file names of the .mp4 and .srt files to be muxed must match each other.

for v in *.mp4; do ffmpeg -fflags genpts -i "${v}" -i "${v//.mp4/.srt}" -c:v copy -c:a copy -c:s srt -metadata:s:s:0 language=eng -metadata title="${v//.mp4/''}" "${v//.mp4/.mkv}"; done

Batch convert mp4 video with external metadata text files and embed subtitles

As the batch conversion above with the addition of supplying metadata from external text files.

for v in *.mp4; do ffmpeg -fflags genpts -i "${v}" -i "${v//.mp4/'.txt'}" -i "${v//.mp4/.srt}" -map_metadata 1 -metadata:s:s:0 language=eng -c:s srt -c:v copy -c:a copy "${v//.mp4/.mkv}"; done

Batch convert mp4 video adding two external subtitles and metadata text file

Note the mappings: 0:0 video stream, 0:1 audio stream, 1:0 English subtitle (default), 2:0 Swedish subtitle, -map_metadata 3 (analogous to 3:0) the metadata text file.

for v in *.mp4; do ffmpeg -fflags genpts -i "${v}" -i "${v//.mp4/_eng.srt}" -i "${v//.mp4/_swe.srt}" -i "${v//.mp4/'.txt'}" -map 0:0 -map 0:1 -map 1:0 -map 2:0 -map_metadata 3 -c:a copy -c:v copy -c:s srt -metadata:s:s:0 language=eng -metadata:s:s:1 language=swe  "${v//.mp4/.mkv}"; done

Change a video container

The following example changes the container from the flash format .flv to mp4.
ffmpeg -i input_file.flv -c:v copy -c:a copy -copyts output_file.mp4

This example changes the container from mkv to mp4 keeping the existing video codec but using the FDK non free AAC Codec.
ffmpeg -i input_file.mkv -acodec libfdk_aac -c:v copy output_file.mp4

Sometimes ffmpeg fails with a 'Can't write packet with unknown timestamp' error. Try using the following flags '-fflags genpts', for example:

ffmpeg -fflags genpts -i input_file.avi -c:v copy -c:a copy -metadata title="My Movie" output_file.mkv

Extract audio from a video file

This extracts audio from a video file and converts it to mp3, includes ID3 compatible tags for artist and song, and sets the sample and bit rates.

ffmpeg -i my_music_video.mp4 -map 0:1 -c:a libmp3lame -b:a 192k -ar 48000 -metadata artist="The Artist" -metadata title="Song Title" my_music.mp3

This extracts audio from a video file and converts it to mp3, fades in the audio from the start for four seconds and increases the volume by 6db.

ffmpeg -i my_music_video.mp4 -map 0:1 -c:a libmp3lame -b:a 192k -ar 48000 -af 'afade=t=in:ss=0:d=4,volume=2.00' -metadata artist="The Artist" -metadata title="Song Title" my_music.mp3

Denoise video

Useful for reducing the visible noise, denoising, on old black and white and poorly recorded movies.

ffmpeg -i mymovie.mp4 -vf hqdn3d=1.5:1.5:6:6 -c:v libx264 -c:a copy -metadata title='My Movie' mymovie_denoised.mp4

Slightly less intrusive setting:

ffmpeg -i mymovie.mp4 -vf hqdn3d=4:4:3:3 -c:v libx264 -c:a copy -metadata title='My Movie' mymovie_denoised.mp4

Format: luma_spatial:chroma_spatial:luma_tmp:chroma_tmp

Be warned, the hqdn3d filter can be very hit and miss, some experimentation will be necessary.

Setting the setdar and pixel ratio

Usually the following using the -aspect switch is sufficient to correct aspect problems and doesn't require video re-encoding.

ffmpeg -fflags genpts -i input_file.mp4 -c:v copy -c:a copy -aspect 2.21 output_file.mp4

There are occasions where the setdar is needed.

Find the video frame size, e.g., 720x576:
ffmpeg -i input_file.mp4

Re-processes the video and change the aspect with the setdar switch:
ffmpeg -fflags genpts -i input_file.mp4 -vf scale=720x576,setdar=2.21:1 output_file.mp4

Higher quality option:
ffmpeg -fflags genpts -i input_file.mp4 -c:v libx264 -b 1400k -preset slow -c:a copy -vf scale=720x576,setdar=2.21:1 output_file.mp4

Sometimes the pixel aspect ratio has to be changed as well because some players ignore the setdar:
ffmpeg -fflags genpts -i input_file.mp4 -crf 20 -vf scale=1280x576,setdar=2.21:1 output_file.mp4

Join two video files together

Create the mp4 files and integrate the audio as above. The command below combines three FFmpeg processes. Two ts streams are created as intermediary files and then concatenated.

ffmpeg -i mymovie_complete_01.mp4 -c copy -bsf:v h264_mp4toannexb -f mpegts intermediate1.ts; ffmpeg -i mymovie_complete_02.mp4 -c copy -bsf:v h264_mp4toannexb -f mpegts intermediate2.ts; ffmpeg -i "concat:intermediate1.ts|intermediate2.ts"  -c:v copy -c:a copy -bsf:a aac_adtstoasc mymovie_joined2.mp4

A simpler method using the concat protocol which copies the audio codec.

ffmpeg -i mymovie_part1.avi -c:a copy -qscale:v 1 intermediate1.mpg; ffmpeg -i mymovie_part2.avi -c:a copy -qscale:v 1 intermediate2.mpg; cat intermediate1.mpg intermediate2.mpg > intermediate_all.mpg; ffmpeg -i intermediate_all.mpg -qscale:v 2 -c:a copy mymovie_joined.avi

Concatenating using the concat demuxer.

This method copies the video and audio streams. Create a text file, for example, join_video_files_list.txt and in that file make a list of the video files to be joined:

file 'myvideo_part1.avi'
file 'myvideo_part2.avi'

From the command line:

ffmpeg -f concat -i join_video_files_list.txt -c copy joined_video_file.avi

Splice video with fade in and fade out

Splice a section of video from a movie and re-edit the spliced selection with audio and video fade in and fade out. This is a two step process, cut the file then perform the fades.

1) Extract the video, for example, starting from 27 minutes 50 seconds ending at 36 minutes:
ffmpeg -i mymovie.avi -ss 00:27:50.0 -to 00:36:00.0 -c:v copy -c:a copy mymovie_extracted_video.mp4
					
2) Extract the video from the spliced section adding a two second fade in and fade out from/to black*: ffmpeg -i mymovie_extracted_video.mp4 -an -filter:v 'fade=in:0:50,fade=out:st=488:d=2' -c:v libx264 mymovie_faded_in_out_video.mp4 *With the version of ffmpeg tested, I was unable to use purely seconds or frames as a time parameter. Only a combination of frames and seconds. Probably a fault with the customised compilation. 3) Extract the audio, using the FDK non free AAC Codec, from the spliced section adding a two second fade in/fade out: ffmpeg -i mymovie_extracted_video.mp4 -vn -af 'afade=t=in:ss=0:d=2,afade=t=out:st=488:d=2' -c:a libfdk_aac -map 0:1 -b:a 192k mymovie_faded_in_out_audio.m4a A codec has to be used with the -af switch. 4) Recombine the video and audio in an mkv container: ffmpeg -i mymovie_faded_in_out_audio.m4a -i mymovie_faded_in_out_video.mp4 -c:v copy -c:a copy -metadata title='mymovie trailer' mymovie_with_fades.mkv

FFmpeg Convert Video Files to MKV Python Utility

A utility semi-automating the conversion of video files to mkv has been written in Python 2.7 and Python 3. A choice of preset for conversion to H.264 and AAC is available as well as including .srt subtitle files.

FFmpeg Documentation

The official FFmpeg documentation includes 'Command Line Tools Documentation', 'Components', 'Libraries' and 'General Documentation'.

Documentation for FFmpeg Filters.

FFmpeg x264 Encoding Guide.

FFmpeg Audio Channel Manipulation.

License

This document is free to use and distribute under the GNU Free Documentation License.

Gary Hollands - October 2013.