FFmpeg can be used to encode videos into difference formats. It can re-encode videos and join, merge or split videos at ones will. FFmpeg is a powerful tool compatible with most major Operating Systems (Linux, Mac, Windows). FFmpeg has a lot of options/parameters and sometimes these can get quite convoluted, so we will go through the most common video tasks explaining in detail the options/parameters to be passed.

Before going ahead, if you haven’t already installed FFmpeg, you can download and install it from here.


Some Basics concepts about a Video –

  • Codec: A codec is nothing but a way/method of encoding or decoding a video. Encoding is the process where the video data is compressed/encrypted for transmission or storage. Decoding is a process that reverses the encoding process for playback. The codec to be used is decided depending on factors like target file-size and target quality. Currently, h265 and vp9 are popular video codecs with great support.
  • Container: A container, (as the word suggests) is something that contains the components of a video together. These components would be the video itself, the audio track(or even multiple audio tracks), the subtitles if any, meta-data and so on. The container is represented by a file extension. Examples of some popular containers are OGG (.ogg), AVI (.avi), MPEG (.mpeg), Matroska (.mkv).

Encode Videos
Now that you have an idea of the basics of a Video file, lets go ahead and learn how we could encode video into a different format.


1. Encoding a Video from 1 format to another:

Copy Encoding/ Stream copy –

Lets say you wish to encode an avi into an mp4 file.

ffmpeg -i inputFile.avi -c copy outputFile.mp4
/**
 * -i => Input file
 * -c => codec
 */

Here, we passed the -c copy option which causes the original audio + video streams (with their codecs) to simply be copied. i.e. No real encoding takes place. (which is why this type of encoding will be very fast!) The only thing that changes is the container. The filesize of the output video remains the same as that of the input.

Note:

To just see a small preview of how the output will look, you could pass a -t 30 option, which means that only the first 30 seconds of the input video will be encoded. If you wish to specify a starting point for the preview, you can pass a -ss 10 option which will generate a clip beginning from the 10th second.

ffmpeg -i inputFile.avi -c copy -t 30 outputFile.mp4
ffmpeg -i inputFile.avi -c copy -ss 10 -t 30 outputFile.mp4
/**
 * -i => Input file
 * -c => codec
 * -t => time duration in seconds
 * -ss => start time in seconds or HH:MM:SS
 */

Lossy Encoding –

Lets take the same example as above, i.e. we wish to encode an avi file into an mp4 file.

ffmpeg -i inputFile.avi outputFile.mp4
/**
 * -i => Input file
 */

Executing this will immediately start the process of encoding that will take a certain amount of time depending on your computers processing power. The output will be a video file in the mp4 format. Just by changing the file extensions as needed, the same command can be used to convert a video from any format to any other format.

Since we did not specify any options when executing the command, the default options are used. The encoding process compresses the original video data and this results in a lossy encoding. Visually the quality of this lossy encoding might not be evident but sometimes the obtained result may not be what you wanted in terms of quality or file-size.
Lets see ahead how we could have finer control over the file-size/video quality.

Adjusting the Bitrate:

Bit rate is the amount of information stored for each second of media that is played. The higher the bit rate, the less compression, resulting in a overall higher quality but at the cost of a larger file size. Bitrate is usually expressed in kbps or mbps.

// results in a video with a small file-size and of lower quality
ffmpeg -i inputFile.avi -b:v 1500k -b:a 128k outputFile.mp4
/**
 * -i => Input file
 * -b:v => Bitrate of the Video codec. [in kbps(k) or mbps(m)]
 * -b:a => Bitrate of the Audio codec. [in kbps(k)]
 */

// results in a video with a larger file-size but of higher quality
ffmpeg -i inputFile.avi -b:v 7500k -b:a 320k outputFile.mp4
/**
 * -i => Input file
 * -b:v => Bitrate of the Video codec. [in kbps(k) or mbps(m)]
 * -b:a => Bitrate of the Audio codec. [in kbps(k)]
 */

Manually selecting the Codec

You can also decide which audio/video codec you want to use. Choice of the codec depends on what the end result should be.
h265, vp9 are 2 popular and widely supported video codecs while aac and mp3 are 2 famous and fully supported audio codecs.

// use libx265 video and aac audio codec
ffmpeg -i inputFile.avi -c:v libx265 -c:a aac outputFile.mp4
ffmpeg -i inputFile.avi -c:v libx265 -c:a aac -b:v 7000k -b:a 320k outputFile.mp4      // with higher bitrates

