all projects
personalpythonfastapitypescriptreactffmpeghls
Self-hosted Web Media Player
A FastAPI + React media server I built because nothing off-the-shelf streamed my video collection the way I wanted. Hover previews, scrub-bar previews, on-demand HLS - all lazy, all cached, all snappy.
- preview format
- WebM (VP8)
- scrub bar
- VTT sprite sheets
- streaming
- on-demand HLS
Why
A big video collection on a disk attached to my home server. I wanted to watch it from any device without copying files or fighting Plex. Off-the-shelf options didn't match how I had things laid out, so I wrote my own. The interesting work was making it feel like YouTube on a home box that pre-transcodes nothing.
What makes it not boring
- Hover previews as a single WebM per video - 20 short clips sampled across the duration, concatenated. WebM not GIF, because GIFs are huge and ugly.
- Scrub-bar previews as VTT sprite sheets - one tiled JPEG plus a WebVTT cue map, sprite preloaded on VTT load so the browser cache is warm before the first hover. Zero HTTP per hover.
- On-demand HLS - playlists and
.tssegments synthesised at request time via ffmpeg. Storage is the constrained resource on a home box, so segments live as ephemeral output instead of pre-rendered files. - Thumbnails, previews, and sprite sheets all generated lazily in background threads on first metadata fetch, then cached. The grid never blocks on encoding.