FFmpeg for video encoding

A couple of weeks ago I needed to trim an MP4 file. I didn’t necessarily want to re-encode besides I was on a machine without a media encoding application. I thought I’d try out FFmpeg which is a command line video and audio transcoder.

To install FFmpeg I used Brew, the OS X Package Manager (Windows users can investigate Chocolatey):

$ brew install ffmpeg

It takes a while but once it’s installed we can start trimming or transcoding video and audio. 

I have a file on my Desktop folder and used

$ cd ~/Desktop

to navigate to it in Terminal. I’m just going to leave my inputs and outputs here for demonstration. In a real world situation I’d hope that I would be a little more organised (stress on the hope).

To change the format of the video to, say a WMV (presumably to send to someone in 2010), it’s just:

$ ffmpeg -i "input-vid.mp4" "output-vid.wmv"

(The inverted commas are optional but do a better job at breaking up the syntax.)

Now we have WMV transcoding on a Mac for free.

The -i option denotes that the next value is the input file name (and path if we were in a different directory) and after that comes the output file. Note that all I’ve supplied is a file extension and FFmpeg has used that as the basis for the file type it will transcode to.

Audio

If we wanted to just take the audio and convert it to an MP3 then it’s

$ ffmpeg -i "input-vid.mp4 "output-audio.mp3"

Copy

The file we are using is an MP4 H.264 and we can convert this to a .avi which is just a container format without encoding again using -c copy:

$ ffmpeg -i "input-vid.mp4" -c copy "output-vid.avi"

Same goes for Quicktime .mov files which are also just containers:

$ ffmpeg -i "input-vid.mp4" -c copy "output-vid.mov"

Resizing

To resize video just use the -s option followed by the required dimensions:

$ ffmpeg -i "input-vid.mp4" -t 00:00:30 -s 640x360  "cut-vid.mp4"

Changing Bitrates

To alter the video bitrate just use -a:v [bitrate amount]

$ ffmpeg -i "input-vid.mp4" -b:v 500k "output-vid.mp4"

Here the output file will have an Average Bit Rate (ABR) of 500kb

A Constant Bit Rate (CBR) can be set by explicitly stating the same maximum and minimum bit rate:

$ ffmpeg -i "input-vid.mp4" -b:v 500k -minrate 4000k -maxrate 4000k "cut-vid.mp4"

Audio bit rates are set the same:

$ ffmpeg -i "input-vid.mp4" -b:a 500k "cut-vid.mp4"

Trimming video

To trim the video extracting just a section from 10 seconds in to 30:

$ ffmpeg -i "input-vid.mp4" -ss 00:00:10 -to 00:00:30 -c copy "cut-vid.mp4"

The first part of this -ss is the seek command which will start the video at 10 seconds (HH:MM:SS:xxx(milliseconds)). The -to command should be pretty self- explanatory.

Need just the first 30 seconds?

$ ffmpeg -i "input-vid.mp4" -t 00:00:30 -c copy "cut-vid.mp4"

The -t command is the duration.

Problems can arise when we don’t land on an I-frame. In short, file formats like MPEG-4 use a compression algorithm which means that only certain frames are ‘real frames’ (I-frames) while the rest are based on the previous I-Frame, a guess of what the next one will look like or a combination of both. Not landing on an I-frame can resul in a stalled image or no image at all. In order to ensure accurate video and audio syncing we may need to re-encode by just omitting the -c copy:

$ ffmpeg -i "input-vid.mp4" -t 00:00:30 "cut-vid.mp4"

However if we want to re-encode the video but just copy the audio we can use:

$ ffmpeg -i "input-vid.mp4" -c:a copy "cut-vid.mp4"

More complex scenarios like multiple audio and subtitle streams can use the -map option.

Screengrabs

If we wanted to create a JPEG screen grab from the tenth second:

$ ffmpeg -i "input-vid.mp4" -ss 00:00:10  -frames:v 1 "grab-1.jpg"

Specifying codecs

Since formats like .mov are just containers we can specify the codec we want to use as well as the library that will do the encoding. Each have different options that are available here.

To see that encoders that are available:

$ ffmpeg -encoders

This lists all available encoders:

Downloads_—_bash_—_80×23To encode as Windows Media 7 use the name after -c:v:

$ ffmpeg -i "big_buck_bunny_480p_surround-fix.avi" -c:v wmv1 "output-video.wmv"

If you don’t like working in lossy formats we can even encode to Apple’s ProRes format.

HTML5 fast start

When encoding HTML5 video it’s advisable to have the file’s header information at the start of the file to aid progressive download. This ensures that since all data about the file is contained at the start it starts playing quickly.

This is achieved with the moov atom. For an MP4 encoded using the libx264 library:

$ ffmpeg -i "input-file.mp4" -c v:libx264 -movflags faststart -c v:lib264  "output-file.mp4"

FFmpeg is a quick and relatively easy way to encode video an worth an install. You can also check out the repo on GitHub here.

Leave a Reply

Your email address will not be published. Required fields are marked *