Skip to content

Instantly share code, notes, and snippets.

@yunooooo
Forked from steven2358/ffmpeg.md
Last active March 19, 2023 11:44
Show Gist options
  • Save yunooooo/0eb0cc29cf9091650e3b4a86580d9e86 to your computer and use it in GitHub Desktop.
Save yunooooo/0eb0cc29cf9091650e3b4a86580d9e86 to your computer and use it in GitHub Desktop.
FFmpeg cheat sheet

FFmpeg Cheat Sheet

A list of useful commands for the ffmpeg command line tool.

Full documentation: https://www.ffmpeg.org/ffmpeg.html

Basic conversion

ffmpeg -i input.mp4 output.mkv

Remux an MKV file into MP4

ffmpeg -i input.mkv -c copy output.mp4

High-quality encoding

Use the crf (Constant Rate Factor) parameter to control the output quality. The lower crf, the higher the quality (range: 0-51). The default value is 23, and visually lossless compression corresponds to -crf 18. Use the preset parameter to control the speed of the compression process. Additional info: https://trac.ffmpeg.org/wiki/Encode/H.264

ffmpeg -i in.mp4 -preset slower -crf 18 out.mp4

Trimming

Without re-encoding:

ffmpeg -ss [start] -i in.mp4 -t [duration] -c copy out.mp4
  • -ss specifies the start time, e.g. 00:01:23.000 or 83 (in seconds)
  • -t specifies the duration of the clip (same format).
    • -to specified the end time. Must be used in place of -t.
  • -c copy copies the first video, audio, and subtitle bitstream from the input to the output file without re-encoding them. This won't harm the quality and make the command run within seconds.

With Re-encoding:

If you leave out the -c copy option, ffmpeg will automatically re-encode the output video and audio according to the format you chose. For high quality video and audio, read the x264 Encoding Guide and the AAC Encoding Guide, respectively.

ffmpeg -ss [start] -i in.mp4 -t [duration] -c:v libx264 -c:a aac -strict experimental -b:a 128k out.mp4

Mux video and audio from different videos:

To copy the video from in0.mp4 and audio from in1.mp4:

ffmpeg -i in0.mp4 -i in1.mp4 -c copy -map 0:0 -map 1:1 -shortest out.mp4

Resize Video

To convert a video to 720p:

ffmpeg -i input.mp4 -vf scale=-1:720 output.mp4

To convert a video to 4K:

ffmpeg -i input.mp4 -vf scale=-1:2160 output.mp4

Convert Video to GIF

To make a .gif that is half the size of the input video (recommended)

ffmpeg -i input.mp4 -filter_complex "scale=iw/2:ih/2,split [a][b];[a] palettegen=stats_mode=diff [p];[b][p] paletteuse=new=1" output.gif

To make a .gif that is the same size with 30fps (slow, not recommended)

ffmpeg.exe -i input.mp4 -filter_complex "[0:v] fps=30,split [a][b];[a] palettegen=stats_mode=diff [p];[b][p] paletteuse=new=1" output.gif

Change Video Speed

To double the speed of a video:

ffmpeg -i input.mp4 -vf "setpts=0.5*PTS" output.mp4

Use the following for setpts to change the speed:

  • setpts=2*PTS = Half Speed
  • setpts=0.5*PTS = 2x Speed
  • setpts=0.25*PTS = 4x Speed

Concat Demuxer

First, make a text file.

file 'in1.mp4'
file 'in2.mp4'
file 'in3.mp4'
file 'in4.mp4'

Then, run ffmpeg:

ffmpeg -f concat -i list.txt -c copy out.mp4

Delay audio/video

Delay video by 3.84 seconds:

ffmpeg -i in.mp4 -itsoffset 3.84 -i in.mp4 -map 1:v -map 0:a -vcodec copy -acodec copy out.mp4

Delay audio by 3.84 seconds:

ffmpeg -i in.mp4 -itsoffset 3.84 -i in.mp4 -map 0:v -map 1:a -vcodec copy -acodec copy out.mp4

Stack two video files side by side:

ffmpeg -i left.mp4 -i right.mp4 -filter_complex hstack output.mp4

Burn subtitles

Use the libass library (make sure your ffmpeg install has the library in the configuration --enable-libass). First convert the subtitles to .ass format:

ffmpeg -i sub.srt sub.ass

Then add them using a video filter:

ffmpeg -i in.mp4 -vf ass=sub.ass out.mp4

Rotate a video

Rotate 90 clockwise:

ffmpeg -i in.mov -vf "transpose=1" out.mov

For the transpose parameter you can pass:

