Table of Contents

ffmpeg

A collection of useful scripts:

Video manipulation

Reduce video filesize

Re-encode into H.265 with high CRF value (works for old formats with less efficient compression). Source.

ffmpeg -i INPUT.mp4 -vcodec libx265 -crf 28 OUTPUT.mp4

If H.265 is not desirable, change the video codec and lower the CRF value to maintain similar quality.

ffmpeg -i INPUT.mp4 -vcodec libx264 -crf 26 OUTPUT.mp4

Rotate video

Two parameters govern this: (1) actual video orientation, (2) rotation metadata. Source.

First check if there is already rotation metadata present that is rotating the video weirdly.

ffmpeg -i INPUT.mp4 2>&1 | grep rotate

If rotation metadata is present, adjust it (the other options allow preserving of global metadata).

ffmpeg -i INPUT.mp4 -map_metadata 0 -metadata:s:v rotate="90" -codec copy OUTPUT.mp4

If no rotation metadata is present, either insert it, or re-encode the whole video to support in older video players using the transpose parameter. Supply the video codec to avoid re-encoding into different format, and simply copy the audio stream.

ffmpeg -i INPUT.mp4 -vf "transpose=1" -vcodec libx264 -a:c copy OUTPUT.mp4

The transpose parameter accepts the following:

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

For 180 degrees rotation, use -vf "transpose=2,transpose=2"

Cropping video

ffmpeg -i INPUT.mp4 -vf "crop=123:234:345:456" OUTPUT.mp4

Crops a rectangular box of length 123 and width 234, starting from top-left coordinates of (345,456). Recommended to use a image editing program to identify the position and bounding boxes (e.g. screenshot).

Remove audio stream

Copy the video stream but not the audio stream. Source.

ffmpeg -i INPUT.mp4 -vcodec copy -an OUTPUT.mp4

If using another source for audio instead,

ffmpeg -i video_from_here.mp4 -i audio_from_here.mp4 \
    -c:v copy -c:a copy -map 0:v:0 -map 1:a:0 output.mp4

Other file formats

Convert to GIF

The split filter controls the color palette - here we reuse the color palette from the video, according to source.

ffmpeg -ss 2 -t 0.5 -i input.mp4 \
    -vf "fps=30,scale=640:-1:flags=lanczos,split[s0][s1];[s0]palettegen[p];[s1][p]paletteuse" \
    -loop 0 output.gif

Convert to video

Colorspace of GIFs are small, so might also be good to encode images as a video instead:

ffmpeg -framerate 18.6264 -i "20230803_dataset594_histogram_%d.png" \
    -c:v libx264 -vf "fps=30,tpad=stop_mode=clone:stop_duration=2,format=yuv420p" spedup.mp4

Add subtitles

Subtitles need to be in .ass (Advanced SubStation Alpha) format instead of the more commonly seen .srt (SubRip Text). For subtitles during a specific scene, use the offset flag to automatically adjust the timing (.ass has a precision of 10ms):

ffmpeg -itsoffset -1:28:23.12 -i subtitles.srt subtitles.ass
ffmpeg -i {{INPUT}}.mov -vf ass=subtitles.ass -crf 24 {{OUTPUT}}.mp4

Of tangential interest, this Wikipedia article quotes the ATSC committee recommendation of audio-leading-video between -45 to +15ms, and quotes ITU measured detectability threshold to -125 to +45ms. This is an audio sync problem, which may be relevant for accurate subtitle sync as well.