Vellum/internal/media
mithral 6201535dd7 Discover and serve subtitle tracks
Two halves of the same feature: the scanner finds tracks, the media layer
serves them as WebVTT.

Discovery walks each directory for .srt/.ass/.ssa/.vtt/.sub beside a video and
matches them by base name, including the language form "Movie.en.srt" and
"Movie.pt-BR.srt". A sidecar is never itself an item. Matching is a dot-guarded
prefix on the real video base name, so a dotted release name like
"The.Matrix.1999.1080p.en.srt" does not read the year as a language.

Serving adds two routes inside the existing item family, both grant-checked
through catalog.Store (ADR-005) so forbidden and absent are the same 404.
Browsers play WebVTT and nothing else, so .srt is converted (header plus the
comma-to-dot in timestamps), .vtt passes through, and embedded streams and
.ass/.ssa go through ffmpeg. Conversions are cached under ConfigDir, because
converting per request would spawn an ffmpeg on every seek. A track that fails
to convert fails alone - the video and the other tracks are unaffected.

Subtitle rows are a cache of what is on disk, so a vanished sidecar has its row
deleted. That is the opposite of a vanished video, which is marked instead
(ADR-003) because progress hangs off it and cannot be regenerated.

Verified red-green: disabling the sidecar call fails all four scanner tests,
and removing the VTT header fails the conversion test.

Known limits: a "Movie.forced.en.srt" records "forced.en" rather than "en",
and the conversion cache is keyed by track id, so a sidecar replaced under an
unchanged row serves the stale conversion until a rescan recreates the row.
2026-10-12 11:42:51 -04:00
..
covers.go Phase 3: EPUB module, file streaming, per-user progress 2026-10-09 16:36:27 -04:00
fixtures_test.go Phase 2: split the fat packages along real boundaries 2026-10-11 16:03:10 -04:00
handlers.go Discover and serve subtitle tracks 2026-10-12 11:42:51 -04:00
handlers_test.go Wave 3: search depth, transfer size, and the Home screen's tests 2026-10-11 13:46:18 -04:00
items.go Expose the television tree: catalog reads, API routes, Jellyfin shapes 2026-10-12 01:41:05 -04:00
items_test.go Wave 3: search depth, transfer size, and the Home screen's tests 2026-10-11 13:46:18 -04:00
media.go Phase 2: split the fat packages along real boundaries 2026-10-11 16:03:10 -04:00
series.go Expose the television tree: catalog reads, API routes, Jellyfin shapes 2026-10-12 01:41:05 -04:00
series_test.go Expose the television tree: catalog reads, API routes, Jellyfin shapes 2026-10-12 01:41:05 -04:00
subtitles.go Discover and serve subtitle tracks 2026-10-12 11:42:51 -04:00
subtitles_test.go Discover and serve subtitle tracks 2026-10-12 11:42:51 -04:00