简体   繁体   中英

How to fetch song details every time from an API before playing in just_audio and audio_service

I want to use audio_service and just_audio to play audio in the background. But the problem is I have to set queue at the start with all metadata to make sure they run automatically even when the app is in background. But I don't have song URLs to play the song. Instead, I have a function which can be used to get song play URLs. Now I want to call that function every time to get song play URL and use that URL to play the song. I want to call that function in the code of AudioBackgroundService, not in the code of my flutter UI. Because if my UI is absent ie in the background then that function will not be called. So to make sure that function is called everytime it have to be in AudioServiceBackground code. Is there a way to do so? I'm using the same code provided in the audio_service documentation . I guess I have to use that function in onStart function of AudioService but I still can't figure the way out. Also, it will be much better if it can call that function for next song while playing the current one.

The URL is not required when setting the queue. You can set each MediaItem 's ID to your unique song ID, and amend this data later by storing the URL in the extras field when it becomes known.

First, I suggest this startup sequence:

await AudioService.start(backgroundTaskEntrypoint: _entrypoint);
await AudioService.updateQueue(songs);
AudioService.play();

In your background audio task, you would want fields to store your player and queue:

AudioPlayer _player = AudioPlayer();
List<MediaItem> _queue = [];

onStart doesn't need to do anything except any initialisation you want to do on your player, such as registering listeners for events (eg listen for when the currently playing audio completes so that you can call skipToNext() ). You should implement onUpdateQueue as follows:

Future<void> onUpdateQueue(List<MediaItem> queue) =>
  await AudioServiceBackground.setQueue(_queue = queue);

And onPlay :

Future<void> onPlay() => _player.play();

You will also want to implement onSkipToQueueItem :

Future<void> onSkipToQueueItem(String mediaId) async {
  final index = _queue.indexWhere((item) => item.id == mediaId);
  if (_queue[index].extras['url'] == null) {
    // fetch from your API and update queue
    _queue[index] = _queue[index].copyWith(
      extras: {'url': await fetchUrl(_queue[index].id),
    );
    await AudioServiceBackground.setQueue(_queue);
  }
  await AudioServiceBackground.setMediaItem(_queue[index]);
  // load URL into player
  await _player.setUrl(_queue[index].extras['url']);
}

The default implementations of onSkipToNext/onSkipToPrevious are defined in terms of this.

Since your API call loads each URL separately on demand, this will create a gap between each song. just_audio can support gapless playback if you can stack together multiple URLs in advance.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM