flutteraudiojust-audioaudio-service

How can I loop audio a custom number of times in a queue with just_audio in Flutter?


How to loop audio in a queue for a custom duration (e.g. N number of loops), then move to the next item in the queue which would also play on loop for N number of times.

For example, loop a short audio clip, of say 5 seconds length, for 15 seconds total (3 loops); then after move to the second item in the queue, say an audio clip of 30 seconds, which would loop for say 60 seconds (2 loops).

In my example code, I am using audio_service with just_audio to play the actual audio. I am setting the audio player to LoopMode.one (which loops indefinitely, as I am not sure how to set this to loop only N number of times).

class MyAudioHandler extends BaseAudioHandler {

  @override
  Future<void> play() async {
     setRepeatMode(AudioServiceRepeatMode.one);
    _audioPlayer.setLoopMode(LoopMode.one);
    _audioPlayer.play();
  }

  @override
  Future<void> addQueueItems(List<MediaItem> mediaItems) async {
    final audioSource = mediaItems.map(_createAudioSource);
    _playlist.addAll(audioSource.toList());
    final newQueue = queue.value..addAll(mediaItems);
    queue.add(newQueue);
    await _audioPlayer.setAudioSource(_playlist);
    setRepeatMode(AudioServiceRepeatMode.one);
  }

  UriAudioSource _createAudioSource(MediaItem mediaItem) {
    return AudioSource.asset(
     mediaItem.id,
      tag: mediaItem,
    );
  }

/// More code
}


And when I add an item to my queue, I set a custom duration to MediaItem (which is ignored).


                ElevatedButton(
                  onPressed: () async {
                    List<MediaItem> mediaItems = [
                      const MediaItem(
                        id: 'assets/audio/jingle.mp3',
                        title: 'jingle',
                          duration: Duration(seconds: 15)
                      ),
                      const MediaItem(
                        id: 'assets/audio/jazz.mp3',
                        title: 'jazz',
                          duration: Duration(seconds: 30)
                      ),
                    ];
                    getIt<AudioHandler>().addQueueItems(mediaItems);
                  },
                  child: const Text('Add to queue'),
                ),


Solution

  • This answer focuses on how to loop and sequence in just_audio.

    The following code prepares a playlist that will play jingle.mp3 3 times and then play jazz.mp3 2 times:

    _playlist.addAll([
      LoopingAudioSource(count: 3, child: AudioSource.asset('assets/audio/jingle.mp3')),
      LoopingAudioSource(count: 2, child: AudioSource.asset('assets/audio/jazz.mp3')),
    ]);
    

    Since the looping is built into the specification of the playlist, you should not set any loop mode on the player. Let the playlist play normally according to its specification.

    Another way to achieve the same effect is to just insert multiple copies of the same audio source into the playlist:

    _playlist.addAll([
      AudioSource.asset('assets/audio/jingle.mp3'),
      AudioSource.asset('assets/audio/jingle.mp3'),
      AudioSource.asset('assets/audio/jingle.mp3'),
      AudioSource.asset('assets/audio/jazz.mp3'),
      AudioSource.asset('assets/audio/jazz.mp3'),
    ]);
    

    Or with collection loops:

    _playlist.addAll([
      for (var i = 0; i < 3; i++) AudioSource.asset('assets/audio/jingle.mp3'),
      for (var i = 0; i < 2; i++) AudioSource.asset('assets/audio/jazz.mp3'),
    ]);