【问题标题】:audio_service and just_audio design for app that supports queuing and multiple playlists支持排队和多个播放列表的应用程序的 audio_service 和 just_audio 设计
【发布时间】:2021-09-04 03:24:35
【问题描述】:

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

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

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

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

【问题讨论】:

    标签: flutter just-audio audio-service


    【解决方案1】:

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

    This answer 展示了如何使用即将发布的 0.18 版本的 audio_service 预览来保持 just_audio 和 audio_service 播放列表同步。首先,将MediaItem audio_service 对象存储在just_audio 播放列表中每个项目的tag 属性中,然后将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中广播一个新的队列。

    【讨论】:

    • 感谢瑞恩的回答。对于每一个微小的变化都广播整个队列(可能包含数千个项目)是不是有点矫枉过正,并且不会导致 UI 上的大量重新渲染和/或状态更新,例如,列表视图位置丢失等第四次?
    • 另外,我仍然无法理解流程。假设用户点击 UI 上 Song 小部件旁边的“立即播放”按钮,它应该有效地将相应的歌曲排在当前歌曲(如果有的话)之后并播放它。如何使用just_audioaudio_service 实现这一目标?
    • 1.您可能不想要一个有 1000 个项目的队列,对吗?当您通过 audio_service 广播队列时,它会通过 Android 媒体会话协议到达 Android Auto 等客户端。我认为您需要一个可管理大小的队列。 2. 如果您使用上面提供的同步码,那么您只需将歌曲添加到连接的音频源,它会自动更新audio_service的队列。
    • 我当然不想要 1000 首歌曲的队列,但这取决于应用程序用户,而不是我 :) 该应用程序理论上可以托管无限量的歌曲,例如我的 dogfooding 版本有约 5,000 首歌曲,播放全部按钮意味着 5,000 首歌曲的队列。一些艺术家(女王或平克弗洛伊德)也有相当多的唱片。
    • 您可能希望实施限制以防止用户这样做。不过,就目前而言,这就是它的设计方式,以便与 Android 的媒体会话协议兼容,但随着迁移到 media2,这可能会变得更好,但不会在短期内。
    猜你喜欢
    • 2021-12-17
    • 2021-10-13
    • 2023-04-10
    • 2021-08-11
    • 2014-12-05
    • 2021-05-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多