Best FFmpeg Advanced Commands For Video, Audio and Images Encoding

Best FFmpeg Advanced Commands For Video, Audio and Images Encoding
Photo by Jakob Owens / Unsplash

Why FFmpeg worth to learn

FFmpeg is ... well, there's no sense in a classical introduction. This is the Swiss knife for multimedia. Big, solid and popular project without real competitors, also used in many applications. Of course, a lot of applications available to work with multimedia, from free to super costly giants made by Abobe & Sony. Let's highlight the reasons why you need FFmpeg:

  • Easy automation: find the best command for your needs and repeat it.
  • Open Source: easy to modify
  • Simple scaling: Docker containers, Linux, Windows, macOS and even ARM devices like Raspberry Pi are supported.
  • A LOT of supported formats.
  • Easy to use: fast switching from base use cases to advanced.
  • Great community with devs and users.
  • A lot of ready solutions on internet.
  • Solid documentation.
  • And many more!

Video

  • Convert video for a website:
$ ffmpeg -i video_in.mkv -c:v libx264 -c:a libfdk_aac video_out.mp4
$ ffmpeg -i video_in.mkv -c:v libx264 -profile:v high -c:a libfdk_aac video_out.mp4

The video_out.mp4 file should be played in any modern browser without issues. The second command use "high" preset for better video quality. c:v is the shortcut for codec:video, same about c:a for audio. Using modern video codecs like VP9 and AV1 also possible:

$ ffmpeg -i video_in.mp4 -c:v libvpx-vp9 -c:a libopus video_out.webm
$ ffmpeg -i input.mp4 -c:v libaom-av1 -movflags +faststart -c:a libfdk_aac video_out.mp4
  • Create a thumbnail image:
$ ffmpeg -i video_in.mp4 -ss 00:00:10 -vframes 1 thumbnail.png
// extract 1 frame from 00:10 (10th second) position
  • Trim/cut a video
// cut first 10 minutes
$ ffmpeg -i video_in.mp4 -ss 00:00:00 -to 00:10:00 -c copy video_out.mp4
// `-c copy` prevents video from re-encoding;
// also re-packaging video with `-c copy` often fixes bugs in original container
  • Record a screencast with x264 ultrafast profile
$ ffmpeg -s 1920x1080 -framerate 30 -f x11grab -i :0.0 -c:v libx264rgb -crf 0 -preset ultrafast -color_range 2 sceencast.mkv

CRF(Constant Rate Factor) designed to control video quality, default is 18, highest is 51. Except ultrafast x264 supports another profiles: superfast, faster, fast, medium, slow, slower, veryslow.

  • Add a second video from webcam:
$ ffmpeg -i /dev/video0 -i /dev/video1 -filter_complex "[1]scale=-1:1080[right];[0][right]hstack,format=yuv420p" -f v4l2 /dev/video2

The v4l2loopback kernel module required; webcam video will be moved 1080 pixels left.

  • ffplay - small built-in video player

Yeah, FFmpeg comes with a minimalistic player, ffplay. Type ffplay /path/to/video.mp4 in command line to open a media file; player supports rewind with arrow keys and full screen with F shortcut.

  • ffprobe - get info about media file:
$ ffprobe -v quiet -print_format xml -show_format -show_streams video_in.mp4 > file.xml
  • Convert video to .gif image:
$ ffmpeg -ss 30.0 -t 2.5 -i video_in.mp4 -filter_complex "[0:v] palettegen" palette.png
$ ffmpeg -ss 30.0 -t 2.5 -i video_in.mp4 -i palette.png -filter_complex "[0:v][1:v] paletteuse" video.gif

The option -ss 30.0 -t 2.5 means we're taking 2.5s video since 30s after start(30...32.5), palettegen filter will create 256 colors palette first, [0:v] - pick first video stream, [0:v][1:v] - pick video stream as first stream and palette as second.

  • Extract video and audio:
$ ffmpeg - video_in.mp4 -map 0:0 -c copy video_only.mp4 -map 0:1 -c copy audio0.mp3 -map 0:2 -c copy audio1.mp3

-map 0:0 - pick the first (0) stream - video, -map 0:1 - second stream, the first audio track.

  • Join/concatenate several videos:
$ echo file 'video1.mp4' >> medialist &&  echo file 'video2.mp4' >> medialist
$ ffmpeg -safe 0 -f concat -i medialist.txt -c copy video_out.mp4
  • Join/concatenate video and audio:
$ ffmpeg -i video_in.mp4 -i audio_in.mp3 -c copy video_out.mp4
  • Convert 10-bit x265 video to 10-bit x264:
$ ffmpeg -i video_in.mp4 -c:v libx264 -crf 25 -c:a copy video_out.mkv
  • Convert 10-bit x265 video to 8-bit x264:
$ ffmpeg -i video_in.mp4 -c:v libx265 -vf format=yuv420p -c:a copy video_out.mkv
  • Convert 10-bit x265 to 8-bit x264:
$ ffmpeg -i video_in.mpv -c:v libx264 -crf 18 -vf format=yuv420p -c:a copy video_out.mkv
  • Video rotation:
$ ffmpeg -i input -c:v libx264  -vf "transpose=1" -c:a copy output.mkv

The transpose=1 option rotates video 90 degrees clockwise, 0 - 90 degrees counterclockwise, 2 - 180 counterclockwise, 3 - 180 clockwise.

  • Edit video metadata: -metadata:s:v title="Video Title"

  • Edit media file metadata: -metadata title="Movie 49" -metadata description="In 2049..." -metadata comment="Have Fun!"

  • Saving RTSP stream to file

$ ffmpeg -i rtps://192.168.0.100/video -c copy video_out.mp4
  • Fast seek for long videos:
$ ffmpeg -ss 05:00:00 -noaccurate_seek -to 06:00:00 -i video_in.mp4 -c copy video_out.mp4
// cut 5h...6h from video
  • Downgrade fps: from 60 to 30
$ ffmpeg -i video_in.mp4 -r 30 video_out.mp4

  • Save all video keyframes to images:
$ ffmpeg -i video_in.mp4 -vf "select=eq(pict_type\,I)" -vsync vfr frame-%06d.png
  • Create video from images:
$ ffmpeg -r 30 -i ./%06d.jpg -c:v libx264 video_out.mp4
  • Crop and concatenate three videos vertically
$ ffmpeg -i video1.mp4 -i video2.mp4 -i video3.mp4 -filter_complex "[0:v]crop=1296:432:0:200[c0];[1:v]crop=1296:432:0:200[c1];[2:v]crop=1296:432:0:230[c2];[c0][c1][c2]vstack=inputs=3[out]" -map "[out]" video_out.mp4
  • Crop and concatenate four videos into 2x2 mosaic video
$ ffmpeg -i video1.mp4 -i video2.mp4 -i video3.mp4 -i video4.mp4 -filter_complex "[0:v][1:v]hstack=inputs=2[row1];[2:v][3:v]hstack=inputs=2[row2];[row1][row2]vstack=inputs=2[out]" -map "[out]" video_out.mp4
  • Delay video
$ ffmpeg -i video_in.mp4 -itsoffset TIMEinSec -i video_in.mp4 -map 0:v -map 1:a -c copy video_out.mp4
$ ffmpeg -i video_in.mp4 -itsoffset  -i video_in.mp4 -map 1:v -map 0:a -c copy video_out.mp4
  • Download playlist to single video file:
ffmpeg -i "https://server.com/playlist.m3u8" -c copy video_out.mp4

Audio

  • Extract audio from video: $ ffmpeg -i video_in.mp4 audio_out.wav

  • Convert FLAC to MP3:

$ ffmpeg -i audio_in.flac -ab 320k audio_out.mp3
  • Convert FLAC to Opus:
$ ffmpeg -i audio_in.flac -c:a libopus -b:a 256k -vbr on audio_out.opus
  • Convert FLAC to AAC:
$ ffmpeg -i audio_in.flac -c:a libfdk_aac -vbr 3 output.m4a".
  • Delay audio
$ ffmpeg -i video_in.mp4 -itsoffset TIMEinSec -i video_in.mp4 -map 0:v -map 1:a -c copy video_out.mp4
  • Down mix 7.1 audio to stereo
$ ffmpeg -i audio_in.aac  -c:a libfdk_aac -b:a 160k -ac 2 audio_out.aac
  • Edit track metadata:
    -metadata:s:a title="xx"
$ ffmpeg -i audio_in.mp3 -c copy -metadata:s:a title="Track N9" audio_out.mp3
  • Audiobooks

The best modern codec for audiobooks is Opus, works perfect on 32kbps.
Convert MP3 audiobook to Opus:

$ ffmpeg -i audio_in.wav -c:a libopus -b:a 32k -vbr on -application voip audio_out.opus

For old devices without Opus support, HE-AAC-v2 is the best choice:

$ ffmpeg -i input.wav -c:a libfdk_aac -profile:a aac_he_v2 -b:a 32k audio_out.m4a

Images

FFmpeg supports basic image formats; for example, let's convert PNG to JPEG:

$ ffmpeg -i image.png image.jpeg

AVIF and JPEG XL covered in Part 2.

Batch mode

  • Print frame rate of every file
$ for v in \*.mp4
    do echo $v; ffprobe -v error -select_streams v -of default=noprint_wrappers=1:nokey=1 -show_entries stream=r_frame_rate "$v"
  done
  • Print selected info of every file in directory in CSV format
$ for f in \*.mp4
    do echo -n $f,; ffprobe -v quiet -show_streams $f
  done

Read more