Skip to content

Instantly share code, notes, and snippets.

@dexeonify
Last active May 30, 2024 07:39
Show Gist options
  • Save dexeonify/ed31c7d85fcf7297719e2ec4740fafda to your computer and use it in GitHub Desktop.
Save dexeonify/ed31c7d85fcf7297719e2ec4740fafda to your computer and use it in GitHub Desktop.
Some basic and frequently-used FFmpeg command lines compiled into one long gist.

FFmpeg Cheat Sheet

Table of Contents

Expand

Video Encoding

DNxHR

ffmpeg -i input.mp4 -c:v dnxhd -profile:v dnxhr_hq output.mxf

The -profile:v output option is required to select the DNxHR profile, such as -profile:v dnxhr_hq. Accepted values for -profile:v are: dnxhd, dnxhr_444, dnxhr_hqx, dnxhr_hq, dnxhr_sq, dnxhr_lb.

  • DNxHR LB: dnxhr_lb - Low Bandwidth. 8-bit 4:2:2 (yuv422p). Offline Quality.
  • DNxHR SQ: dnxhr_sq - Standard Quality. 8-bit 4:2:2 (yuv422p). Suitable for delivery format.
  • DNxHR HQ: dnxhr_hq - High Quality. 8-bit 4:2:2 (yuv422p).
  • DNxHR HQX: dnxhr_hqx - High Quality. 10-bit 4:2:2 (yuv422p10le). UHD/4K Broadcast-quality delivery.
  • DNxHR 444: dnxhr_444 - Finishing Quality. 10-bit 4:4:4 (yuv444p10le). Cinema-quality delivery.

Source

ProRes

ffmpeg -i input.mp4 -c:v prores_ks -profile:v 2 output.mov

The -profile switch takes an integer from -1 to 5 to match the ProRes profiles:

  • -1: auto (default)
  • 0: proxy ≈ 45Mbps YUV 4:2:2
  • 1: lt ≈ 102Mbps YUV 4:2:2
  • 2: standard ≈ 147Mbps YUV 4:2:2
  • 3: hq ≈ 220Mbps YUV 4:2:2
  • 4: 4444 ≈ 330Mbps YUVA 4:4:4:4
  • 5: 4444xq ≈ 500Mbps YUVA 4:4:4:4

About Apple ProRes

Source

CineForm

ffmpeg -i input.mp4 -c:v cfhd -quality 8 output.mov

The -quality options accepts the following values:

-quality           <int>    set quality (from 0 to 12) (default film3+)
   film3+          0
   film3           1
   film2+          2
   film2           3
   film1.5         4
   film1+          5
   film1           6
   high+           7
   high            8
   medium+         9
   medium          10
   low+            11
   low             12

H.264/AVC

ffmpeg -i input.mov -pix_fmt yuv420p -c:v libx264 -c:a copy -crf 22 -preset veryslow output.mp4
  1. Choose a CRF value

    • The range of the CRF scale is 0–51, where 0 is lossless, 23 is the default and 51 is worst quality possible.
    • A lower value generally leads to higher quality, and a subjectively sane range is 17–28.
    • The range is exponential, so increasing the CRF value +6 results in roughly half the bitrate/file size, while -6 leads to roughly twice the bitrate.
    • Choose the highest CRF value that still provides an acceptable quality. If the output looks good, then try a higher value. If it looks bad, choose a lower value.
  2. Choose a preset

    • A preset is a collection of options that will provide a certain encoding speed to compression ratio. A slower preset will provide better compression (compression is quality per filesize).
    • Use the slowest preset that you have patience for. The available presets in descending order of speed are:
      • ultrafast
      • superfast
      • veryfast
      • faster
      • fast
      • medium – default preset
      • slow
      • slower
      • veryslow
      • placebo – ignore this as it is not useful (see FAQ)

FFmpeg Wiki: H.264 Video Encoding Guide

H.265/HEVC

