FFMPEG Notes

Published: March 31, 2025

← Newer EntryOlder Entry →


I'm no master of FFMPEG, but I've learned a few things here and there that I think might help.

Please note that these commands use Windows Command Prompt line-continuation characters (^), so you'll need to change them depending on your environment (\ for POSIX shells, ` for PowerShell).

Various Operations

Extract audio from video

Command:

ffmpeg ^
  -i {INPUT_VIDEO_FILE} ^
  -vn ^
  -acodec copy ^
  {OUTPUT_AUDIO_FILE}

Example:

ffmpeg ^
  -i input.mp4 ^
  -vn ^
  -acodec copy ^
  output.aac

The -vn flag disables video output.

Add fade

Command:

ffmpeg ^
  -i {INPUT_VIDEO_FILE} ^
  -vf "fade=t={DIRECTION}:st={STARTING_TIME}:d={DURATION}" ^
  -c:a copy ^
  {OUTPUT_VIDEO_FILE}

Example:

ffmpeg ^
  -i input.mp4 ^
  -vf "fade=t=in:st=1:d=1" ^
  -c:a copy ^
  output.mp4

st=1 indicates the starting time, and d=1 indicates how long it should take for the fade to complete. You can change fade=t=in to fade=t=out to create a fade-out effect instead, but you'll need to adjust the timing so it starts near the end of the video instead.

Replace audio track

Command:

ffmpeg ^
  -i {INPUT_VIDEO_FILE} ^
  -i {REPLACEMENT_AUDIO_FILE} ^
  -c:v copy ^
  -map 0:v:0 ^
  -map 1:a:0 ^
  {OUTPUT_VIDEO_FILE}

Example:

ffmpeg ^
  -i input.mp4 ^
  -i newaudio.wav ^
  -c:v copy ^
  -map 0:v:0 ^
  -map 1:a:0 ^
  output.mp4

Take note that, if the audio file is longer than the video file, the audio will not be clipped to the duration of the video. You'll need to make sure they're both the same length, or it'll freeze on the last video frame until the audio track finishes playing.

Cut clip, re-encoding video to reset keyframes

A higher CRF value will reduce the quality but also the file size. A slower preset will result in a smaller file size due to more optimized compression, but it'll take longer to encode the file (see this page for more information). I usually set the preset to ultrafast while I'm trying to get the timing of the clip correct, then use slow when ready to perform the final cut.

Command:

ffmpeg ^
  -i {INPUT_VIDEO_FILE} ^
  -ss {START_TIME} ^
  -t {CLIP_DURATION} ^
  -c:v libx264 ^
  -crf {QUALITY} ^
  -preset {COMPRESSION_RATE} ^
  -c:a aac ^
  {OUTPUT_VIDEO_FILE}

Example:

ffmpeg ^
  -i input.mp4 ^
  -ss 00:20:00.0 ^
  -t 00:01:30.0 ^
  -c:v libx264 ^
  -crf 18 ^
  -preset slow ^
  -c:a aac ^
  output.mp4

Mapping Streams

Let's say you want to cut a clip from a file which has 1 video track, 3 audio tracks (Eng, Jpn, Fre), and 3 subtitle tracks (Eng, Fre, Ara). You want to capture the video, the English/Japanese audio, and the English subtitle track.

First, you need to use ffprobe.exe to check which tracks are which. You'll receive a detailed output with the metadata for each track in the file (which are called "streams"). Each stream has a brief descriptor, which indicates the stream number, the type of stream (audio, video, subtitle), and some other information such as the codec and/or resolution.

A lot of information has been truncated below, but you might see something similar to this:

Stream #0:0(ara): Subtitle: ass (default)
* Stream #0:1: Video: hevc (Main 10)...
Stream #0:2(fre): Audio: aac (LC)...
* Stream #0:3(jpn): Audio: aac (LC)...
* Stream #0:4(eng): Audio: aac (LC)...
Stream #0:5(fre): Subtitle: ass
* Stream #0:6(eng): Subtitle: subrip
* Stream #0:7: Attachment: ttf

You won't see the asterisks, though. I put those in to highlight which streams we want for this example (you'll see their indices in the command below). Note the TTF file as well, I'm pretty sure we'll want that, too.

For this example, we'll simply make a copy of the video. To select the streams, we'll use the -map option. We need to specify it for each of the streams we identified when we probed the video file.

ffmpeg ^
  -i input.mkv ^
  -c copy ^
  -map 0:1 ^
  -map 0:3 ^
  -map 0:4 ^
  -map 0:6 ^
  -map 0:7 ^
  output.mkv

And that's it! Another quick thing to note: if you have multiple streams, and you want to copy them all, it generally doesn't if you don't map anything. Without any mapping, FFMPEG will only copy the first streams it finds (in this case, it'd just copy the Japanese audio stream, for example). But, if you want to preserve ALL of the streams, simply use -map 0 and it'll do so.


← Newer EntryOlder Entry →


Return to Top