在 just_audio 和 audio_service 中播放之前如何每次从 API 中获取歌曲详细信息

时间:2021-02-11 12:49:18

标签: android flutter dart flutter-layout just-audio

我想使用 audio_servicejust_audio 在后台播放音频。但问题是我必须在开始时使用所有元数据设置队列,以确保即使在应用程序处于后台时它们也会自动运行。但我没有歌曲 URL 来播放这首歌。相反,我有一个可用于获取歌曲播放 URL 的函数。现在我想每次都调用该函数来获取歌曲播放 URL 并使用该 URL 播放歌曲。我想在 AudioBackgroundService 的代码中调用该函数,而不是在我的 flutter UI 代码中。因为如果我的 UI 不存在,即在后台,则不会调用该函数。所以要确保每次必须在 AudioServiceBackground 代码中调用该函数。有没有办法这样做?我正在使用 audio_service documentation 中提供的相同代码。我想我必须在 AudioService 的 onStart 函数中使用该函数,但我仍然找不到出路。另外,如果能在播放当前歌曲的同时为下一首歌曲调用该函数会更好。

1 个答案:

答案 0 :(得分:1)

设置队列时不需要 URL。您可以将每个 MediaItem 的 ID 设置为您唯一的歌曲 ID,稍后通过将 URL 存储在 extras 字段中来修改此数据。

首先,我建议这样启动顺序:

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

在您的后台音频任务中,您需要字段来存储您的播放器和队列:

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

onStart 除了您想在播放器上做的任何初始化之外,不需要做任何事情,例如注册事件的监听器(例如在当前播放的音频完成时监听,以便您可以调用 {{1 }})。您应该按如下方式实现 skipToNext()

onUpdateQueue

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

onPlay

您还需要实现 Future<void> onPlay() => _player.play();

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']); } 的默认实现是根据此定义的。

由于您的 API 调用按需分别加载每个 URL,这将在每首歌曲之间产生间隙。 just_audio 可以支持无缝播放,前提是你可以提前将多个 URL 叠加在一起。

相关问题