HarmonyOS 鸿蒙Next中AVSession与AVPlayer集成时锁屏播控面板和后台播放如何正确联动?

HarmonyOS 鸿蒙Next中AVSession与AVPlayer集成时锁屏播控面板和后台播放如何正确联动? 在做音乐播放应用,使用 @kit.MediaKit 中的 AVPlayer 做音频播放,同时接入 @kit.AVSessionKit 的 AVSession 实现系统级播控。实际遇到以下问题:锁屏面板的曲目信息不随切歌更新、播放/暂停按钮状态与 AVPlayer 不同步、应用切后台后音频播放被系统回收

7 回复

开发者您好,由于媒体类应用后台播放时需要依赖播控中心的界面对音视频后台播放进行播控操作,应用需注册相应的控制命令,应用播放状态(播放进度、状态、倍速等)也需及时通过setAVPlaybackState更新播放相关的状态。应用切换资源时,应重新设置正确的元数据,并注意更新播放相关的状态。

应用如果要实现后台播放或锁屏播放,需要同时满足:根据应用类型正确创建并接入AVSession;按需申请相应的长时任务避免应用进入挂起状态。

可以参考该文档进行修改:

音视频后台播放和长时任务的使用流程以及注意事项

您还可以通过视频课程进行系统性的学习:

音视频后台播控服务

更多关于HarmonyOS 鸿蒙Next中AVSession与AVPlayer集成时锁屏播控面板和后台播放如何正确联动?的实战系列教程也可以访问 https://www.itying.com/category-93-b0.html


期待解决

先说曲目信息不随切歌更新:

切歌时需要调用 setAVMetadata()重新设置当前曲目的元数据(标题、艺术家、封面、时长等)。如果切歌后只更新了 AVPlayer 的播放源而没有同步更新 AVSession 的元数据,锁屏面板自然不会刷新。此外,元数据必须完整,缺少必要字段(如 title、artist)会导致通知栏显示异常。

再说第二个:播放/暂停按钮状态不同步,这是双向同步问题:

AVSession → AVPlayer:必须通过 session.on(‘play’)/ session.on(‘pause’)注册控制命令回调,在回调中操作 AVPlayer 并同步更新 setAVPlaybackState()。只有注册了回调,播控中心的按钮才会亮起,否则按钮置灰。

AVPlayer → AVSession:当 AVPlayer 状态变化时(如用户在应用内点击播放),必须同步调用 setAVPlaybackState()上报给 AVSession,否则锁屏面板状态不会更新。

最后是后台播放被系统回收的问题:

HarmonyOS 对后台媒体播放有强制约束:如果应用未接入 AVSession,系统会在检测到应用退至后台时停止音视频播放。即使接入了 AVSession,还必须申请 AUDIO_PLAYBACK类型的长时任务(backgroundTaskManager.startBackgroundRunning),否则应用进程会被挂起导致播放停止。两者缺一不可

Interface (AVSession)-@ohos.multimedia.avsession (媒体会话管理)-ArkTS API-AVSession Kit(音视频播控服务)-媒体 - 华为HarmonyOS开发者

AVSession 和 AVPlayer 不会自动保持所有状态一致,需要应用自己把播放状态同步过去。切歌时要同时更新 AVMetadata(标题、歌手、封面、时长等)和 AVPlaybackState(播放/暂停、position、speed、bufferedTime 等);播放、暂停、seek、上一首/下一首这些控制命令也要注册回调,再反向驱动 AVPlayer。

后台播放还需要看长时任务/后台音频能力是否匹配。否则 AVSession 面板还在,但进程进入后台后 AVPlayer 被挂起或回收,就会出现锁屏按钮状态和实际播放脱节。建议把播放器封装成单一状态源,再由它统一推送给 AVPlayer、AVSession 和页面 UI。

在HarmonyOS Next中,AVSession与AVPlayer联动需通过AVSessionController绑定会话,将播放元数据、状态及控制命令(播放/暂停/切歌)注册到会话。锁屏播控面板由系统读取会话状态自动渲染,无需自定义UI。后台播放需在module.json5中配置ohos.permission.KEEP_BACKGROUND_RUNNING,并申请backgroundTaskManager长时任务类型为audioPlayback。集成时确保AVPlayer状态变化(如stateChange)同步更新AVSession的playbackState,并通过setAVMetadata更新标题、歌手等信息。锁屏控制命令通过onCommand回调驱动AVPlayer对应操作即可。

在鸿蒙Next中,AVSession与AVPlayer联动需遵循“状态双向绑定”原则,并配合系统长时任务机制。以下是关键实现:

// 1. 创建AVSession并关联播放器
let avSession = await avSessionKit.AVSession.createAVSession(context, 'music', 'audio');
let controller = await avSession.getController();

// 2. 切歌时更新元数据(解决曲目信息不更新)
let metadata = {
  assetId: 'song_001',
  title: currentSong.title,
  artist: currentSong.artist,
  album: currentSong.album,
  duration: currentSong.duration
};
await avSession.setAVMetadata(metadata);

// 3. 监听AVPlayer状态变化并同步到AVSession(解决播放/暂停不同步)
avPlayer.on('stateChange', (state) => {
  let playbackState = {
    state: state === 'playing' ? avSessionKit.PlaybackState.PLAY : avSessionKit.PlaybackState.PAUSE,
    position: avPlayer.currentTime
  };
  avSession.setAVPlaybackState(playbackState);
});

// 4. 后台播放长时任务(避免被回收)
import { backgroundTaskManager } from '@kit.BackgroundTasksKit';
let taskId = await backgroundTaskManager.requestStartRunning(
  'audioPlayback',
  { duration: 30 * 60 * 1000 } // 30分钟,按需调整
);
// 在应用切入后台时调用,退出时停止:
// backgroundTaskManager.stopRunning(taskId);

联动要点

  • 每次avPlayer.src变化后,必须重新setAVMetadata,并重置播放状态。
  • 使用avSession.setAVPlaybackState同步stateposition,同时在AVSession的on('play')/on('pause')回调中控制avPlayer.play()/pause(),实现双端控制。
  • 后台播放必须申请长时任务,否则系统会回收音频焦点和资源。
  • 若需支持锁屏进度条拖动,通过avSession.on('seek')监听,调用avPlayer.seek(seekTime)

完成以上绑定,锁屏面板即可实时反映曲目和播放状态,后台播放也能稳定运行。

回到顶部