My posts are usually notes and reference materials for myself, which I publish here with the hope that others might find them useful.
Given a source video
To compress for web at a reasonable broadband bitrate of about 1.5Mbps video / 128kbps audio:
ffmpeg -i source.mp4 -c:v libx264 -b:v 1.5M -c:a aac -b:a 128k target.mp4
To compress and also convert to WebM:
ffmpeg -i source.mp4 -c:v libvpx-vp9 -b:v 1M -c:a libopus -b:a 128k target.webm
(Note that the 33% lower bitrate -- 1M for VP9 vs 1.5M for H.264 -- is deliberate; VP9 encodes about 20-50% more efficiently than H.264. Opus and AAC are about equally efficient.)
To scale down a high-resolution source video to something more reasonable for Web (qHD for cellular, HD for broadband), the
-filter:v argument is used:
ffmpeg -i source.mp4 -c:v libvpx-vp9 -b:v 0.33M -c:a libopus -b:a 96k \ -filter:v scale=960x540 target.webm
-c:v specifies the video codec;
-b:v specificies video bitrate;
-c:a specifies audio codec;
-b:a audio bitrate;
-filter:v applies a filter (in this case, scale) to the video stream.
To use the older VP8 codec with WebM, use
libvpx instead of
If the source video does not have an audio track, then omit the
To explicitly specify the container format, use the
-f command-line option:
-f mp4 or
For MP4 containers, the video codec used is H.264 and the audio codec is AAC, which enjoys near-universal browser support.
For Chrome and related browsers. WebM containers use VP8/9 and Opus.
Chrome also supports MP4 (H.264/AAC), so there is no point providing WebM unless the file size and/or quality is improved.
Bitrates can obviously be varied; I use 0.5M video and 96k audio for cellular.