florent37 / Flutter-AssetsAudioPlayer

Play simultaneously music/audio from assets/network/file directly from Flutter, compatible with android / ios / web / macos, displays notifications
https://pub.dartlang.org/packages/assets_audio_player
Apache License 2.0
739 stars 336 forks source link

Android: restarting an audio track that's finished with LoopMode.none #361

Open andrewpmoore opened 3 years ago

andrewpmoore commented 3 years ago

Flutter Version

My version : 2.0.10

Lib Version

My version : Flutter 1.22.0-12.1.pre • channel beta

Platform (Android / iOS / web) + version

Platform : Android

Describe the bug

I'm playing 2 audio streams with 2 instances of assetsAudioPlayer (a voiceover and some music). The voiceover is set not to loop, but the music is.

When I stop the audio of both streams - by calling stop() on them both and then try to open and play them again I find that if the voice stream had finished, it won't start again, but the music will.

I've tried calling stop() and then play() and also pause() and then seek(Duration()) but once the voice stream has finished there seems no way to get it started again.

The only thing I've found that works is to dispose the wole assetAudioPlayer for the voice instance and then create it again. I'm not sure if it's a bug or whether something specific needs to be done once an audio track finishes to get it to play again.

Small code to reproduce


//I call these to start the music
_assetsAudioPlayerMusic.open(
        Audio.network(selectedMusic.url),
        autoStart: false,
        loopMode: LoopMode.single,
        volume: _musicVolume / 100,
      );

_assetsAudioPlayerVoice.open(
        Audio.network(selectedVoice.url),
        autoStart: false,
        volume: _voiceVolume / 100,
      );

//Listen for when both are ready
_subscriptionsVoice.add(_assetsAudioPlayerVoice.onReadyToPlay.listen((audio) async {
      _voiceReadToPlay = true;
      playIfAllReady();
    }));

_subscriptionsMusic.add(_assetsAudioPlayerMusic.onReadyToPlay.listen((audio) async {
      _musicReadyToPlay = true;
      playIfAllReady();
}));

  void playIfAllReady() {
if (_musicReadyToPlay && _voiceReadToPlay) {
      _assetsAudioPlayerMusic.play();
      _assetsAudioPlayerVoice.play();
}

//listening for the state of the players
_subscriptions.add(_assetsAudioPlayerMusic.currentPosition.listen((Duration position) {
     //the first play will play both and if stopped before the voice finishes, it'll start again with stop(), play()
         //but if the voice stream finishes, then it won't restart
         //the only thing I've found to do is dispose the audio player and create a new instance
            print(
          "musicVol: ${_assetsAudioPlayerMusic.volume.value}/${_assetsAudioPlayerMusic.isPlaying.value} voiceVol: ${_assetsAudioPlayerVoice.volume.value}/${_assetsAudioPlayerVoice.isPlaying.value}");
}));  
andrewpmoore commented 3 years ago

Just to follow up on this, it only seems to happen with m3u8 files. Once I changed to using an mp3 instead then it'll stop and restart correctly.