likes
comments
collection
share

[译]Flutter 特性丰富的音频播放器 just_audio (五) - 状态模型/配置音频 session

作者站长头像
站长
· 阅读数 17

本文翻译自: just_audio | Flutter Package (flutter-io.cn)

译时版本:0.9.31


状态模型

播放器的状态包含两种正交的状态: playing 和 processingState

playing 状态典型地映射为应用的 开始/暂停 按钮,只会在响应应用中直接的方法调用时发生改变。 相比之下,processingState 反映底层音频解码器的状态,既可以响应应用发出的方法调用,也能响应音频处理管线内部异步发生的事件。

下图示意了有效的状态变换: [译]Flutter 特性丰富的音频播放器 just_audio (五) - 状态模型/配置音频 session

状态模型提供了一种灵活的方式来捕获状态的不同绑定,如 playing+buffering (播放 + 缓冲)vs paused+buffering (暂停 + 缓冲),这可以使状态能更真实地呈现在应用的UI中。 重要的是要理解,除非 processingState == ready 这个指示着缓冲区已满且准备好播放,否则即使 playing == true ,也不会有声音真正播放出来。

这很符合直觉,可以想象一下 playing 状态映射到应用的 播放/暂停 按钮:

  • 用户按 “播放” 按钮开始播放新的音轨,按钮不会立即反映 “播放” 的状态,不过在音频加载( processingState == loading )时会有短暂的静音,但是一旦缓冲区最终填满(既 processingState == ready ),音频就会开始播放。

  • 播放过程中进行缓存时(例如,由于缓慢的网络连接),应用的 播放/暂停 按钮会保持 “播放” 状态,虽然 processingState == buffering 时临时会听不到声音。一旦缓冲区被填满, processingState == ready 了,就会听到声音。

  • 播放到音频流的末尾时,播放器会保持 “播放” 的状态,然后进度条的位置在音轨的末尾。 应用的进度条定位到音频流的前面为止,都不会听到声音。一些应用会在这时选择显示 “重新播放” 按钮代替 播放/暂停 按钮,这(重新播放)会调用 seek(Duration.zero) 。 点击时,会自动从选择的进度条位置继续播放(因为起初从来没有暂停过)。 其它应用可能会想要监听 processingState == completed 事件,然后通过程序暂停并回退到音频的那个时点。 应用要想同时响应正交的状态时,可以通过单个绑定的监听 playerStateStream 的流。 该流会触发同时包含 playing 和 processingState 最新值的事件。

配置音频 session

如果应用使用了音频,那么需要告诉操作系统应用带有的使用方案和应用在设备上如何和其它音频应用交互。 不同的音频应用通常有独特的要求。例如,导航应用说出驾驶指令时,音乐播放器会在避开它的音频,广播播放器也会暂停它的音频。根据要构建的三种之一的应用,需要配置应用的音频设定和回调,以正确地处理这些交互。

just_audio 默认会选择适合音乐播放器应用的设定,这意味着当导航开始(播报语音)时会将音频静音,但是当接打电话或其他音乐播放器开始时会暂停播放。 如果是要构建一个广播播放器或音频书籍阅读器,这种行为就不太合适了。 在后台静音播放音频时,用户可以更好地理解导航指令,但是同时听着音频书籍或广播时就会很难理解导航指令。

可以为应用使用 audio_session 包以改变默认的音频 Session 配置。例,对于一个广播播放器,可以使用:

final session = await AudioSession.instance;
await session.configure(AudioSessionConfiguration.speech());

注意: 如果应用使用了多种不同的音频插件,例如,音频记录,文本语音,或背景音频,有可能这些插件会在内部覆盖其它的音频Session设定,所以建议在加载完所有的音频插件之后使用 audio_session 来应用你自己喜欢的配置。 你可能会考虑询问所用音频插件的开发者,让他们提供一个不覆写全局设定允许在外部管理的选项。