Video on demand: hosting and streaming stored video
Upload, organise and deliver recorded video efficiently with object storage and HLS.
Recorded video is a delivery problem more than a hosting problem. Get the storage and the delivery format right and the rest is easy.
Where the files live
Store video in object storage, not on the web server's disk — see Object storage basics. Object storage is cheap, scales, and can be served directly to viewers or via a CDN without touching your app server.
Deliver as HLS, not a raw MP4
A single huge MP4 forces the whole file (or a large chunk) before playback, and cannot adapt to slow connections. HLS breaks the video into small segments and serves a manifest the player follows, enabling:
Instant start (play while downloading).
Adaptive quality (switch renditions mid-playback).
Seek anywhere, quickly.
Transcode an uploaded MP4 into HLS segments with FFmpeg · source:
ffmpeg -i input.mp4 \
-vf "scale=-2:720" -c:v libx264 -preset veryfast -crf 21 \
-c:a aac -b:a 128k \
-hls_time 6 -hls_playlist_type vod \
-hls_segment_filename "seg_%03d.ts" index.m3u8Generate a ladder (1080p/720p/480p) and a master manifest for adaptive playback.
Organise with metadata
Keep a thumbnails, title, description and duration per asset so your library is browsable. MediaCMS, PeerTube and Jellyfin (all listed under app hosting) are ready-made front-ends if you would rather not build one.
Bandwidth expectations
VOD bandwidth = bitrate × concurrent viewers. A popular 1080p library at 5 Mbps with 50 simultaneous viewers is 250 Mbit/s — object storage behind a CDN is the sane architecture at that point.
Access control
If the video is private, do not rely on an unguessable URL alone. Use signed URLs (time-limited) or a token check at the edge. Public marketing video can be genuinely public; paid content must not be.
Related reading