// use vp9 video and mp3 audio codec
ffmpeg -i inputFile.avi -c:v vp9 -c:a libmp3lame outputFile.mp4
ffmpeg -i inputFile.avi -c:v vp9 -c:a libmp3lame -b:v 7000k -b:a 320k outputFile.mp4    // with higher bitrates

/**
 * -i => Input file
 * -c:v => Video codec. You can also use the option -vcodec instead
 * -c:a => Audio codec. You can also use the option -acodec instead
 * -b:v => Bitrate of the Video codec. [in kbps(k) or mbps(m)]
 * -b:a => Bitrate of the Audio codec. [in kbps(k)]
 */

Alternatively, with h264/h265 encoding, there is an option -crf which can be changed to improve the visual quality of the video.
The lower the value, the better the visual quality.

ffmpeg -i inputFile.avi -c:v libx264 -c:a aac -crf 20 outputFile.mp4
/**
 * -i => Input file
 * -c:v => Video codec. You can also use the option -vcodec instead
 * -c:a => Audio codec. You can also use the option -acodec instead
 * -crf => Constant Rate Factor (lower value gives better quality)
 */

Lossless Encoding –

The commands for Lossless encoding vary depending upon the codecs used. For example, for h264/h265 encoding, you can set the crf option to 0 to get a lossless encoding. And for Vp9, you can set the lossless option to 1.

ffmpeg -i inputFile.mkv -c:v libx264 -preset ultrafast -crf 0 outputFile.mkv
ffmpeg -i inputFile.mkv -c:v libx265 -crf 0 outputFile.mkv

// For lossless VP9 encoding, 
ffmpeg -i input.mp4 -c:v vp9 -lossless 1 output.webm

/**
 * -i => Input file
 * -c:v => Video codec. You can also use the option -vcodec instead
 * -preset => Encoding speed to compression ratio. ultrafast/superfast/veryfast/faster/fast/medium/slow/slower/veryslow (defaults to medium)
 * -crf => Constant Rate Factor (lower value gives better quality, use 0 for lossless)
 */

2. Resize video resolution

With FFmpeg, you can easily resize/scale your video’s resolution to either a fixed dimensions or you can resize proportionally. To resize proportionally, provide only 1 of the dimension you wish to use (height/width) and set the other to -1.

// resize to a fixed dimension/resolution
ffmpeg -i inputFile.avi -c:v vp8 -vf scale=640:360 -c:a libvorbis outputFile.mkv
// resize proportionally
ffmpeg -i inputFile.VOB -c:v libx265 -c:a aac -vf scale=1080:-1 outputFile.mkv
ffmpeg -i inputFile.VOB -c:v libx265 -c:a aac -vf scale=-1:1080 outputFile.mkv

/**
 * -i => Input file
 * -c:v => Video codec. You can also use the option -vcodec instead
 * -c:a => Audio codec. You can also use the option -acodec instead
 * -vf => filter
 */

3. Join or merge 2 or more videos

To merge several videos together, use the following command:

ffmpeg -i "concat:file1.mpg|file2.mpg|file3.mpg" output.avi
ffmpeg -i "concat:file1.mpg|file2.mpg|file3.mpg" -c copy output.mpg

Note: Sometimes, this might not work as expected with certain formats (like MP4 files) when the files to be joined have been encoded differently or have a different resolution. In this case, you will be required to convert each MP4 file into an intermediate format and then thereafter join those intermediate files together.

// convert each file
ffmpeg -i file1.mp4 -c copy -bsf:v h264_mp4toannexb temp1.ts
ffmpeg -i file2.mp4 -c copy -bsf:v h264_mp4toannexb temp2.ts
// Then join the intermediate files
ffmpeg -i "concat:temp1.ts|temp2.ts" -c copy -bsf:a aac_adtstoasc output.mp4

/**
 * -i => Input file
 * -c => codecs (audio+video)
 * -bsf:v => Bitstream filter for video
 * -bsf:a => Bitstream filter for audio
 */

4. Split a video into multiple parts

You can split a video by using the -ss and -to options which accept the start time and the end time respectively. Using this you can split your video into as many parts as you’d like.

