How Channels DVR delivers an HLS M3U source with subtitles (and what survives)

Tested with a custom M3U source (Stream Format HLS: H.264 + AAC, a WebVTT subtitle track, and EIA-608 in the video), on Apple TV and iPhone (Channels app 7.1.2), DVR ffmpeg 6.0.2.

Delivery paths

  • Direct (local, Original): the app fetches /devices/…/channels/N/stream.mpg. No ffmpeg runs; the DVR passes the TS through. WebVTT and 608 both reach the app. Recordings are the same raw TS, so they keep both tracks too.
  • Stream (HLS) at Original: master.m3u8?codec=copy&format=copy → ffmpeg remux (-c:v copy -c:a copy -c:s copy -f hls -hls_passthrough_subtitles 1). WebVTT ends up as a private data stream and the master playlist has no SUBTITLES group, so the app shows nothing. 608 stays in the video.
  • Reduced quality: the app only sends ?bitrate=N. If N is above the source rate, it's still the plain remux. Below it, a second ffmpeg transcodes (libx264 veryfast, fastdeint=blend, scaled to 720p, or 384p around 300 kbps, with -b:v/-minrate/-maxrate). 608 survives the transcode; WebVTT doesn't.
  • Remote: even "Original" uses the HLS remux, and on cellular the app's adaptive bitrate stepped down to a 384p transcode within a minute. So remotely only 608 works. The quality choice is entirely client-side; on the server, a VPN client that connects directly counts as local, and any X-Forwarded-For header makes a request remote (auth required).
  • Audio: AAC is copied (re-encoded to stereo at low bitrates); AC-3 is re-encoded to 6-channel AAC 256k.

How the app shows captions (tvOS and iOS)

  • WebVTT ("On"): centered, but only available on Direct. Cue end times are ignored: a caption stays until the next one replaces it.
  • 608 ("Track 2"): works on every path, but is always drawn in a left-anchored box. PAC column/tab offsets are ignored, and leading spaces and transparent spaces are trimmed. Even a full 32-column row sits on the left.
  • 708 only: not shown at all.

Takeaway: for remote viewers, embed 608. For centered text at home, add WebVTT (Direct only).

What would help

  1. Pass WebVTT through the HLS remux/transcode as a real SUBTITLES rendition.
  2. Honor 608 positioning (PAC indent / column).
  3. Honor WebVTT cue end times.