Search code examples
flutteraudiojust-audio

How to play one audio right after another in flutter?


I have like 10 - 15 audio, and I need to play them one after another or you can say merge them. They are dynamic(I get the urls from server). I'm using the just_audio packege for playing audio. I'm using ConcatenatingAudioSource to play one audio after another

This is how I initialize the player

late AudioPlayer _audioPlayer;
  List<AudioPlayer> players = [];
  ConcatenatingAudioSource concatenatingAudioSource =
      ConcatenatingAudioSource(children: []);

@override
  void initState() {
    super.initState();
    WidgetsBinding.instance.addPostFrameCallback((timeStamp) {
      final state = ref.watch(homeController);
      state.ayahList.forEach((element) async {
        final player = AudioPlayer();
        await player.setUrl('https://example.com/$element.mp3');
        players.add(player);
      });
      final audioSources = players
          .map((player) => player.audioSource ?? AudioSource.uri(Uri()))
          .toList();
      concatenatingAudioSource =
          ConcatenatingAudioSource(children: audioSources);
      _audioPlayer = AudioPlayer()..setAudioSource(concatenatingAudioSource);
    });
  }

This is the UI, it's very simple

@override
  Widget build(BuildContext context) {
    return StreamBuilder(
        stream: audioPlayer.playerStateStream,
        builder: (context, snapshot) {
          final playerState = snapshot.data;
          final processingState = playerState?.processingState;
          final playing = playerState?.playing;
          if (!(playing ?? false)) {
            return IconButton(
                onPressed: () => audioPlayer.play(),
                icon: const Icon(Icons.play_arrow_rounded));
          } else if (processingState != ProcessingState.completed) {
            return IconButton(
                onPressed: () => audioPlayer.pause(),
                icon: const Icon(Icons.pause_rounded));
          }
          return const Icon(Icons.play_arrow_rounded);
        });
  }

Now when I click the play button, nothing happens, nothing on the log as well. Maybe I got the whole wrong idea about concatenatingAudioSource, I don't know. Please help me


Solution

  • I figured out another way to play one audio after another

    onPressed: () {
                  audioPlayer.setUrl(
                      'https:example.com/${state.ayahList[i-1]}.mp3');
                  audioPlayer.play();
    
                  audioPlayer.playerStateStream.listen((event) async {
                    if (event.processingState == ProcessingState.completed) {
                      if (i < state.ayahList.length) {
                        audioPlayer.setUrl(
                            'https://example.com/${state.ayahList[i]}.mp3');
                        await audioPlayer.play().then((value) => i++);
    
                      } else {
                        i = 0;
                      }
                    }
                  });
                },