// create a clip of ~2 minutes beginning from the 10th minute to the 12th minute
ffmpeg -i inputVideo.mp4 -ss 00:10:00 -to 00:12:00 outputClip.mp4
/**
 * -i => Input file
 * -c => encoding (audio + video)
 * -ss => start time
 * -to => end time
 */

5. Extract Audio from a Video

You can easily extract the audio from a video by using the vn option which tells FFmpeg to skip processing the video.

ffmpeg -i input.avi -vn output.mp3

// Using custom audio sampling frequency/audio channels/audio-bitrate, 
ffmpeg -i input.avi -vn -ar 44100 -ac 2 -b:a 192k output.aac 

// extracting audio from the 5th second to the 10th second
ffmpeg -i input_input.avi -ss 5 -to 10 -vn output.mp3

/**
 * -i => Input file
 * -vn => skip the video stream
 * -ar => Audio Sampling Frequency
 * -ac => Number of Audio Channels (2 => Stereo)
 * -b:a => bit-rate for the audio stream (in kbps/mbps)
 * -ss => start time
 * -to => end time
 */

You can also extract the original audio in a lossless way by only copying the original encoded audio. Since no real encoding takes place, this process will be super-fast.

// Get the information about video
// (This reveals the audio codec used) 
ffmpeg -i input.avi
// If the audio codec is mp3,
ffmpeg -i input.avi -c:a copy output.mp3
// If the audio codec is aac,
ffmpeg -i input.flv -c:a copy output.aac
 
/**
 * -i => Input file
 * -c:a => Audio codec to use
 */

6. Add a sound track to a Video

Here, there are 2 possibilities according to what the end result is expected.

A. Replace the original Audio

You can overwrite the original audio with a new audio as shown below. By default, the duration of the output video will be that of the longer input file. That means that if the audio is longer than the video, the video will freeze when it reaches its end whereas the sound will continue, and vice-versa.

To avoid that, you could use either use the -shortest option which truncates the output to the same duration as the shortest input or use the -t 300 option which will truncate the output at the 300th second.

ffmpeg -i inputAudio.mp3 -i inputVideo.avi outputVideo.avi
ffmpeg -i inputAudio.mp3 -i inputVideo.avi -shortest outputVideo.avi
ffmpeg -i inputAudio.mp3 -i inputVideo.avi -t 300 outputVideo.avi
/**
 * -i => Input file
 * -shortest => Makes output to be the same duration as the shortest input
 * -t => time in seconds
 */

B. Add a new Audio track

If you wish to conserve the original audio, and only add a new audio track, it can be done by mapping the audio streams.

ffmpeg -i input_video_with_audio.avi -i new_audio.ac3 -map 0 -map 1 -c copy outputVideo.avi
/**
 * -i => Input file
 * -c => Codec (both audio + video)
 * -map => maps the input files
 */

Here, -map 0 copies (includes) all streams(audio + video) from the first input file (input_video_with_audio.avi) and -map 1 includes all streams (in this case, one i.e. audio) from the second input file (new_audio.ac3).

7. Convert Audio from one format to another

Audio can be re-encoded from from its original format to another one by using the vn flag which ignores the video stream if any. Encoding happens simply by using the desired format’s file extension.

ffmpeg -i input.wav -vn output.mp3
ffmpeg -i input.mp4 -vn output.ogg
ffmpeg -i input.flv -vn output.mp3
ffmpeg -i input.flac -vn -ar 44100 -ac 2 -b:a 192k output.aac
/**
 * -i => Input file
 * -vn => skip the video stream
 * -ar => Audio Sampling Frequency
 * -ac => Number of Audio Channels (2 => Stereo)
 * -b:a => bit-rate for the audio stream (in kbps/mbps)
 */

8. Convert Video to Images and Vice-versa

You can generate images from a video in the following formats:
PGM, PPM, PAM, PGMYUV, JPEG, GIF, PNG, TIFF, SGI.
The number of images generated depends on the Framerate of the video. 1 image per frame is generated.
The following command will generate images named image1.jpg, image2.jpg, …

ffmpeg -i input.mpg image%d.jpg
/**
 * -i => Input file
 * %d => Regular expression to denote digits
 */

Similarly, you can convert a bunch of images into a video.

ffmpeg -i image%d.jpg output.avi
/**
 * -i => Input file
 * %d => Regular expression to denote digits
 */

Some more interesting info can be found in the references, feel free to go through them.
Hope it helps! 🙂


References:

The post Encode Videos with ffmpeg cheatsheet appeared first on Digital Fortress.