ffmpeg -i input.mp4 -pix_fmt yuv420p10le -c:v libx265 -c:a copy -crf 26 -preset slow output.mov
  1. Choose a CRF

    CRF affects the quality. The default is 28, and it should visually correspond to libx264 video at CRF 23, but result in about half the file size. CRF works just like in x264, so choose the highest value that provides an acceptable quality.

  2. Choose a preset

    The default is medium. The preset determines compression efficiency and therefore affects encoding speed. Valid presets are ultrafast, superfast, veryfast, faster, fast, medium, slow, slower, veryslow, and placebo. Use the slowest preset you have patience for. Ignore placebo as it provides insignificant returns for a significant increase in encoding time.

FFmpeg Wiki: H.265/HEVC Video Encoding Guide

VP9

ffmpeg -i input.mkv -c:v libvpx-vp9 -pass 1 -pix_fmt yuv420p10le -profile:v 2 -lag-in-frames 25 -crf 25 -b:v 0 -g 240 -cpu-used 4 -tile-rows 0 -tile-columns 1 -row-mt 1 -f null NUL
ffmpeg -i input.mkv -c:v libvpx-vp9 -pass 2 -pix_fmt yuv420p10le -profile:v 2 -lag-in-frames 25 -crf 25 -b:v 0 -g 240 -cpu-used 4 -tile-rows 0 -tile-columns 1 -row-mt 1 output.webm
  • Two-pass is the recommended encoding method for libvpx-vp9 as some quality-enhancing encoder features are only available in 2-pass mode.

  • For two-pass, you need to run ffmpeg twice, with almost the same settings, except for:

    • In pass 1 and 2, use the -pass 1 and -pass 2 options, respectively.
    • In pass 1, output to a null file descriptor, not an actual file. (This will generate a logfile that ffmpeg needs for the second pass.)
    • In pass 1, you can leave audio out by specifying -an.
  • Constant quality 2-pass is invoked by setting -b:v to zero and specifiying a quality level using the -crf switch:

    ffmpeg -i input.mp4 -c:v libvpx-vp9 -b:v 0 -crf 30 -pass 1 -an -f null NUL && ^
    ffmpeg -i input.mp4 -c:v libvpx-vp9 -b:v 0 -crf 30 -pass 2 -c:a libopus output.webm

FFmpeg Wiki: VP9 Encoding Guide

Tuning libvpx-vp9 to be more efficient - r/AV1

AV1

# libaom
ffmpeg -i input.mp4 -c:v libaom-av1 -pass 1 -pix_fmt yuv420p10le -cpu-used 6 -crf 20 -b:v 0 -g 300 -lag-in-frames 35 -f null NUL
ffmpeg -i input.mp4 -c:v libaom-av1 -pass 2 -pix_fmt yuv420p10le -cpu-used 6 -crf 20 -b:v 0 -g 300 -lag-in-frames 35 output.mkv

# rav1e
ffmpeg -i input.mp4 -c:v librav1e -pix_fmt yuv420p10le -speed 6 -qp 60 output.mkv

# SVT-AV1
ffmpeg -i input.mp4 -c:v libsvtav1 -pix_fmt yuv420p10le -preset 6 -rc 0 -qp 25 output.mkv

(This only applies to libaom) Same with libvpx-vp9, using 2-pass mode is recommended as it enables some fancy options, like better adaptive keyframe placement and better ARNR frame decisions, alongside better rate control.

Controlling Speed/Quality

-cpu-used sets how efficient the compression will be. Default is 1. Lower values mean slower encoding with better quality, and vice-versa. Valid values are from 0 to 8 inclusive. To enable fast decoding performance, also add tiles (i.e. -tiles 4x1 or -tiles 2x2 for 4 tiles).

Keyframe placement

By default, libaom's maximum keyframe interval is 9999 frames. This can lead to slow seeking, especially with content that has few or infrequent scene changes. The -g option can be used to set the maximum keyframe interval. Anything up to 10 seconds is considered reasonable for most content, so for 30 frames per second content one would use -g 300, for 60 fps content -g 600, etc.

