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.