mirror of
https://github.com/R0m1k3/xtremobile.git
synced 2026-10-11 17:29:26 +02:00
feat: add audio track cycling and force lavc downmix fix
This commit is contained in:
1 parent
123a49cfa6
commit
c7be0bae52
1 file changed
+47
-15
@@ -185,35 +185,34 @@ class _NativePlayerScreenState extends ConsumerState<NativePlayerScreen>
|
|||||||
'decoder+vo'); // Allow frame drops at decoder and video output
|
'decoder+vo'); // Allow frame drops at decoder and video output
|
||||||
|
|
||||||
// ============ AUDIO CODEC SUPPORT FOR VOD ============
|
// ============ AUDIO CODEC SUPPORT FOR VOD ============
|
||||||
// Reverted to safer defaults for Android TV
|
// V3: Explicit LAVC Downmix & Audiotrack
|
||||||
|
|
||||||
// Ensure audio is NOT muted
|
// Ensure audio is NOT muted
|
||||||
(_player.platform as dynamic)?.setProperty('mute', 'no');
|
(_player.platform as dynamic)?.setProperty('mute', 'no');
|
||||||
|
|
||||||
// Force software audio decoding for maximum compatibility (AC3/DTS/EAC3)
|
// Explicitly enable LAVC downmixing to stereo (Crucial for 5.1/7.1 on Stereo devices)
|
||||||
// Hardware decoding of audio often fails on Fire TV
|
(_player.platform as dynamic)?.setProperty('ad-lavc-downmix', 'yes');
|
||||||
(_player.platform as dynamic)?.setProperty('ad', 'lavc:*');
|
|
||||||
|
|
||||||
// Audio configuration - Safe Stereo
|
|
||||||
(_player.platform as dynamic)?.setProperty('audio-channels', 'stereo');
|
(_player.platform as dynamic)?.setProperty('audio-channels', 'stereo');
|
||||||
(_player.platform as dynamic)
|
(_player.platform as dynamic)
|
||||||
?.setProperty('audio-normalize-downmix', 'yes');
|
?.setProperty('audio-normalize-downmix', 'yes');
|
||||||
|
|
||||||
// LET MPV DECIDE OUTPUT (Removing explicit 'ao')
|
// Force software decoding for audio tracks (Maximum compatibility)
|
||||||
// Removing explicit 'aid=1' (Default requires auto)
|
(_player.platform as dynamic)?.setProperty('ad', 'lavc:*');
|
||||||
|
|
||||||
// Track Selection - Auto (Safest)
|
// Use audiotrack (standard Android)
|
||||||
|
(_player.platform as dynamic)?.setProperty('ao', 'audiotrack');
|
||||||
|
|
||||||
|
// Track Selection - Auto
|
||||||
(_player.platform as dynamic)?.setProperty('aid', 'auto');
|
(_player.platform as dynamic)?.setProperty('aid', 'auto');
|
||||||
(_player.platform as dynamic)?.setProperty('alang', 'fr,fra,fre,en,eng');
|
(_player.platform as dynamic)?.setProperty('alang', 'fr,fra,fre,en,eng');
|
||||||
|
|
||||||
// Volume
|
// Volume & Sync
|
||||||
(_player.platform as dynamic)?.setProperty('volume', '100');
|
(_player.platform as dynamic)?.setProperty('volume', '100');
|
||||||
|
// Slightly larger buffer for software decoding
|
||||||
// Sync settings
|
(_player.platform as dynamic)?.setProperty('audio-buffer', '0.25');
|
||||||
(_player.platform as dynamic)?.setProperty('audio-buffer', '0.2');
|
|
||||||
(_player.platform as dynamic)?.setProperty('video-sync', 'audio');
|
(_player.platform as dynamic)?.setProperty('video-sync', 'audio');
|
||||||
|
|
||||||
debugPrint('MediaKitPlayer: Audio SAFE configuration applied');
|
debugPrint('MediaKitPlayer: Audio V3 (Downmix) configuration applied');
|
||||||
|
|
||||||
_controller = VideoController(_player);
|
_controller = VideoController(_player);
|
||||||
|
|
||||||
@@ -761,10 +760,12 @@ class _NativePlayerScreenState extends ConsumerState<NativePlayerScreen>
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Down Arrow - Next channel (Live only)
|
// Down Arrow - Next channel (Live) or Cycle Audio (VOD)
|
||||||
if (key == LogicalKeyboardKey.arrowDown) {
|
if (key == LogicalKeyboardKey.arrowDown) {
|
||||||
if (widget.streamType == StreamType.live && widget.channels != null) {
|
if (widget.streamType == StreamType.live && widget.channels != null) {
|
||||||
_playNext();
|
_playNext();
|
||||||
|
} else if (widget.streamType != StreamType.live) {
|
||||||
|
_cycleAudioTrack();
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@@ -783,6 +784,37 @@ class _NativePlayerScreenState extends ConsumerState<NativePlayerScreen>
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Future<void> _cycleAudioTrack() async {
|
||||||
|
final tracks = _player.state.tracks.audio;
|
||||||
|
if (tracks.isEmpty) {
|
||||||
|
if (mounted) {
|
||||||
|
ScaffoldMessenger.of(context).showSnackBar(
|
||||||
|
const SnackBar(
|
||||||
|
content: Text('Aucune piste audio détectée'),
|
||||||
|
duration: Duration(seconds: 1)),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
final current = _player.state.track.audio;
|
||||||
|
int currentIndex = tracks.indexOf(current);
|
||||||
|
int nextIndex = (currentIndex + 1) % tracks.length;
|
||||||
|
final nextTrack = tracks[nextIndex];
|
||||||
|
|
||||||
|
await _player.setAudioTrack(nextTrack);
|
||||||
|
|
||||||
|
if (mounted) {
|
||||||
|
ScaffoldMessenger.of(context).showSnackBar(
|
||||||
|
SnackBar(
|
||||||
|
content: Text(
|
||||||
|
'Audio: ${nextTrack.language ?? "inconnu"} (${nextTrack.title ?? nextTrack.id})'),
|
||||||
|
duration: const Duration(seconds: 2),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
final title = widget.channels != null && widget.channels!.isNotEmpty
|
final title = widget.channels != null && widget.channels!.isNotEmpty
|
||||||
|
|||||||
Reference in new issue
Block a user