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



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

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

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

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

(对于v0.18和更高版本,您不再调用start,而是用audioHandler.替换AudioService.)

在你的后台音频任务(v0.17)或音频处理程序(v0.18)中,你想要字段来存储你的播放器和队列:

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

onStart(v0.17)或您的音频处理程序构造函数(v0.18)不需要做任何事情,除了您想要在播放器上做的任何初始化,例如为事件注册侦听器(例如侦听当前播放的音频何时完成,以便您可以调用skipToNext())。您应该按照以下方式实现updateQueue的回调:

// 0.17 solution:
Future<void> onUpdateQueue(List<MediaItem> queue) =>
await AudioServiceBackground.setQueue(_queue = queue);
// 0.18 solution:
Future<void> updateQueue(List<MediaItem> newQueue) async {
queue.add(_queue = newQueue);
await super.updateQueue(newQueue);
}

对于play回调:

// 0.17 solution:
Future<void> onPlay() => _player.play();
// 0.18 solution:
Future<void> play() => _player.play();

您还需要实现skipToQueueItem回调:

// 0.17 solution:
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']);
}
// 0.18 solution
Future<void> skipToQueueItem(index) async {
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),
);
queue.add(_queue);
}
await mediaItem.add(_queue[index]);
// load URL into player
await _player.setUrl(_queue[index].extras['url']);
}

skipToNext/skipToPrevious回调函数的默认实现是这样定义的。

由于您的API调用根据需要分别加载每个URL,这将在每首歌曲之间创建一个间隙。just_audio可以支持无间隙播放,如果你可以堆叠多个url提前。

相关内容

  • 没有找到相关文章