FFmpeg Wiki: libaom AV1 Encoding Guide

Making aomenc-AV1/libaom-AV1 the best it can be in a sea of uncertainty - r/AV1

FFV1

ffmpeg -i input.mp4 -c:v ffv1 -coder 1 -context 1 -g 24 -slices 24 output.mkv

The relevant options used:

Name FFmpeg argument Valid values Comments
Coder -coder 0, 1, 2 0=Golomb-Rice, 1=Range Coder, 2=Range Coder (with custom state transition table)
Context -context 0, 1 0=small, 1=large
GOP size -g integer >= 1 For archival use, GOP-size should be "1"
Slices -slices 4, 6, 9, 12, 16, 24, 30 Each frame is split into this number of slices. This affects multithreading performance, as well as filesize: Increasing the number of slices might speed up performance, but also increases the filesize.

FFmpeg Wiki: FFV1 encoding cheatsheet

Video Filtering

Change Framerate

You may consider using fps filter. It won't change the video playback speed.

Example to reduce fps from 59.6 to 30:

ffmpeg -i input.mkv -vf fps=fps=30 output.mkv

Source

Trimming

Input Seeking

Cut from 00:01:00 to 00:03:00 (in the original), using the faster seek.

ffmpeg -ss 00:01:00 -i video.mp4 -t 00:02:00 -c copy cut.mp4

Cut from 00:01:00 to 00:02:00, as intended, using the faster seek.

ffmpeg -ss 00:01:00 -i video.mp4 -to 00:02:00 -c copy -copyts cut.mp4

Output Seeking

Cut from 00:01:00 to 00:02:00, as intended, using the slower seek.

ffmpeg -i video.mp4 -ss 00:01:00 -to 00:02:00 -c copy cut.mp4

To extract only a small segment in the middle of a movie, it can be used in combination with -t which specifies the duration, like -ss 60 -t 10 to capture from second 60 to 70. Or you can use the -to option to specify an out point, like -ss 60 -to 70 to capture from second 60 to 70. -t and -to are mutually exclusive. If you use both, -t will be used.

Note: If you specify -ss before -i only, the timestamps will be reset to zero, so -t and -to will have the same effect. If you want to keep the original timestamps, add the -copyts option.

Timecode Calculator

FFmpeg Wiki: Seeking

Time duration syntax

Cropping

ffmpeg -i in.mp4 -vf "crop=out_w:out_h:x:y" out.mp4

Where the options are as follows:

  • out_w is the width of the output rectangle
  • out_h is the height of the output rectangle
  • x and y specify the top left corner of the output rectangle
  • You can refer to the input image size with in_w and in_h as shown in this first example. The output width and height can also be used with out_w and out_h.

Preview Crop

You can take a crop and preview it live with ffplay:

ffplay -i in.mp4 -vf "crop=in_w:in_h-40"

Source

crop filter Documentation

Concatenate

$ cat concat.txt
file '/path/to/file1'
file '/path/to/file2'
file '/path/to/file3'

$ ffmpeg -f concat -safe 0 -i concat.txt -c copy output.mkv

Using concat demuxer

Use this method when you want to avoid a re-encode and your format does not support file-level concatenation (most files used by general users do not support file-level concatenation).

(echo file 'first file.mp4' & echo file 'second file.mp4' ) > list.txt
ffmpeg -safe 0 -f concat -i list.txt -c copy output.mp4

This however requires your clips to have the same codec, resolution, framerate etc. – so it doesn't work with all kinds of heterogenous sources.

Using concat protocol

Use this method with formats that support file level concatenation (MPEG-1, MPEG-2 PS, DV). Do not use with MP4.

ffmpeg -i "concat:input1|input2" -c copy output.mkv

This method does not work for many formats, including MP4, due to the nature of these formats and the simplistic concatenation performed by this method.

Source

FFmpeg FAQ: How can I join video files?

FFmpeg Wiki: Concatenating media files

