fix(android): derive the mpv fallback passthrough list from the audio route
Audio passthrough defaults on for Android TV, scoped to ExoPlayer because mpv force-passes through every codec named in audio-spdif and has no decode fallback. That scoping did not survive the ExoPlayer to mpv handoff: PlayerAndroid queued the raw ac3,eac3,dts,dts-hd,truehd list as a pending mpv property and prepareMpvFallback replayed it verbatim, so a sink that bitstreams only Dolby formats was told to force TrueHD and DTS-HD anyway. mpv selected spdif_truehd, the audio output never initialised, and playback froze at its start position while still showing a first frame — the stop timeline reported the position it opened with. Treat passthrough as a request and resolve the codec list against the route when mpv actually starts, so an HDMI or AVR change between ExoPlayer startup and the handoff cannot replay codecs from the old sink. Gate each codec on the exact advertised encoding rather than media3's passthrough probe: that probe answers DTS-HD by downgrading to the DTS core, and mpv reads "dts,dts-hd" as "dts-hd" alone, so accepting the downgrade would name DTS-HD MA to a core-only receiver and lose DTS too.
This commit is contained in:
@@ -192,6 +192,40 @@ void main() {
|
||||
);
|
||||
});
|
||||
|
||||
test('ExoPlayer leaves the mpv passthrough codec list to the native fallback', () async {
|
||||
final calls = <MethodCall>[];
|
||||
await withMockPlayerChannels(
|
||||
methodChannelName: 'com.plezy/exo_player',
|
||||
eventChannelName: 'com.plezy/exo_player/events',
|
||||
methodHandler: (call) async {
|
||||
calls.add(call);
|
||||
if (call.method == 'initialize') return true;
|
||||
if (call.method == 'requestAudioFocus') return true;
|
||||
return null;
|
||||
},
|
||||
testBody: () async {
|
||||
final player = PlayerAndroid();
|
||||
try {
|
||||
expect(await player.requestAudioFocus(), isTrue);
|
||||
await player.setAudioPassthrough(true);
|
||||
|
||||
final passthrough = calls.singleWhere((call) => call.method == 'setAudioPassthrough');
|
||||
expect((passthrough.arguments as Map)['enabled'], isTrue);
|
||||
// mpv force-passthroughs audio-spdif with no decode fallback, so the
|
||||
// plugin derives it from the audio route instead (#1703).
|
||||
expect(
|
||||
calls.where(
|
||||
(call) => call.method == 'setMpvProperty' && (call.arguments as Map)['name'] == 'audio-spdif',
|
||||
),
|
||||
isEmpty,
|
||||
);
|
||||
} finally {
|
||||
await player.dispose();
|
||||
}
|
||||
},
|
||||
);
|
||||
});
|
||||
|
||||
test('ExoPlayer retries initialization after a recoverable native failure', () async {
|
||||
var initializeAttempts = 0;
|
||||
await withMockPlayerChannels(
|
||||
|
||||
Reference in New Issue
Block a user