VOD from Live
A live stream ends. The viewer who missed it wants to watch it on demand. The platform already has all the segments: they were generated during the live stream and pushed to the CDN. Making them into a VOD (video on demand) is less a technical challenge and more a stitching-and-indexing problem.
Segments Are Already There#
During a live stream, transcoding at ingest generates 2-6 second segments at each quality level. These segments are stored in object storage as they’re produced. The live manifest file (the HLS .m3u8 file) is a sliding window: it always points to the last N segments, dropping old ones as new ones arrive.
Converting to VOD means creating a permanent manifest that points to all segments from start to finish, not just the latest window. If a 4-hour stream produced 7200 segments (at 2 seconds each), the VOD manifest lists all 7200. Viewers can seek to any point by jumping to the appropriate segment.
The Seek Index#
Seeking to “1 hour 23 minutes in” requires knowing which segment contains that timestamp. The manifest file handles this: each segment entry includes its duration and cumulative start time. A player calculates “1:23:00 is at byte position X in the manifest, which corresponds to segment 2490.” Download segment 2490 and start playing.
For very long VODs (8+ hour gaming sessions), loading a manifest with thousands of entries gets slow. Platforms use chunked manifests: a top-level manifest points to sub-manifests covering 30-minute windows. Seeking loads only the relevant 30-minute sub-manifest.
Live-to-VOD Delay#
The VOD becomes available after the stream ends and the manifest generation job runs. Platforms advertise “VOD available within X minutes of stream end.” That X depends on: manifest generation time (fast, usually under a minute) plus any post-processing (adding chapter markers, generating thumbnails for the seek bar, running the recording through content moderation).
Thumbnail generation for the seek bar scrubber is the expensive part: generating one thumbnail per 30 seconds for a 4-hour stream means 480 thumbnails, each requiring decoding and scaling one video frame.
Storage Lifecycle#
VODs are kept for different durations depending on the platform’s policy. Twitch keeps VODs for 14-60 days by default. Long-term archival requires moving old segments to cold storage tiers. The segment files themselves are often small (2-6 seconds of video, a few MB each), so lifecycle policies operate at the manifest level: if the manifest is deleted, the segments become orphaned and can be garbage collected.
At Salesforce#
We generated weekly report exports that users could download later. The export process ran and stored results in S3. The download link was the URL to the stored export. Exports expired after 30 days. We built exactly this pattern: generate once, serve many times, expire on a schedule. The only difference from VOD is we weren’t dealing with 7200 segment files per export.
What I’m Learning#
The transition from live to VOD is mostly a metadata problem: you already have the data, you just need a different index into it. The live manifest is a rolling view; the VOD manifest is a complete view of the same data.
Have you built archival systems where the “archive” was really just a different index over data that already existed?