fix(eq): re-apply equalizer when the native audio session rotates
ExoPlayer assigns a new audio session id after transient audio-focus interruptions (navigation prompts, radar warnings), leaving the AndroidEqualizer attached to the dead session so playback resumed without equalization until the next station switch. The session-id listener now detects genuine rotations through a dedicated guard and re-activates the equalizer with the current preset, gated on EQ availability to stay clear of player teardown/rebuild.
This commit is contained in:
@@ -3,6 +3,7 @@ import 'dart:developer' as developer;
|
||||
import 'dart:ui' show Locale;
|
||||
|
||||
import 'package:audio_service/audio_service.dart';
|
||||
import 'package:flutter/foundation.dart' show visibleForTesting;
|
||||
import 'package:just_audio/just_audio.dart';
|
||||
|
||||
import '../l10n/display_names.dart';
|
||||
@@ -159,6 +160,12 @@ class PluriWaveAudioHandler extends BaseAudioHandler
|
||||
StreamSubscription<int?>? _androidAudioSessionIdSub;
|
||||
final _androidAudioSessionIdController = StreamController<int?>.broadcast();
|
||||
int? _androidAudioSessionId;
|
||||
|
||||
/// Last session id processed for EQ re-apply purposes (Design "Change-guard
|
||||
/// field separate from broadcast field"). Kept apart from
|
||||
/// [_androidAudioSessionId] so external broadcast semantics on
|
||||
/// [androidAudioSessionIdStream] stay untouched by the EQ re-apply guard.
|
||||
int? _ultimaSessionIdEq;
|
||||
Future<void> _colaCambioFuente = Future<void>.value();
|
||||
int _revisionFuente = 0;
|
||||
|
||||
@@ -262,6 +269,14 @@ class PluriWaveAudioHandler extends BaseAudioHandler
|
||||
if (!_androidAudioSessionIdController.isClosed) {
|
||||
_androidAudioSessionIdController.add(sessionId);
|
||||
}
|
||||
if (debeReaplicarEcualizador(
|
||||
sessionId: sessionId,
|
||||
ultimaSessionIdEq: _ultimaSessionIdEq,
|
||||
eqDisponible: _eqDisponible,
|
||||
)) {
|
||||
_ultimaSessionIdEq = sessionId;
|
||||
unawaited(_activarEcualizador());
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@@ -502,6 +517,7 @@ class PluriWaveAudioHandler extends BaseAudioHandler
|
||||
_eq = AndroidEqualizer();
|
||||
_eqDisponible = false;
|
||||
_androidAudioSessionId = null;
|
||||
_ultimaSessionIdEq = null;
|
||||
_player = _crearPlayer();
|
||||
await _player.setVolume(_volumenEfectivo);
|
||||
_conectarStreamsPlayer();
|
||||
@@ -536,6 +552,19 @@ class PluriWaveAudioHandler extends BaseAudioHandler
|
||||
}
|
||||
}
|
||||
|
||||
/// Pure re-apply decision for a native session-id emission. No side effects.
|
||||
///
|
||||
/// Returns `true` when the native audio session id genuinely rotated
|
||||
/// mid-playback (audio-focus ducking by another app) and the equalizer is
|
||||
/// currently attached, meaning the caller should re-attach the EQ and
|
||||
/// re-push the current preset's gains via [_activarEcualizador].
|
||||
@visibleForTesting
|
||||
static bool debeReaplicarEcualizador({
|
||||
required int? sessionId,
|
||||
required int? ultimaSessionIdEq,
|
||||
required bool eqDisponible,
|
||||
}) => sessionId != null && sessionId != ultimaSessionIdEq && eqDisponible;
|
||||
|
||||
/// Aplica un preset al ecualizador nativo Android.
|
||||
Future<void> aplicarPreset(PresetEcualizador preset) async {
|
||||
_presetActual = preset;
|
||||
|
||||
Reference in New Issue
Block a user