fix(player): keep an explicit transcode subtitle choice through the deferred pass
Persist the choice before arming the deferred selection pass. The screen callback routes to onSubtitleTrackSelectedByUser, which invalidates the pending selection, so arming first retired the very listener that applies the choice once mpv discovers the sidecar. The existing test stubbed the persist callback and so could not observe the invalidation; it now routes through the manager like production does.
This commit is contained in:
@@ -15,8 +15,11 @@ Future<bool> deferTranscodeSubtitleSelection({
|
||||
}) async {
|
||||
final deferredTrack = PlaybackSubtitleResolver.subtitleTrackForSource(sourceTrack, sidecar: sourceSidecar);
|
||||
trackManager.preferredSubtitleTrack = deferredTrack;
|
||||
trackManager.applyTrackSelectionWhenReady();
|
||||
// Persist first: the screen callback routes to onSubtitleTrackSelectedByUser,
|
||||
// which invalidates the pending selection. Arming before that would retire the
|
||||
// deferred pass we depend on to apply this choice once mpv discovers the sidecar.
|
||||
await onSubtitleTrackChanged(deferredTrack, sourceStreamId: sourceStreamId);
|
||||
trackManager.applyTrackSelectionWhenReady();
|
||||
return shouldContinue();
|
||||
}
|
||||
|
||||
|
||||
@@ -654,6 +654,7 @@ void main() {
|
||||
onSubtitleTrackChanged: (track, {sourceStreamId}) async {
|
||||
persistedTrack = track;
|
||||
persistedSourceStreamId = sourceStreamId;
|
||||
await mgr.onSubtitleTrackSelectedByUser(track, sourceStreamId: sourceStreamId);
|
||||
},
|
||||
shouldContinue: () => true,
|
||||
);
|
||||
@@ -685,6 +686,78 @@ void main() {
|
||||
expect(player.selectedSubtitle.map((track) => track.id), ['native-0']);
|
||||
});
|
||||
|
||||
test('persisting a deferred transcode choice keeps the late-track pass armed', () async {
|
||||
await SettingsService.getInstance();
|
||||
final sourceTrack = MediaSubtitleTrack(
|
||||
id: 32,
|
||||
index: 0,
|
||||
languageCode: 'spa',
|
||||
title: 'Spanish',
|
||||
codec: 'srt',
|
||||
selected: false,
|
||||
forced: false,
|
||||
);
|
||||
final player = _FakePlayer(
|
||||
tracks: const Tracks(
|
||||
audio: [AudioTrack(id: 'audio', language: 'eng')],
|
||||
),
|
||||
);
|
||||
final mgr = _make(
|
||||
player: player,
|
||||
mediaInfo: MediaSourceInfo(
|
||||
videoUrl: 'https://example.com/transcode.m3u8',
|
||||
partId: 100,
|
||||
audioTracks: [MediaAudioTrack(id: 1, languageCode: 'eng', selected: true)],
|
||||
subtitleTracks: [sourceTrack],
|
||||
chapters: const [],
|
||||
),
|
||||
);
|
||||
addTearDown(mgr.dispose);
|
||||
|
||||
await deferTranscodeSubtitleSelection(
|
||||
trackManager: mgr,
|
||||
sourceTrack: sourceTrack,
|
||||
sourceSidecar: const PlaybackSubtitleSidecar(
|
||||
sourceStreamId: 32,
|
||||
preload: true,
|
||||
track: SubtitleTrack(
|
||||
id: 'container:32',
|
||||
language: 'spa',
|
||||
title: 'Spanish',
|
||||
codec: 'srt',
|
||||
isExternal: true,
|
||||
isContainer: true,
|
||||
uri: 'https://example.com/video.mkv',
|
||||
),
|
||||
),
|
||||
sourceStreamId: 32,
|
||||
onSubtitleTrackChanged: (track, {sourceStreamId}) =>
|
||||
mgr.onSubtitleTrackSelectedByUser(track, sourceStreamId: sourceStreamId),
|
||||
shouldContinue: () => true,
|
||||
);
|
||||
expect(player.selectedSubtitle, isEmpty);
|
||||
|
||||
player.emitTracks(
|
||||
const Tracks(
|
||||
audio: [AudioTrack(id: 'audio', language: 'eng')],
|
||||
subtitle: [
|
||||
SubtitleTrack(
|
||||
id: 'native-late',
|
||||
language: 'spa',
|
||||
title: 'Spanish',
|
||||
codec: 'srt',
|
||||
isExternal: true,
|
||||
isContainer: true,
|
||||
uri: 'https://example.com/video.mkv',
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
await _drainAsync();
|
||||
|
||||
expect(player.selectedSubtitle.map((track) => track.id), ['native-late']);
|
||||
});
|
||||
|
||||
test('five-second fallback keeps listening and applies a late advertised subtitle', () async {
|
||||
await SettingsService.getInstance();
|
||||
|
||||
|
||||
Reference in New Issue
Block a user