flutterdartjust-audio

How to play two (or more) audio files simultaneously with just_audio and audio_service?


I tried reading through the project readme and issues on Github to see if it was a possibility to play two or more audio files simultaneously using the just_audio and audio_service plugins for Flutter. Has anyone achieved something similar using these plugins or similar ones? I currently use these plugins in production so it'd be preferable to stick with them to add the desired functionality to the app.

Any help would be greatly appreciated, thanks!


Solution

  • In just_audio, you can create two instances of AudioPlayer and set them to play different audio sources. e.g.

    final player1 = AudioPlayer();
    final player2 = AudioPlayer();
    
    await player1.setUrl(url1);
    await player2.setUrl(url2);
    ...
    player1.play(); // don't await
    player2.play(); // don't await
    

    If you await each play request, it would not start playing the second one until after waiting for the first one to finish playing. So by not awaiting, the second play request should be triggered within milliseconds after the first one, and both will play in parallel.

    If for any reason you need to wait until both players have finished playing, you can use Future.wait:

    await Future.wait([
      player1.play(),
      player2.play(),
    ]);
    print('done'); // this will print after both players are finished.
    

    (Extra example based on your comment) To loop player2 until player1 completes:

    await player2.setLoopMode(LoopMode.one);
    player2.play(); // don't await
    await player1.play(); // wait for player1 to complete
    await player1.pause(); // or stop or dispose
    await player2.pause(); // or stop or dispose
    

    Note that each player uses up native resources, which means two things:

    1. You may hit a resource limit if you create too many parallel instances.
    2. You should call dispose on each player once you're finished using it since this will free up those resources for use by other apps.

    On the audio_service side, you are basically implementing callbacks for what you want to happen when the user presses the play button, etc, and you can stick the above code into your callback. For example, if you want to play both players simultaneously when the user clicks "play", you would implement your callback like this:

    Future<void> play() async {
      player1.play();
      player2.play();
    }
    

    You could also implement the pause callback similarly:

    Future<void> pause() async {
      player1.pause();
      player2.pause();
    }