Mapping

By default, FFmpeg will only take one audio and one video stream. In your case that's taken from the first file only.

You need to map the streams correctly:

ffmpeg -i input.mp4 -i input.mp3 -c copy -map 0:v:0 -map 1:a:0 output.mp4
  • The order mapping options determine which streams from the input are mapped to the output.
  • 0:v:0 is the first video stream of the first file and 1:a:0 is the first audio stream of the second file. The v/a are not strictly necessary, but in case your input files contain multiple streams, that helps to disambiguate.
  • If your audio stream is longer than the video file, or vice-versa, you can use the -shortest option to have ffmpeg stop the conversion when the shorter of the two ends.

Source

FFmpeg Wiki: Selecting streams with the -map option

-map option Documentation

Fetch Total Frames Count

ffprobe: Query the container

ffprobe -v error -select_streams v:0 -show_entries stream=nb_frames -of default=nokey=1:noprint_wrappers=1 input.mp4
  • This is a fast method.
  • Not all formats (such as Matroska) will report the number of frames resulting in the output of N/A. See the other methods listed below.

What the ffprobe options mean:

  • -v error: This hides "info" output (version info, etc) which makes parsing easier.
  • -count_frames: Count the number of frames per stream and report it in the corresponding stream section.
  • -select_streams v:0: Select only the video stream.
  • -show_entries stream=nb_frames or -show_entries stream=nb_read_frames: Show only the entry for nb_frames or nb_read_frames.
  • -of default=nokey=1:noprint_wrappers=1: Set output format (aka the "writer") to default, do not print the key of each field (nokey=1), and do not print the section header and footer (noprint_wrappers=1). There are shorter alternatives such as -of csv=p=0.

ffmpeg: Count the number of frames

If you do not have ffprobe you can use ffmpeg instead:

ffmpeg -i input.mkv -map 0:v:0 -c copy -f null -
  • This is a somewhat fast method.
  • Refer to frame= near the end of the console output.
  • Add the -discard nokey input option (before -i) to only count key frames.

Source

Image Sequence to Video

Sequential

In this example the input images are sequentially named img001.png, img002.png, img003.png, etc.

ffmpeg -framerate 24 -i img%03d.png output.mp4

If -framerate option is omitted, the default will input and output 25 frames per second. See Framerates for more info.

Starting with a specific image

For example if you want to start with img126.png then use the -start_number option:

ffmpeg -start_number 126 -i img%03d.png -pix_fmt yuv420p out.mp4

FFmpeg Wiki: Slideshow

Video to Image Sequence

GIF/Video to Image Sequence

ffmpeg -i "input/Clap.gif" -vsync 0 "temp/frames%d.png"

Create a thumbnail image every X seconds of the video

Output one image every second:

ffmpeg -i input.mp4 -vf fps=1 out%d.png

Select a custom range with the select filter

Output images between between 2-6 seconds:

ffmpeg -i in.mp4 -vf select='between(t\,2\,6)' -vsync 0 out%d.png
  • Note: Use backslash (\) to escape the commas to prevent ffmpeg from interpreting the commas as separators for the filters.
  • Why vsync 0 is needed: The image2 muxer, which is used to output image sequences, defaults to CFR. So, when given frames with timestamp differences greater than 1/fps, ffmpeg will duplicate frames to keep CFR. That will happen here between selection of t=6 frame and t=15 frame. -vsync 0 prevents that.

Source

FFmpeg Wiki: Create a thumbnail image every X seconds of the video

Delay Audio/Video

If you need to delay video by 3.84 seconds, use a command like this:

ffmpeg.exe -i "movie.mp4" -itsoffset 3.84 -i "movie.mp4" -map 1:v -map 0:a -c copy "movie-video-delayed.mp4"

If you need to delay audio by 3.84 seconds, use a command like this:

