audioplayers
audioplayers copied to clipboard
AudioPlayer problems after disposed.
Using v0.18.3 I have the following class:
import 'package:audioplayers/audio_cache.dart';
import 'package:audioplayers/audioplayers.dart';
import 'package:adeptutils/adeptutils.dart';
import 'package:my_app/src/res/res.dart' as R;
import 'package:assets_audio_player/assets_audio_player.dart';
class AudioUtils {
AssetsAudioPlayer _webAudioPlayer;
AudioCache _mobilePlayer;
static final _soundParentPath =
"${R.sounds.rootFolder}${R.sounds.soundsFolder}";
final _scanSound = Audio("$_soundParentPath${R.sounds.scan}");
final _successSound = Audio("$_soundParentPath${R.sounds.success}");
final _errorSound = Audio("$_soundParentPath${R.sounds.error}");
AudioUtils(){
if(PlatformUtils.isWeb) _webAudioPlayer = AssetsAudioPlayer();
if(PlatformUtils.isMobile){
AudioPlayer audioPlayer = AudioPlayer(mode: PlayerMode.LOW_LATENCY);
audioPlayer.setReleaseMode(ReleaseMode.STOP);
_mobilePlayer =
AudioCache(fixedPlayer: audioPlayer, prefix: _soundParentPath, duckAudio: true);
_mobilePlayer.loadAll([R.sounds.scan, R.sounds.success, R.sounds.error]);
}
}
Future<void> onScan() async {
_webAudioPlayer?.open(_scanSound);
_mobilePlayer?.play(R.sounds.scan);
}
Future<void> onSuccess() async {
_webAudioPlayer?.open(_successSound);
_mobilePlayer?.play(R.sounds.success);
}
Future<void> onError() async {
_webAudioPlayer?.open(_errorSound);
_mobilePlayer?.play(R.sounds.error);
}
onDestroy() {
_webAudioPlayer?.dispose();
_mobilePlayer?.fixedPlayer?.dispose();
}
}
The first time I use an AudioUtils object everything works fine, but when I call onDestroy() (let's say the user leaved the screen where the AudioUtils object was used) and then I use another instance of AudioUtils then anytime I play a sound this Exception is thrown:
[ +148 ms] I/flutter (15113): ══╡ EXCEPTION CAUGHT BY FLUTTER FRAMEWORK ╞═════════════════════════════════════════════════════════
[ ] I/flutter (15113): The following StateError was thrown:
[ ] I/flutter (15113): Bad state: Cannot add new events after calling close
[ ] I/flutter (15113):
[ ] I/flutter (15113): When the exception was thrown, this was the stack:
[ ] I/flutter (15113): #1 AudioPlayer.state= (package:audioplayers/audioplayers.dart:190:28)
[ ] I/flutter (15113): #2 AudioPlayer.play (package:audioplayers/audioplayers.dart:354:7)
[ ] I/flutter (15113): <asynchronous suspension>
[ ] I/flutter (15113): #3 AudioCache.play (package:audioplayers/audio_cache.dart:125:5)
[ ] I/flutter (15113): <asynchronous suspension>
[ ] I/flutter (15113): (elided one frame from dart:async)
[ ] I/flutter (15113): ════════════════════════════════════════════════════════════════════════════════════════════════════
I assume that disposing an audioplayer and creating a new instance should work just fine, so why this exception is thrown?
Are you sure you are creating a new instance of AudioUtils when you go back to the screen? You are probably re-using the same instance and thus not re-creating the disposed player.
200% sure
I guess there might be a race condition if you don't await all calls to AudioCache and/or AudioPlayer. AudioCache first loads the resource and then plays it. If you call AudioPlayer.dispose() while the resource is still loading, the following call to play() might cause the error because AudioPlayer is already disposed. Maybe AudioPlayer should just ignore calls to play() when it is disposed...
Can you confirm with audioplayers: ^1.1.0 ? There were many improvements since then. Maybe it was solved?
I will test it
Still not tested, marking as stale again :)
No longer seems to be relevant. Closing :)