rendi-api FFmpeg Cheatsheet

repository·main·Indexed 23 days ago

https://github.com/rendi-api/ffmpeg-cheatsheet

A categorized collection of FFmpeg commands and ready-to-use snippets for video automation pipelines. Covers common media manipulation tasks including remuxing, encoding, upscaling with aspect ratio preservation, audio replacement and mixing, jump cuts, and social media cropping.

Tokens
11.5K
Snippets
37
Records
61
Agent score
66%

What's inside ffmpeg-cheatsheet

  1. Perform Input vs Output seeking

    main

    Seeking determines how FFmpeg finds the timestamp you want to start at.

    Input Seeking (-ss before -i)

    • Usage: ffmpeg -ss [time] -i input.mp4 ...
    • Pros: Extremely fast; it jumps to the nearest keyframe.
    • Cons: Less accurate; it may not land exactly on the requested timestamp.

    Output Seeking (-ss after -i)

    • Usage: ffmpeg -i input.mp4 -ss [time] ...
    • Pros: Frame-accurate; it decodes and discards frames until it reaches the exact timestamp.
    • Cons: Slower, as it must decode the preceding frames.

    Critical Advice for Trimming: When trimming, it is advised to use output seeking and re-encode the video (do NOT use -c:v copy). Using -c:v copy with seeking can result in black frames or errors because the stream copy might miss the necessary keyframe data required to render the frames immediately following the seek point.

  2. Understand FFmpeg stream and filter notation

    main

    FFmpeg uses specific notation to target streams and apply filters:

    • -vf / -filter:v: Applies a filter chain to video streams only.
    • -af / -filter:a: Applies a filter chain to audio streams only.
    • -filter_complex: Used for complex filter graphs involving multiple inputs, multiple outputs, or mixed audio/video streams.

    Stream Selection Notation:

    • [0]: Selects all streams from the first input.
    • [0:v]: Selects the video stream from the first input.
    • [1:a]: Selects the audio stream from the second input.
    • [name]: Refers to a named intermediate or output stream within a -filter_complex graph.
    • -map [name], -map 0:a, etc.: Explicitly chooses which streams are included in the output.
  3. FFmpeg Best Practices and Gotchas

    main

    Key Technical Considerations

    • Seeking Accuracy: -ss before -i is fast but approximate (input seeking). -ss after -i is slower but frame-accurate (output seeking).
    • Codec Compatibility: For web-hosted MP4/MOV/M4A, use -movflags +faststart to allow playback to start before the file is fully downloaded. For H.264 playback in browsers/QuickTime, use -pix_fmt yuv420p.
    • Stream Mapping: In complex commands, [0:v] refers to the video stream of the first input, and [1:a] refers to the audio stream of the second input. Use -map to explicitly choose which streams go to the output.
    • Re-encoding Requirements: Burning subtitles or applying video filters requires re-encoding. Use -c copy only for simple remuxing or when no changes are made to the stream content.
    • Filter Syntax: Filter expressions are shell-sensitive. When using time expressions in double-quoted filter graphs, use single quotes inside them to avoid shell interference.
  4. Control video quality with CRF (Constant Rate Factor)

    main

    CRF is the recommended rate control mode for most uses when file size is less important than quality. It allows the encoder to maintain a consistent quality level throughout the file.

    • Range: 0–51 (0 is lossless, 23 is default, 51 is worst).
    • Recommended range: 17–28.
    • High quality: -crf 18 or even -crf 10 for very high quality.
    • Scaling: The scale is exponential; increasing CRF by 6 roughly halves the bitrate/file size.

    Note for VP9 (libvpx-vp9): To trigger Constant Quality mode, you must use -crf <value> in combination with -b:v 0.

  5. Trim video by time

    main

    To extract a specific segment from a video, use the -ss (start time) and -to (end time) flags.

    Note: While there are faster seeking methods, using -ss and -to in this manner is generally more accurate for precise trimming, though it may occasionally result in black frames at the start of the clip.

  6. Overlay text on video with drawtext

    main

    Use the drawtext filter to overlay text. You can control visibility, position, font, and background boxes.

    Key Options:

    • text='...': The string to display.
    • textfile=path.txt: Load text from an external file (recommended to avoid shell escaping issues).
    • fontfile=path.ttf: Path to a specific font file.
    • x=val:y=val: Position of the text.
    • fontsize=val: Size of the font.
    • fontcolor=color: Color of the text.
    • alpha='expression': Controls transparency (e.g., for fade-in effects).
    • enable='expression': Controls when the text is visible (e.g., enable='gte(t,1)' shows text starting at 1s).
    • box=1: Enables a background box.
    • boxcolor=color@alpha: Sets background color and opacity (e.g., #6bb666@0.6).
    • boxborderw=val: Padding around the text box.
  7. Combine and fade multiple MP3 tracks

    main

    To join two audio tracks with a smooth transition, use the afade filter to fade out the first track and fade in the second, then use the concat filter to join them.

    • afade=t=out:st=2:d=3: Fades out the audio starting at second 2 with a duration of 3 seconds.
    • afade=t=in:st=0:d=3: Fades in the audio starting at second 0 with a duration of 3 seconds.
    • concat=n=2:v=0:a=1: Concatenates 2 inputs, producing 0 video streams and 1 audio stream.
    ffmpeg -i https://storage.rendi.dev/sample/Neon_Lights_5sec.mp3 -i https://storage.rendi.dev/sample/Neon%20Lights.mp3 -filter_complex "[0:a]afade=t=out:st=2:d=3[a0];[1:a]afade=t=in:st=0:d=3[a1];[a0][a1]concat=n=2:v=0:a=1" -c:a libmp3lame -q:a 2 output_gapless_fade.mp3
  8. Optimize videos for web playback with faststart

    main
    Use -movflags +faststart to move the metadata (moov atom) to the beginning of the container. This allows videos to start playing immediately while downloading (progressive download), which is highly recommended for MP4, M4A, and MOV files.
  9. Crop video for social media (Vertical format)

    main

    To convert a landscape video (e.g., 1080x720) to a vertical social media format (e.g., 720x1080), you can split the video into chunks, crop them to specific areas, and then concatenate them.

    Key Filters:

    • split=3[1][2][3]: Splits input into 3 named chunks.
    • trim=start:end: Trims the video to a specific time segment.
    • setpts=PTS-STARTPTS: Resets timestamps (required when using trim and concat).
    • crop=w:h:x:y: Crops the video. Using min(in_w-offset, target_w) helps prevent cropping outside boundaries.
    • pad=w:h:x:y:color: Adds black padding if the crop dimensions are smaller than the target, preventing distortion.
    • scale=w:h: Resizes the cropped chunk to the target resolution.
    • concat=n=N:v=1: Concatenates the processed chunks back into one video stream.
  10. Mix audio from a video and an external file

    main

    To mix the original audio from a video with a new audio file, use a -filter_complex with the amix filter.

    To prevent the new audio from overpowering the original, use the volume filter on the second input (e.g., [1:a]volume=0.2[a1]).

    Important: Use both amix=duration=shortest (within the filter) and the -shortest flag (as a global option) to ensure the output video length matches the shortest input and to avoid bugs related to output duration.

    ffmpeg -i https://storage.rendi.dev/sample/big_buck_bunny_720p_16sec.mp4 -i https://storage.rendi.dev/sample/Neon_Lights_5sec.mp3 -filter_complex "[1:a]volume=0.2[a1];[0:a][a1]amix=inputs=2:duration=shortest" -shortest -map 0:v -c:v copy -c:a aac output_mix_audio.mp4
  11. Merge, mix, and normalize multiple audio sources

    main

    To merge audio from multiple MP4 files into a single MP3, you can use a complex filter chain to:

    1. Mix them using amix.
    2. Pan the result to mono using pan=mono|c0=.5*c0+.5*c1 (blending 50% of left and 50% of right channels).
    3. Apply dynamic normalization using dynaudnorm to smooth out volume differences.
    4. Downsample to a specific rate (e.g., -ar 16000).
    ffmpeg -i https://storage.rendi.dev/sample/big_buck_bunny_720p_16sec.mp4 -i https://storage.rendi.dev/sample/popeye_talking.mp4 -filter_complex "[0:a][1:a]amix=inputs=2:duration=longest,pan=mono|c0=.5*c0+.5*c1,dynaudnorm" -ar 16000 -c:a libmp3lame -b:a 64k merged_audio.mp3
  12. Concatenate multiple media clips

    main

    To join clips (e.g., Intro + Main + Outro) using the concat filter, you must first normalize the streams to ensure they have matching frame rates (fps), pixel formats, Sample Aspect Ratio (SAR), and audio sample formats.

    Pattern for normalization and concatenation:

    [0:v]fps=30,format=yuv420p,setsar=1[intro_v];
    [0:a]aformat=sample_fmts=fltp:channel_layouts=stereo[intro_a];
    ...
    [intro_v][intro_a][main_v][main_a][outro_v][outro_a]concat=n=3:v=1:a=1[outv][outa]

    In the concat filter, n=3 specifies the number of segments, v=1 specifies one video output, and a=1 specifies one audio output.