0 = 90CounterCLockwise and Vertical Flip (default)
1 = 90Clockwise
2 = 90CounterClockwise
3 = 90Clockwise and Vertical Flip

Use -vf "transpose=2,transpose=2" for 180 degrees.

Deinterlace

ffmpeg -i input.ts -vf yadif=1 -c:v libx264 -preset slow -c:a copy output.ts
  • yadif=0 will output a frame for each frame
  • yadif=1 will output a frame for each fields (recommended)

Create a video slideshow from images

Parameters: -r marks the image framerate (inverse time of each image); -vf fps=25 marks the true framerate of the output.

ffmpeg -r 1/5 -i img%03d.png -c:v libx264 -vf fps=25 -pix_fmt yuv420p out.mp4

Extract images from a video

Note: Converting to .bmp will process a lot faster than .jpg

  • Extract all frames: ffmpeg -i input.mp4 thumb%04d.jpg
  • Extract a frame each second: ffmpeg -i input.mp4 -vf fps=1 thumb%04d.jpg
  • Extract only one frame: ffmpeg -ss 0:10 -i input.mp4 -vframes 1 thumb.jpg

Display the frame number on each frame

ffmpeg -i in.mov -vf "drawtext=fontfile=arial.ttf: text=%{n}: x=(w-tw)/2: y=h-(2*lh): fontcolor=white: box=1: boxcolor=0x00000099: fontsize=72" -y out.mov

Create Thumbnail Grid from Video

ffmpeg -hide_banner -loglevel -i input.mp4 -ss 0:01 -vframes 6 -vf "select=not(mod(n\,300)),scale=-1:320,tile=3x2" -vsync vfr thumbnails.jpg
  • -ss 0:01 = Starts the frame previews at 0:01
  • -vframes 6 = Generates 6 frames
  • mod(\n,300) = Selects every 300 frames
  • scale=-1:320 = Resizes the frames to 360 height
  • tile=3x2 = Output image grid is 3 columns + 2 rows

Create .m3u8 file losslessly (for HLS Stream):

ffmpeg -i input.mp4 -c:v copy -c:a copy -sn -f hls -hls_time 4 -hls_playlist_type event output.m3u8

Metadata: Change the title

ffmpeg -i in.mp4 -map_metadata -1 -metadata title="My Title" -c:v copy -c:a copy out.mp4

Download "Transport Stream" video streams

  1. Locate the playlist file, e.g. using Chrome > F12 > Network > Filter: m3u8
  2. Download and concatenate the video fragments:
ffmpeg -i "path_to_playlist.m3u8" -c copy -bsf:a aac_adtstoasc out.mp4

If you get a "Protocol 'https not on whitelist 'file,crypto'!" error, add the protocol_whitelist option:

ffmpeg -protocol_whitelist "file,http,https,tcp,tls" -i "path_to_playlist.m3u8" -c copy -bsf:a aac_adtstoasc out.mp4

Mute some of the audio

To replace the first 90 seconds of audio with silence:

ffmpeg -i in.mp4 -vcodec copy -af "volume=enable='lte(t,90)':volume=0" out.mp4

To replace all audio between 1'20" and 1'30" with silence:

ffmpeg -i in.mp4 -vcodec copy -af "volume=enable='between(t,80,90)':volume=0" out.mp4

Batch FFmpeg Processing

This command uses FOR to run ffmpeg to convert every .mp4 in the current folder to .mkv without quality loss

FOR %a in (*.mp4) DO ffmpeg -i "%a" -c copy -strict experimental "%~na.mkv"

Useful Parameters with Descriptions

  • -i = input file
  • -c = codec
    • -c:a - audio codec
    • -c:v - video codec
    • -c:s - subtitle codec
  • -sn = disable subtitles
  • -an = disable audio
  • -vn = disable video
  • -ab = audio bitrate
  • -hide_banner = hide banner in output
  • -loglevel quiet = hides usual metadata from output

Extra Info

Video Containers
  • .mp4 - MPEG-4 (Part 14)
  • .m4v - Raw MPEG-4
  • .mov - QuickTime
  • .mkv - Matroska
  • .webm - WebM (Used for HTML5)
  • .m2ts - Blu-ray MPEG-2 TS (Blu-ray Transport Stream)
  • Outdated:
    • .avi - Audio Video Interleave (Microsoft)
    • .wmv - Windows Media Video (Microsoft)
    • .ts/.tp - MPEG-TS (Transport Stream)
Audio Containers
  • .flac - Free Lossless Audio Codec
  • .mp3 - MPEG Layer III Audio
  • .m4a - An audio-only MPEG-4 file
  • .opus - Opus Container Format
  • .wav - Standard Microsoft lossless container
  • .aiff - Standard Apple lossless container
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment