首页 > 解决方案 > 支持排队和多个播放列表的应用程序的 audio_service 和 just_audio 设计

问题描述

我正在使用 Flutter 和+组合为Koel构建一个移动应用程序。该应用程序基本上是这样工作的:audio_servicejust_audio

  1. 用户登录
  2. 应用从服务器加载大量 JSON 数据
  3. 应用程序将所述数据解析为歌曲、艺术家、专辑和播放列表
  4. 应用程序允许用户将歌曲添加到(顶部/底部/当前之后)/从队列中删除歌曲并播放或随机播放它们。整个应用程序中只有一个队列(即,如果用户在播放列表屏幕中按“全部播放”,队列的当前内容将被该播放列表中的歌曲替换)。
  5. 我在这里假设一个队列(List<Song>?)和一个ConcatenatingAudioSource应该总是在那里(尽管可以是空的),以便可以进行第 4 步

audio_service我一直在尝试使用and just_audio( )来实现第 4 步ConcatenatingAudioSource,但到目前为止还没有那么成功。本质上,我不清楚如何设计应用程序的架构。我是否需要检测队列并将其与andSong同步,如果是,如何?当用户从 UI 中删除歌曲小部件时,如何从队列和? 用户在播放列表屏幕中的歌曲小部件上点击“立即播放”的内容,在使播放器切换到该歌曲同时仍保持队列处于活动状态的情况下应该发生什么?audio_servicejust_audioSongMediaItemConcatenatingAudioSource

(可能值得一提的是,给出的示例audio_service非常基本,固定队列中有固定的歌曲列表,这与我的情况几乎不相似。此外,某些功能(例如,将歌曲排在当前歌曲之后) t 似乎可用,这意味着我必须依赖BackgroundAudioTask.onCustomAction,它只接受某些数据类型作为参数。MediaItem而且我的自定义Song模型对象似乎不受支持。)

标签: flutterjust-audioaudio-service

解决方案


我同意您保留单个ConcatenatingAudioSource并仅使用其方法插入、删除或替换其子项的方法。然后,您可以收听以sequenceStateStream观察 just_audio 播放列表的更改并将它们传送到 audio_service。

这个答案展示了如何使用即将发布的 0.18 版本的 audio_service 的预览来保持 just_audio 和 audio_service 播放列表同步。首先,将MediaItemaudio_service 对象存储在tagjust_audio 播放列表中每个项目的属性中,然后将 just_audio 的序列从映射和管道传输sequenceStateStream到 audio_service 队列中:

_player.sequenceStateStream
    .map((state) => state?.effectiveSequence)
    .distinct()
    .map((sequence) =>
        sequence?.map((source) => source.tag as MediaItem).toList())
    .pipe(queue); // <-- this is the audio_service queue stream

如果您改用 audio_service 0.17 或更早版本,则 just_audio 端的原理仍然相同,只是在 audio_service 端有一个setQueue方法而不是queue流,因此您不能只通过管道传输流。相反,您将.pipe(queue)在最后删除该位并执行.listen(AudioServiceBackground.setQueue).

效果是每次有效播放列表just_audio(即播放列表)发生变化时,都会在 中广播一个新的队列audio_service


推荐阅读