fix(subtitles): match preferred language against track labels for untagged tracks#1324
fix(subtitles): match preferred language against track labels for untagged tracks#1324anikettuli wants to merge 2 commits into
Conversation
…agged tracks Embedded subtitle tracks in MKV files frequently carry no ISO language tag — format.language arrives as null or "und" with the language only present in the track title (e.g. "English", "English [SDH]"). findPreferredSubtitleTrackIndex matched exclusively on the language tag, so for these files the preferred-language lookup always failed, the auto-selection left ExoPlayer's container-default track active, and users saw Arabic/Italian/Spanish/Portuguese subtitles even though an English track existed. Two changes: - When no track matches a target by language tag, fall back to matching the track label through the same normalizeLanguageCode path, restricted to tracks whose tag is null/blank/"und" so a usable foreign tag can never be hijacked by a coincidental label. - When neither pass matches anything, explicitly disable the text track instead of leaving the container-default selection showing a language the user never asked for. New unit test PlayerTrackSelectionTest covers tag matching (639-1, 639-2, regional), the null/"und" label fallback, suffixed labels, tag-over-label precedence, foreign-tag protection, and secondary target fallback. The null/"und" cases fail against the previous implementation. Fixes NuvioMedia#1197 Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
There was a problem hiding this comment.
Pull request overview
Note
Copilot was unable to run its full agentic suite in this review.
Adds label-based subtitle track matching when language tags are missing/unknown, plus adjusts runtime subtitle deselection behavior and introduces targeted tests.
Changes:
- Add label fallback matching in
findPreferredSubtitleTrackIndexwhen a track has no usable language tag (null /und). - Add common tests covering ISO tags, regional variants, and label fallback behavior.
- Simplify runtime deselection logic when no preferred subtitle track is found.
Reviewed changes
Copilot reviewed 3 out of 3 changed files in this pull request and generated 1 comment.
| File | Description |
|---|---|
| composeApp/src/commonTest/kotlin/com/nuvio/app/features/player/PlayerTrackSelectionTest.kt | Adds test coverage for subtitle preference matching, including label fallback cases. |
| composeApp/src/commonMain/kotlin/com/nuvio/app/features/player/PlayerTrackSelection.kt | Implements label fallback selection for tracks without a usable language tag. |
| composeApp/src/commonMain/kotlin/com/nuvio/app/features/player/PlayerScreenRuntimeTrackActions.kt | Changes when subtitles are deselected if no preferred track is found. |
|
Hi :) If you are going to change things here, pleace check how we detect brazilian and latin american subtitles in the TV version. This is still missing in mobile and would be good to have it here |
…419 tracks
Embedded tracks tagged with a bare "pt" or "es" often carry the
regional variant only in their name or track id ("Português (Brasil)",
"Español (Latinoamérica)"). Subtitle selection now derives an
effective variant from those fields using the same tag lists as the
TV app, so pt-BR and es-419 preferences can find their tracks.
Regional pairs are matched exactly, also mirroring TV: a "pt"
preference no longer selects a Brazilian track and "es" no longer
selects a Latin American one, nor the reverse.
normalizeLanguageCode additionally recognizes the accented
"português" / "español" spellings that real-world track labels use;
the unaccented checks missed them, which also broke the label
fallback for untagged Brazilian tracks.
Requested by review on the PR for cross-app consistency with NuvioTV.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
|
@skoruppa Done in e71e337 — ported the TV detection into this PR. Tracks tagged with a bare On a separate note — I know it's unrelated, but I've been mistagged as |
Summary
Embedded subtitle tracks in MKV files frequently carry no ISO language tag —
format.languagearrives as null or"und"with the language only present in the track title (e.g. "English", "English [SDH]"). The preferred-language auto-selection matched exclusively on the language tag, so for these files the lookup always failed, ExoPlayer's container-default track stayed active, and users saw Arabic/Italian/Spanish/Portuguese subtitles even though an English track existed.PR type
Why
The root cause was reproduced with a failing unit test before writing the fix:
findPreferredSubtitleTrackIndexinPlayerTrackSelection.kthandles ISO 639-1/639-2 tags, regional variants, and even full language names in the language field — but returns -1 for tracks whose tag is null or"und", which is exactly how MKV muxers commonly ship embedded tracks.Two changes:
normalizeLanguageCode/languageMatchesPreferencepath. The fallback is restricted to tracks whose normalized tag is null or"und", so a track with a usable foreign tag can never be hijacked by a coincidental label.selectSubtitleTrack(-1)instead of leaving the container-default selection showing a language the user never asked for. This branch previously only fired for the FORCED preference.Interactions verified during review: persisted per-show track choices run first (
restorePersistedTrackPreferenceIfNeededsets the applied flag before this code executes) so they cannot be clobbered, and there is no automatic addon-subtitle apply at startup (bothsetSubtitleUrisites are explicit user actions) so the disable path cannot interfere with addon subtitles. One accepted edge: an untagged track labeled "Non-English parts only" would label-match an English preference — by convention that is an English forced-narrative track, so selecting it over nothing is reasonable.Issue or approval
Fixes #1197
UI / behavior impact
Policy check
CONTRIBUTING.md.Scope boundaries
languageMatchesPreferenceitself is unchanged — the fallback lives only in subtitle track selection.Testing
./gradlew :composeApp:compileFullDebugKotlinAndroidpasses clean../gradlew :composeApp:testFullDebugUnitTestpasses.New unit test
PlayerTrackSelectionTest(10 cases): ISO 639-1/639-2/regional tag matching as regression guards, the null and"und"label-fallback cases (these fail against the previous implementation), suffixed labels ("English [SDH]"), tagged-track-wins-over-label-only precedence, foreign-tag protection against coincidental labels, no-match returns -1, and secondary-target fallback.Manual (please verify during review — needs a device):
Screenshots / Video (UI changes only)
Not a UI change.
Breaking changes
None.
Linked issues
Fixes #1197