FFMPEG Notes

I'm no master of FFMPEG, but I've learned a few things here and there that I think might help. Any or all of the info on this page could be totally wrong.

Snippets

Extract audio from video

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

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

Add black (or any color) frames to start of video

You need to create a solid-color bitmap file that matches the video resolution for this.

ffmpeg -loop 1 -framerate {INPUT_VIDEO_FPS} -t {DURATION} -i {BITMAP_FILE} -i {INPUT_VIDEO_FILE} -filter_complex "[0][1]concat=n=2:v=1:a=0" {OUTPUT_VIDEO_FILE}

ffmpeg -loop 1 -framerate 30 -t 1 -i black.bmp -i input.mp4 -filter_complex "[0][1]concat=n=2:v=1:a=0" output.mp4

Add fade

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

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

Replace audio track

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

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

Combine GIF & audio files, pausing on last frame of GIF for 2 seconds, with fade in/out

The scale filter is needed for the GIF, the tpad filter pauses the GIF on its last frame, the fade filters are obvious.

ffmpeg -i {INPUT_GIF_FILE} -i {INPUT_AUDIO_FILE} -movflags faststart -pix_fmt yuv420p -vf "scale=trunc(iw/2)*2:trunc(ih/2)*2, tpad=stop_mode=clone:stop_duration=2, fade=in:0:20, fade=t=out:st=3:d=1" {OUTPUT_VIDEO_FILE}

ffmpeg -i input.gif -i input.wav -movflags faststart -pix_fmt yuv420p -vf "scale=trunc(iw/2)*2:trunc(ih/2)*2, tpad=stop_mode=clone:stop_duration=2, fade=in:0:20, fade=t=out:st=3:d=1" output.mp4

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.

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}

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

Tips

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.

I've highlighted the streams we want in yellow. 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.