diff --git a/docs/audio-switching-notes.md b/docs/audio-switching-notes.md index 8bef9e0..4ad783e 100644 --- a/docs/audio-switching-notes.md +++ b/docs/audio-switching-notes.md @@ -6,17 +6,21 @@ Referencia interna para futuras correcciones del reproductor de PluriWave. Este - `AudioPlayer.play()` **no debe esperarse como si fuera “arrancar y terminar”** en un stream de radio en vivo. Según la documentación de `just_audio`, el `Future` de `play()` completa cuando la reproducción termina, se pausa o se detiene. En una radio en vivo puede quedar vivo hasta que otra acción lo interrumpa. - Para streams en vivo, la UI debe depender de `playerStateStream`: `loading`/`buffering` para spinner, `ready + playing` para estado en directo. -- El ejemplo de radio de `just_audio` configura `AudioSession` y escucha errores de playback. Conviene tratar el cambio de emisora como una operación transaccional: parar fuente anterior, asignar fuente nueva y arrancar sin bloquear el flujo principal. +- El ejemplo de radio de `just_audio` configura sesión de audio y escucha errores de playback. Conviene tratar el cambio de emisora como una operación transaccional: parar fuente anterior, asignar fuente nueva y arrancar sin bloquear el flujo principal. - En `audio_service`, si se cambia de fuente desde `playMediaItem`, hay que evitar que errores tardíos de la fuente anterior limpien la emisora nueva. Es una carrera típica cuando se hace `stop()` y enseguida se carga otro stream. ## Decisión aplicada en PluriWave -- Serializar cambios de emisora con una cola interna. +- Mantener `setUrl(...)` porque era la ruta que conectaba correctamente la primera emisora en esta app. +- Serializar cambios de emisora con una cola interna para que no se solapen `stop/setUrl/play`. - Usar una revisión incremental para que solo la última solicitud pueda actualizar estado/errores. -- Usar `setAudioSource(..., preload: false)` y luego `play()` sin `await`, para que la carga de stream vivo no bloquee la operación. -- Ignorar errores emitidos durante la ventana de cambio de fuente, porque pueden pertenecer al stream anterior. +- Ejecutar `play()` sin `await`, porque en radios en vivo su `Future` no representa “ya arrancó”, sino “terminó/pausó/detuvo”. - Proteger `EstadoRadio.reproducir` con revisión para que una reproducción vieja que termine tarde no aplique presets/clicks encima de la emisora nueva. +## Intento descartado + +- Se probó `setAudioSource(..., preload: false)` siguiendo una interpretación más transaccional del API, pero en PluriWave rompió incluso la primera conexión. Queda descartado salvo que se acompañe de logs nativos que justifiquen retomarlo. + ## Fuentes consultadas - just_audio `AudioPlayer.play()` API: https://pub.dev/documentation/just_audio/latest/just_audio/AudioPlayer/play.html diff --git a/lib/servicios/servicio_audio.dart b/lib/servicios/servicio_audio.dart index 487b94a..d2e5939 100644 --- a/lib/servicios/servicio_audio.dart +++ b/lib/servicios/servicio_audio.dart @@ -1,7 +1,6 @@ import 'dart:async'; import 'dart:developer' as developer; -import 'package:audio_session/audio_session.dart'; import 'package:audio_service/audio_service.dart'; import 'package:just_audio/just_audio.dart'; @@ -97,7 +96,6 @@ class PluriWaveAudioHandler extends BaseAudioHandler with SeekHandler { final AndroidEqualizer _eq = AndroidEqualizer(); late final AudioPlayer _player = AudioPlayer( - userAgent: 'PluriWave/0.1.0 (es.freetimelab.pluriwave)', audioPipeline: AudioPipeline(androidAudioEffects: [_eq]), ); @@ -117,23 +115,9 @@ class PluriWaveAudioHandler extends BaseAudioHandler with SeekHandler { bool _cambiandoFuente = false; PluriWaveAudioHandler() { - unawaited(_configurarSesionAudio()); _setupStreams(); } - Future _configurarSesionAudio() async { - try { - final session = await AudioSession.instance; - await session.configure(const AudioSessionConfiguration.music()); - } catch (e) { - developer.log( - '[PluriWave] No se pudo configurar AudioSession: $e', - name: 'ServicioAudio', - level: 800, - ); - } - } - void _setupStreams() { _player.playerStateStream.listen((state) { final playing = state.playing; @@ -268,12 +252,7 @@ class PluriWaveAudioHandler extends BaseAudioHandler with SeekHandler { await _player.stop().timeout(_timeoutCambioFuente); if (revision != _revisionFuente) return; - await _player - .setAudioSource( - AudioSource.uri(Uri.parse(mediaItem.id), tag: mediaItem), - preload: false, - ) - .timeout(_timeoutCambioFuente); + await _player.setUrl(mediaItem.id).timeout(_timeoutCambioFuente); if (revision != _revisionFuente) return; await _activarEcualizador();