Repository navigation
Live TV subtitles/audio, IPTV guide and playlist fixes - #806
Conversation
Live channels often carry their subtitles inside the stream (DVB bitmap subtitles in MPEG-TS) and more than one audio language. The Live TV player never chose a subtitle track, so subtitles only showed when the device's system captions were on in the same language - on some TVs and not on others - and the audio was whatever the stream listed first. Live TV now starts each channel on the profile's default subtitle language and default audio language (when not "Off" / "Auto"), and the full-screen controls gain Subtitles and Audio buttons that list the channel's tracks. A choice is remembered per channel for the session.
… focus IPTV HLS channels often carry DVB subtitles inside the TS segments while the master playlist's CODECS lists only video and audio. With chunkless preparation the player built its track list from CODECS alone, so those subtitles never appeared. Media3 already reads a segment when a variant lists two audio codecs, which is why channels of the same provider showed subtitles or not depending on their audio count. IPTV HLS is now always prepared from its first segment (Live TV, the Home preview and TvScreen); measured startup is unchanged. - Home preview: channel previews use the profile's default subtitle language; trailers keep the no-subtitle default. - A live stream whose buffer stops moving now raises an error after 12s (Media3's default is 10 minutes) and is restarted at the live edge, at most once a minute and outside the existing retry budget. - Full-screen controls: the action buttons no longer overlap the centred playback controls; the controls slide aside only when needed. - Closing the Subtitles or Audio list returns focus to the button that opened it, so left/right move between the controls again. - The track list is shared by Subtitles and Audio, so it is renamed to LiveTrackPicker / LiveTrackOption.
…dresses A plain M3U whose guide is only named in its `#EXTM3U url-tvg="..."` line showed no guide at all once its channels were kept in the SQLite store: - readCache() returned before restoring the saved guide address when the cache held no channels and no guide yet - always the case before the first guide load, so the guide could never load. - The store startup path (getPagedStartupSnapshotOrNull) never restored it. - Only a typed or Xtream guide counted as an XMLTV source. The saved address is now restored on those paths; when none was saved the playlist header is read once per session; a declared guide counts as an XMLTV source. The visible XMLTV fallback downloads the whole file, and the same file may not be fetched again for two minutes, so for lists up to 10,000 channels it now keeps every channel's programmes instead of only the visible rows (the 304 check still uses the requested channels). Pasted addresses can carry characters trim() keeps, e.g. a trailing NUL that sent every playlist request to `list.m3u%00` (HTTP 400). Playlist, guide and Stalker portal/MAC input now drop control and invisible format characters before use, which also repairs addresses already saved.
Switching which playlist is enabled left the Home Favorite TV row showing the old playlist's channels until the app restarted: the home load that follows finds the new channel list still loading, reports the row as unavailable and keeps it, and nothing rebuilt it once the list was ready. Home now watches the enabled playlists and portals. When they change it rebuilds the row as soon as the new list can be read - replaced, or removed when the new sources have no favourites - and drops a stale row that still cannot be rebuilt after about a minute. Renames and other settings do not trigger it.
With the subtitle or audio list open longer than the HUD's 5 s timeout, the HUD hiding handed focus back to the playback surface. Down then zapped channels and OK/Back no longer reached the list. The hand-back now waits while either list is open.
Broadcast IPTV channels often carry several DVB subtitle streams (for example Hebrew and Russian). In HLS mode Media3's TsExtractor keys tracks by stream type and keeps only the lowest PID of each, so only the first subtitle language ever reached the player - chosen by stream order, not by the user's language. IPTV HLS now uses a vendored copy of the media3 1.9.0 TS extractor (src/main/iptvts-java, same pattern as the vendored Matroska extractor) whose only change gives each DVB subtitle PID its own HLS track id. HLS maps text tracks by id, so all languages appear in the Subtitles list. IptvHlsExtractorFactory routes MPEG-TS segments to it and every other segment type to Media3's DefaultHlsExtractorFactory, configured exactly as before. A second audio language is still collapsed by Media3's HLS audio mapping; out of scope here.
# Conflicts: # app/src/main/kotlin/com/arflix/tv/ui/screens/tv/live/LiveTvScreen.kt
|
Thanks for this, it's a useful Live TV improvement, and the playlist/guide fixes plus emulator testing are appreciated. CI is green and the branch merges cleanly, but I found a few cases to address before merging:
These are code-review findings; I haven't independently tested this build on a physical TV. The feature is worth keeping, but these cases need coverage before calling it fully ready. |
- DVB subtitle track ids in HLS no longer come from the PID. The id is derived from the subtitle service itself (language, subtitling type, composition/ancillary page ids from its descriptor; its position among the program's subtitle streams when it has none), so a rendition switch or discontinuity that carries the same service on another PID keeps the same track id instead of being discarded by the HLS sample-stream wrapper. - The profile's Default subtitle is applied fully: Off disables text tracks, Forced selects only forced tracks, a language selects that language. Every case sets the text preferences explicitly, so the device caption settings (language and caption roles) no longer turn subtitles on or pick another language. The Home channel preview uses the same rules; trailers get the player's own defaults back. - Languages resolve through the app's mapping, now shared with the VOD player (util/LanguageCodes.kt, moved unchanged from PlayerViewModel), so "Portuguese (Brazil)" and regional tags such as pt-BR work. - The track picker opens scrolled to the selected row and requests focus once that row is laid out; a selection below the first screen used to leave focus behind the overlay. - When time, playback controls and actions cannot share one line, the actions take a line of their own above the controls (wrapping further if needed) instead of being drawn over them. Tests: rendition switch with different PIDs, repeated program tables, Off/Forced/language/pt-BR defaults against device caption settings, and control-bar placement (unit); a long track list and every HUD button shown in catch-up mode at narrow and TV widths (device).
|
Thanks for the thorough review. All four points are fixed in b5e5084 (the branch is also merged with current
Unit tests pass; the new device tests were run on an Android TV emulator (API 30). I also checked on-device: subtitle selection on a channel carrying two DVB subtitle languages, and the TV-width control bar on a real channel. |
Summary
Live TV subtitles and audio, plus IPTV fixes found while testing them on real playlists.
Live TV: subtitle and audio tracks
Muxed subtitles were invisible on some channels
CODECS, which names only video and audio, so subtitles muxed into the TS segments never appeared. Media3 falls back to reading a segment when a variant lists two audio codecs, so channels of one provider had subtitles or not depending on their audio count.Every DVB subtitle language on IPTV HLS channels
TsExtractorkeys tracks by stream type and keeps only the lowest PID, so only the first subtitle language ever appeared — picked by stream order, not by the user's language.src/main/iptvts-java, same pattern as the vendored Matroska extractor) whose only change gives each DVB subtitle PID its own HLS track id.IptvHlsExtractorFactoryroutes MPEG-TS segments to it and every other segment type to Media3'sDefaultHlsExtractorFactory, configured exactly as before.Stalled live streams
Full-screen controls
Guide missing for playlists that declare their own XMLTV
A plain M3U whose guide is only named in its
#EXTM3U url-tvg="..."line showed "No guide data matched" on every channel:The saved address is now restored on those paths; when none was saved the playlist header is read once per session; a declared guide counts as an XMLTV source; and for lists up to 10,000 channels one download fills the whole guide.
Pasted addresses with invisible characters
.../list.m3u%00and the server answered HTTP 400. Playlist, guide and Stalker portal/MAC input now drop control and invisible format characters before use, which also repairs addresses already saved.Favorite TV row after switching playlists
Notes
Testing
./gradlew :app:testSideloadDebugUnitTestpasses. New tests:LiveSubtitlesTest,IptvTsSubtitleTracksTest(two DVB languages become two tracks; stock extractor gives one),HudControlBarTest,IptvDeclaredGuideRestoreTest,IptvInputSanitizingTest, additions toLiveTvRetryPolicyTest,LiveTvGuideSourcesTestandFavoriteTvGuideRefreshTest.main, then with this branch a clean state (no saved guide data, nothing typed in settings) filled the guide for every channel from one download, and it survived a restart;