Skip to content

fix: play the correct default subtitle/audio track with multiple defaults#1044

Open
aviadlevy wants to merge 1 commit into
DonutWare:developfrom
aviadlevy:fix/subtitle-audio-default-track-race
Open

fix: play the correct default subtitle/audio track with multiple defaults#1044
aviadlevy wants to merge 1 commit into
DonutWare:developfrom
aviadlevy:fix/subtitle-audio-default-track-race

Conversation

@aviadlevy

Copy link
Copy Markdown
Contributor

Pull Request Description

At playback start, setSubtitleTrack / setAudioTrack (in LibMPV) ran before media_kit had finished parsing the file's tracks — open() returns before the mpv track-list observer fires. Both wrappers map the wanted Jellyfin stream to a player track by list position, so while the track list is still empty the lookup resolves to null and the selection is silently skipped. mpv then keeps the track it auto-selected on load — its first default-flagged track — which is wrong whenever a file has multiple default tracks (e.g. Jellyfin's smart subtitle selection picks the 2nd default).

This is exactly why the in-player UI showed the correct track while a different one actually played, and why re-selecting the same track fixed it (by then the track list had been parsed).

Fix

lib/wrappers/players/lib_mpv.dart: before mapping the wanted stream to a player track, wait for that track to appear on player.stream.tracks. The wait:

  • only fires when the track isn't present yet — already-loaded selections (manual re-selects, transcode) hit the fast path with zero added latency;
  • doesn't affect video load time — the video is already playing (play: true), only the track application waits, and only until mpv finishes parsing (tens of ms);
  • is race-free — Dart is single-threaded, so firstWhere subscribes synchronously before any track-list observer callback can run;
  • is capped at 5s as a pure safety net, and is skipped for external subtitles (that path is unchanged).

Applied to both subtitle and audio selection. The libMDK wrapper has the same latent race but is intentionally left out of scope to keep the diff minimal.

AI assistance

Root-cause investigation and the patch were done with Claude Code. The diagnosis — traced through the vendored DonutWare media_kit fork to confirm open() returns before track parsing and that Tracks.subtitle defaults to [auto, no] — the fix design, and on-device validation were human-reviewed and -owned.

Issue Being Fixed

Resolves #1031 — when a file has multiple subtitle tracks marked as default, the UI selects the correct one but playback uses the first default track instead.

Screenshots / Recordings

Tested On

  • Android — installed the dev build on a physical device; confirmed the correct (non-first) default subtitle track now plays from the start without needing to re-select it.
  • Android TV — uses the native ExoPlayer path (selection by index, not the positional remap), so it isn't affected by this bug.
  • iOS
  • Linux — same LibMPV code path as Android; not separately re-tested but covered by the same fix.
  • Windows
  • macOS
  • Web

Checklist

  • If a new package was added, did you ensure it works for all supported platforms? — no new packages.
  • Check that any changes are related to the issue at hand.

At playback start setSubtitleTrack/setAudioTrack ran before media_kit
finished parsing the file's tracks (open() returns before the track-list
observer fires), so the positional remap resolved to null and the
selection was silently skipped. mpv then kept its own default pick, which
is wrong when a file has multiple default tracks.

Wait for the wanted embedded track to appear on the tracks stream before
mapping. The wait only fires when the track is not yet present, is
race-free, and is capped at 5s, so already-loaded and external cases are
unchanged.

Fixes DonutWare#1031
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Incorrect subtitle track played when file has multipe default tracks

1 participant