目录

后台播放

在实际应用场景中,大多数音视频应用都有后台播放的需求,本指南将详细介绍如何实现后台长时间播放。

基本概念

开始之前,开发者应了解以下基本概念,以便根据自身播放器的类型,更有效地实现后台播放。

应用接入规范

如果应用不满足上述接入规范,退至后台播放时会被系统静音并冻结,无法在后台正常播放。直到应用重新切回前台时,才会被解除静音并恢复播放。

开发步骤

音视频应用进行后台播放的基本步骤如下所示。

[h2]启动播放器

应用可以通过AudioRenderer、AVPlayer、其他第三方或自研的播放器来播放音视频。

[h2]接入AVSession

当创建的音频流类型为STREAM_USAGE_MUSIC、STREAM_USAGE_MOVIE、STREAM_USAGE_AUDIOBOOK或STREAM_USAGE_GAME时,无论是将应用退至后台继续播放,还是在后台启动播放,都必须接入AVSession。

建议在应用启动或开始播放业务前创建AVSession,在应用进程结束或退出播放业务时释放,避免频繁创建和释放影响播放连续性。后台播放期间需确保AVSession对象实例一直存在,避免被系统回收,例如使用类成员变量而非局部变量保存。

创建AVSession后,为了保证用户体验,要求设置以下元数据并注册以下控制命令。

AVSession的接入开发请参考指南应用接入AVSession场景介绍。

[h2]申请长时任务

在长时任务中可以申请多种类型的任务。例如:当后台播放音频的任务类型为AUDIO_PLAYBACK时,应用在后台播放音频、视频或通过AVSession投播组件投播,都可申请类型为AUDIO_PLAYBACK的长时任务。

具体操作请参考长时任务(ArkTS)中的开发步骤。

[h2]监听前后台状态

如果应用本身没有后台播放业务,可以通过监听生命周期函数onBackground来判断应用是否已进入后台并主动停止播放。否则会受到AVSession与长时任务模块管控,对应用正常的播放业务造成影响。如需在应用回到前台时重启播放,可以通过监听生命周期函数onForeground来判断应用是否回到前台。

设置后台播放模式

应用在退至后台前,可以通过setBackgroundPlayMode设置后台播放模式,告知系统当应用退至后台时是否具有播放行为。针对音视频类型应用设置后台播放模式,系统会根据应用设置的值来决定应用退后台时是否展示系统实况窗。

[h2]播放模式说明

当前系统支持设置两种播放模式:

  1. 对于AVSessionType为audio类型的应用,系统默认值为ENABLE_BACKGROUND_PLAY,AVSessionType为video类型的应用,系统默认值为DISABLE_BACKGROUND_PLAY。

  2. 音视频应用在退至后台前应设置正确的后台播放模式,以确保退至后台时系统实况窗展示正确。如果应用内提供了类似“是否支持后台播放”的开关,应用设置的后台播放模式务必与应用内的开关状态保持一致。

[h2]开发步骤

音视频应用进行后台播放的开发步骤如下所示。

  1. 设置后台播放模式之前,需要先创建AVSession会话。建议在应用启动或开始播放业务时创建会话,具体操作请参考接入AVSession。

  2. 创建AVSession后,应用在退至后台前应调用setBackgroundPlayMode接口设置准确的后台播放模式。

import { avSession } from '@kit.AVSessionKit';
import { BusinessError } from '@kit.BasicServicesKit';
// ...

@Entry
@Component
struct Index {
  @State message: string = 'hello world';
  // ...

  build() {
    Column() {
      // ...
      Text(this.message)
        .onClick(async () => {
          let currentAVSession: avSession.AVSession | undefined = undefined;
          let tag = 'createNewSession';
          let context: Context = this.getUIContext().getHostContext() as Context;
          // 假设已经创建了一个session,如何创建session可以参考之前的案例。
          avSession.createAVSession(context, tag, 'audio', (err: BusinessError, data: avSession.AVSession) => {
            if (err) {
              console.error(`CreateAVSession BusinessError: code: ${err.code}, message: ${err.message}`);
            } else {
              currentAVSession = data;
            }
          });
          // 设置后台播放模式
          if (currentAVSession !== undefined) {
            try {
              (currentAVSession as avSession.AVSession)
                .setBackgroundPlayMode(avSession.BackgroundPlayMode.ENABLE_BACKGROUND_PLAY);
              // ...
            } catch (err) {
              console.error(`setBackgroundPlayMode BusinessError: code: ${err.code}, message: ${err.message}`);
              // ...
            }
          }
        })
    }
    .width('100%')
    .height('100%')
  }
}

完整示例

基础播控与播控增强