Optimizing Video with FFmpeg: A Comprehensive Introduction
FFmpeg is an efficient cross-platform tool capable of recording,
converting, editing and streaming digital audio and video in various formats. Although it can perform most multimedia
tasks quickly and easily, it is a command-line tool, making it challenging and verbose to use. In this guide, we will
demonstrate how to perform some typical operations to produce videos for web and social media.
To easily resize and edit your videos online for web and social media, you can use Abraia Studio.
For testing, we will use the Big Buck Bunny trailer, which you can download in FullHD video format from this
Converting video for the web
The first step in producing a video for the web is to encode it in the appropriate format. The most widely supported
format for the web is MP4 encoded with H264. This codec generates small files with excellent quality and works on web
browsers, phones, tablets, and TVs.
To encode a video as MP4 with H264, use the following command:
ffmpeg -i trailer_1080p.mov video.mp4
By default, FFmpeg uses the file extension to select the encoding. For example, a .mp4 file is encoded in H264. Typically,
FFmpeg has a good selection of parameters by default, so we don't need to know anything about video encoding. A full
specification of video encoding parameters is as follows:
ffmpeg -i trailer_1800p.mov -c:v libx264 -crf 21 -preset veryfast -profile:v high -level 4.0 -color_primaries 1 -color_trc 1 -colorspace 1 -movflags +faststart -c:a aac -b:a 128k video.mp4
The only important parameter to consider from the above command is
-movflags +faststart, which enables
quick start playing on web browsers.
Resizing video for social media
A typical operation required before publishing is resizing a video for a platform or device. To resize a video with FFmpeg
we just need to specify the new size (width and height) using the "scale" filter. When we specify the height as -2 this will
be calculated to preserve the current aspect ratio.
ffmpeg -i trailer_1080p.mov -vf "scale=1280:-2" video.mp4
However, if we need to change the aspect ratio of the video, simply resizing it may not yield good results. In such
cases, we can either pad the video with a flat color or crop it.
For instance, to pad a video to an aspect ratio of 1:1 for sharing on Instagram, we can use the following
ffmpeg -i trailer_1080p.mov -vf "scale=720:720:force_original_aspect_ratio=decrease,pad=720:720:(ow-iw)/2:(oh-ih)/2:black" video.mp4
In the above command, we are scaling the video down to 720x720 and using the "force_original_aspect_ratio" option to
maintain the original aspect ratio while scaling. We are then padding the video with a black color to make it square.
Or, to crop a video to an aspect ratio of 1:1, we can use the following command:
ffmpeg -i trailer_1080p.mov -vf "crop='min(iw,1*ih)':'min(iw/1,ih)',scale=720:720" video.mp4
In this command, we are cropping the video to a square aspect ratio of 1:1 by specifying the minimum of the input width
and height for both the width and height of the crop, and then scaling the cropped video to 720x720.
Other resize option is to add a blurred background to the video. For this example, we need to use the "filter_complex"
option to merge two video streams: one for the background and one for the foreground.
First, we take the video input with
[0:v] and we apply a blur filter to produce the background
Second, we take again the video input with
[0:v] and we resize the video to create the foreground
Third, we take the background
[bg] and overlay the
[fg] to build the final video stream
Fourth, we take the audio input with
[0:a] and we create a final audio stream without effects
Finally, we map both outputs for video
[outv] and audio
[outa] to get the final result.
The following command shows how to do this:
ffmpeg -i trailer_1080p.mov -filter_complex "[0:v]scale=720:720,boxblur=luma_radius=min(h\,w)/20:luma_power=1:chroma_radius=min(cw\,ch)/20:chroma_power=1[bg];[0:v]scale=720:720:force_original_aspect_ratio=decrease[fg];[bg][fg]overlay=(W-w)/2:(H-h)/2[outv]" -map [outv] -map 0:a? video.mp4
We can even add a logo, we just need a PNG image with our logo or message in a transparent background an run a
command as bellow:
ffmpeg -i video_clip.mp4 -i logo.png -filter_complex "overlay=(main_w-overlay_w)/2:(main_h-overlay_h)/2" video.mp4
Trimming a video short clip
Lots of time we need to select a clip from a video. Trimming an video with FFmpeg is a little tedious
because we need to use some video player to look for the starting and stopping times of the clip that
we want to cut.
ffmpeg -i trailer_1080p.mov -ss 13.2 -to 16 video_clip.mp4
You can also use the time duration to specify the video cut end.
ffmpeg -i trailer_1080p.mov -ss 13.2 -t 2.8 video_clip.mp4
Create a video frame poster
Other common task is to create a poster from a video frame. This can be easily made
with just to know the timing of such frame.
ffmpeg -i video.mp4 -ss 14.5 -vframes 1 -q:v 2 poster.jpg
Convert a video to GIF
Finally, a useful option to include our videos in, for instance, mail marketing campaigns is to convert it
to an animated GIF. This can be directly done with one command, but the result with FFmpeg is very disappointing.
ffmpeg -i video_clip.mp4 -vf "fps=10,scale=320:-2:flags=lanczos" video_clip.gif
The problem rises because the GIF format only supports 256 colors. This demands to generate a custom color palette
first to improve the results.
ffmpeg -i video_clip.mp4 -vf "fps=10,scale=320:-2:flags=lanczos,palettegen" palette.png
Created the color palette (
the most representative 256 colors for our animation, we can already generate the GIF animation.
ffmpeg -i video_clip.mp4 -i palette.png -filter_complex "fps=10,scale=320:-2:lanczos[video];[video][1:v]paletteuse" video_clip-palette.gif