I’m standardizing my videos to keep them as small as possible while maintaining good quality. The goal is to make them easy to download or stream, without compromising readability or viewing experience. I may also include subtitles to make the content easier to understand and follow. As of now I want them to be at least 1080p. At some point I might do 2K videos, only for some videos.
- 720p (HD) is a video with resolution of 1280 pixels horizontally by 720 pixels vertically (1280×720)
- 1080p (Full HD or FHD) is a video with resolution of 1920 pixels horizontally by 1080 pixels vertically (1920×1080)
- 2K (DCI 2K) is a video with resolution of 2048 pixels horizontal and 1080 vertical (2048×1080).
Table of Contents
Standard Parameters
Container format : WebM
Video
- Codec: AV1
- FPS: 24 or max 30
- Bitrate: Yet to experiment
Audio
- Opus 64–96 kbps
Reference
| Use Case | CRF | Preset | Avg Video Mbps | Audio kbps | Total Mbps | 1-Min Size (MB) |
|---|---|---|---|---|---|---|
| Screen cast (UI, code) | 34–40 | 8–10 | 0.6 – 1.5 | 64–96 | ~1.0 | 7 – 11 MB |
| Lecture (talking head + slides) | 32–36 | 7–9 | 1.2 – 2.5 | 64–96 | ~2.1 | 14 – 18 MB |
| Travel vlog | 28–32 | 6–8 | 3 – 6 | 96–128 | ~4.6 | 30 – 40 MB |
| Cinematic / landscape / drone | 26–30 | 4–7 | 5 – 10 | 128 | ~8.1 | 55 – 70 MB |
| Fast motion (POV riding / sports) | 26–28 | 4–6 | 6 – 12 | 128 | ~10 | 70 – 90 MB |
| Archival master | 22–26 | 3–5 | 10 – 20 | 128–160 | ~15 | 105 – 120 MB |
Mobile Screencasts
Compress the video
time ffmpeg -i osmand_route_using_gpx.mp4 \
-vf "fps=24" \
-c:v libsvtav1 \
-crf 38 -preset 10 \
-c:a libopus \
osmand_route_using_gpx.webm
Video with 800 pixel height
time ffmpeg -i osmand_route_using_gpx.mp4 \
-vf "fps=24,scale=-2:800" \
-c:v libsvtav1 \
-crf 38 -preset 10 \
-c:a libopus \
osmand_route_using_gpx.webm
Re-scale to 1080p with padding
# Rescale to 1080p landscape with blurred backhround
ffmpeg -i osmand_route_using_gpx.mp4 -filter_complex \
"[0:v]fps=24,scale=1920:1080:force_original_aspect_ratio=increase,\
crop=1920:1080,boxblur=30:5[bg]; \
[0:v]fps=24,scale=1920:1080:force_original_aspect_ratio=decrease[fg]; \
[bg][fg]overlay=(W-w)/2:(H-h)/2" \
-c:v libsvtav1 -crf 38 -preset 10 \
-pix_fmt yuv420p \
-c:a libopus -b:a 96k \
OsmAnd_route_using_gpx_1080p_24fps.webm
# Rescale with a specific color background
# I have used color=0x82b965
ffmpeg -i OsmAnd_route_using_gpx.mp4 -filter_complex \
"[0:v]fps=24,scale=1920:1080:force_original_aspect_ratio=decrease[fg]; \
[fg]pad=1920:1080:(ow-iw)/2:(oh-ih)/2:color=0x82b965,format=yuv420p[v]" \
-map "[v]" -map 0:a? \
-c:v libsvtav1 -crf 38 -preset 12 \
-c:a libopus -b:a 96k \
OsmAnd_route_using_gpx_1080p_24fps_bgcolor_1.webm
Desktop Screencasts
TBD
Travel Videos
TBD
Examples
Mobile Screencast 800px height
Embedded here with width = 800px. Under 10MB for 2 Min video.
Mobile Screencast 720p
Embedded here with width = 100%. Try full screen for better idea. Under 10MB for 2 Min video.
Mobile Screencast 1080p
Embedded here with width = 100%. Try full screen for better idea. Under 15MB for 2 Min video.
AVIF
AV1 Image File Format (AVIF) is an open, royalty-free file format specification for storing images or image sequences compressed with AV1 in the HEIF container format. In simple words, its just a better GIF.
ffmpeg -i example.webm -crf 32 -r 8 -vf scale=1000:-1 example.avif
- -r is frame rate
-vf scale=1000:-1 is resize to 1000px width and -1 says keep the aspect ratio
Streaming
Progressive
WebM videos support progressive playback natively in the browser — playback begins before the full file downloads. This works because WebM (based on the Matroska container) stores codec headers early in the file along with a Cues element that acts as a seek table, mapping timestamps to byte offsets. Combined with HTTP range requests, the browser knows exactly which byte range to fetch for any given position, allowing it to buffer and seek without downloading the entire file. For small videos in particular, this makes progressive loading seamless without any additional streaming infrastructure.
Seeking depends on the Cues element. Without it; which can happen with poorly muxed files; seeking degrades to a linear scan or fails entirely.
Cues are sometimes written at the end of the file during recording, since the muxer doesn’t know byte offsets upfront. When this happens, seeking may be limited or unreliable until enough of the file has buffered, as the browser cannot resolve timestamp-to-byte mappings without first reaching the cues. Tools like mkvmerge, ffmpeg (with -cues_to_front) can relocate cues to the front of the file, which is recommended.
You can check where the cues are using ffprobe. For example
ffprobe -v trace -i screencast_linux_bash.webm 2>&1 | grep -i "cue\|seek"
[matroska,webm @ 0x59d40e52af80] Before avformat_find_stream_info() pos: 928 bytes read:32768 seeks:0 nb_streams:2
[matroska,webm @ 0x59d40e52af80] After avformat_find_stream_info() pos: 45464 bytes read:65536 seeks:0 frames:2
[AVIOContext @ 0x59d40e5337c0] Statistics: 65536 bytes read, 0 seeks
The command output shows -> Stream and codec information for both audio and video (nb_streams: 2) was found within the first 928 bytes (pos: 928). ffprobe only needed to read ~45KB (pos: 45464) into the file to gather everything it needed. Total read was 64KB across two sequential 32KB buffer loads — no seeking at all (seeks: 0), everything was found near the front of the file. It decoded 2 frames (frames: 2) to confirm codec parameters.
This is good for progressive load.
Dynamic Adaptive Streaming over HTTP (DASH)
ffmpeg -i osmand_route_using_gpx_720p_24fps_bgcolor.webm \
-map 0:v:0 -map 0:a? \
-c copy \
-f dash \
-use_template 1 -use_timeline 1 \
-seg_duration 30 \
-init_seg_name 'osmand_route_using_gpx_720p_24fps_bgcolor-init-$RepresentationID$.webm' \
-media_seg_name 'osmand_route_using_gpx_720p_24fps_bgcolor-chunk-$RepresentationID$-$Number$.webm' \
manifest.mpd
Other Test Videos
These are test videos. The ones that interests me are the 10 seconds videos of 1MB and 2MB file size. They are FHD.
10 Seconds – 1 MB – FHD
Embedded here with width = 100%. Try full screen for better idea.
10 Seconds – 2MB – FHD
Embedded here with width = 100%. Try full screen for better idea.