ffmpeg.exe -i "movie.mp4" -itsoffset 3.84 -i "movie.mp4" -map 0:v -map 1:a -c copy "movie-audio-delayed.mp4"
  • -itsoffset 3.84 -i "movie.mp4" offsets timestamps of all streams by 3.84 seconds in the input file that follows the option (movie.mp4).
  • -map 1:v -map 0:a takes video stream from the second (delayed) input and audio stream from the first input - both inputs may of course be the same file.

A more verbose explanation can be found here: http://alien.slackbook.org/blog/fixing-audio-sync-with-ffmpeg/

Source

Setting Up a Frameserver for Premiere Pro using Vapoursynth

  1. Install ​Debugmode FrameServer, ​Vapoursynth and ​ffmpeg.

  2. Create a Vapoursynth script named frameserver.vpy by opening a text editor and adding the following (assuming your working directory is D:\Videos\Editing):

    import vapoursynth as vs
    core = vs.get_core()
    
    input = r'D:\Videos\Editing\output.avi'
    
    video = core.avisource.AVISource(input)
    video.set_output()
  3. Open Premiere, select your sequence, and choose "File > Export > Media" (or Ctrl+M).

  4. Under "Export Settings" choose Format: DebugMode FrameServer. Give your file the same name and path based on your Vapourynth script (output.avi in D:\Videos\Editing for this example).

    DebugMode Frameserver in Export Settings

  5. The FrameServer setup window will appear. Set the "Format" in "Video Output" to YUV2. Choose "Next".

    FrameServer setup window

  6. Now you can pipe your Vapoursynth script into ffmpeg. Type this in cmd,

    vspipe frameserver.vpy - --y4m | ffmpeg -i - -c:v libx264 -qp 0 -preset veryfast lossless.mp4

Note: VapourSynth doesn't support audio output, so you would have to export the audio separately.

Source

Speed up/Slow down Part of Video

This slows down one part of a video and keeps the rest as is.

ffmpeg -i input.mp4 `
  -filter_complex
    "[0:v]trim=0:2,setpts=PTS-STARTPTS[v1];
     [0:v]trim=2:5,setpts=2*(PTS-STARTPTS)[v2];
     [0:v]trim=5,setpts=PTS-STARTPTS[v3];
     [0:a]atrim=0:2,asetpts=PTS-STARTPTS[a1];
     [0:a]atrim=2:5,asetpts=PTS-STARTPTS,atempo=0.5[a2];
     [0:a]atrim=5,asetpts=PTS-STARTPTS[a3];
     [v1][a1][v2][a2][v3][a3]concat=n=3:v=1:a=1"
  -c:v libx264 -preset slow output.mp4

How does it work?

  • The trim and atrim filters cut the video into different parts, from 0–2 seconds, from 2–5, and from 5 to the end.
  • In each part a setpts/asetpts filter is applied, which, when using the option PTS-STARTPTS, "resets" the presentation timestamps of each frame in each part, so that they can later be concatenated easily.
  • Each part is given an output label (e.g. [v1] through [v3]).
  • For the video parts that need to be slowed down, every presentation timestamp is doubled (2*(…)), which effectively halves the speed of the video. If you wanted to speed up the video, use a multiplier lower than 1.
  • For audio parts to be sped up / slowed down, use the atempo filter, whose parameter is the speedup (e.g., 0.5 = half speed).
  • These parts are finally concatenated using the concat filter.

Notes about concat:

  • n Set the number of segments. Default is 2.
  • v Set the number of output video streams, that is also the number of video streams in each segment. Default is 1.
  • a Set the number of output audio streams, that is also the number of audio streams in each segment. Default is 0.

Source

How to use trim with HH:MM:SS

There are a variety of methods to do this. Here are three:

"trim=start='00\:00\:01.23':end='00\:00\:04.56'"
"trim=start=00\\\:00\\\:01.23:end=00\\\:00\\\:04.56"
trim=start=00\\\\:00\\\\:01.23:end=00\\\\:00\\\\:04.56

Source

FFmpeg Utilities Documentation: Quoting and escaping

Additional Resources

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment