HarmonyOS 鸿蒙Next中播控中心未显示当前播放的音频

HarmonyOS 鸿蒙Next中播控中心未显示当前播放的音频 我使用AVPlayer播放本地mp3音频,然后开启了后台长时任务,现在可以实现切换后台或者锁屏后继续播放。但是在系统的播控中心里,不展示当前播放的音频。我按照官方文档去设置了AVSession的原数据,打印日志也设置成功了,但是不知道为啥就是不在播控中心展示

6 回复

开发者您好,按播控中心接入流程,当前播控中心的显示规则为:

  1. 创建会话类型为“audio”或“video”的AVSession,设置媒体信息,注册至少一个回调,会在播控中心展示媒体信息。

  2. 创建会话类型为“voice_call”或“video_call”的AVSession,应用上架的一级分类必须是应用(13),二级分类必须是商务(10000001)或社交(10000016)https://developer.huawei.com/consumer/cn/doc/app/agc-help-connect-api-appendix-apptype-0000002271160689,且处于响铃或通话状态,会在播控中心展示通话卡片。

  3. 创建会话类型为“photo”的AVSession,播控中心不展示。

更多关于HarmonyOS 鸿蒙Next中播控中心未显示当前播放的音频的实战系列教程也可以访问 https://www.itying.com/category-93-b0.html


播控中心不展示,99% 不是 AVPlayer 的问题,而是 AVSession 没有处在“系统认为可展示的激活播放态”。你虽然 setAVMetadata 成功了,但只要下面任意一条没满足,播控中心就可能不出卡片/不显示音频信息。

必查点(按优先级)

1)session.activate() 调用时机不对 / 没激活成功

官方接入流程里强调:元数据、控制命令注册完成之后再 activate,否则可能被系统判定为无效会话或展示不完整。 正确顺序应是:

  1. create session
  2. setAVMetadata
  3. 注册控制命令回调(play/pause/next/prev/seek 等,至少要有 play/pause)
  4. await session.activate()
  5. 播放开始后持续上报播放状态(state/position/speed 等)

(流程见“应用接入AVSession场景介绍”) Sources: https://developer.huawei.com/consumer/cn/doc/harmonyos-guides/avsession-access-scene


2)你只设置了元数据,但 没有上报播放状态 / 或 state 不为 PLAY

播控中心是否展示,很依赖 setAVPlaybackState 里的状态。例如你元数据设置了,但一直上报的是 Pause/Stop,或根本没上报 position,系统可能不展示。

最低要求建议你在开始播放后做一次:

  • state = PLAYBACK_STATE_PLAY
  • position = 当前播放进度(ms)
  • speed = 1.0

并且播放过程中建议定时更新 position(比如 500ms~1000ms 一次)。


3)AVSession 实例被释放(最常见“日志成功但界面没东西”)

如果你在某个函数里 let session = await createAVSession(...),后面没有被成员变量/单例持有,页面切换或 GC 后 session 可能被释放,播控中心就不会显示。

做法:把 session 放到 Ability 级单例或页面的成员字段里,确保播放期间一直存在。


4)没有注册控制命令(至少 play/pause)

播控中心的卡片本质是“可控的媒体会话”。如果你只上报 metadata,但 没有注册播控回调,有些版本会不展示或展示异常。

建议至少注册:

  • on('play')
  • on('pause')(如果你想要进度条可拖动再加 on('seek')

一个最小正确骨架(你对照改)

import { avSession as AVSessionManager } from '@kit.AVSessionKit';

class PlayerSessionHolder {
  session?: AVSessionManager.AVSession

  async init(ctx: Context, durationMs: number) {
    this.session = await AVSessionManager.createAVSession(ctx, 'MY_AUDIO_SESSION', 'audio');

    await this.session.setAVMetadata({
      assetId: 'local_mp3_001',
      title: '本地歌曲',
      artist: '未知',
      duration: durationMs,
    });

    // 至少注册 play/pause
    this.session.on('play', () => { /* player.play() */ });
    this.session.on('pause', () => { /* player.pause() */ });

    await this.session.activate(); // 注意:放在 metadata + on(...) 之后

    // 播放开始后上报播放态
    await this.session.setAVPlaybackState({
      state: AVSessionManager.PlaybackState.PLAYBACK_STATE_PLAY,
      position: 0,
      speed: 1.0,
    });
  }

  async updatePosition(posMs: number) {
    if (!this.session) return
    await this.session.setAVPlaybackState({
      state: AVSessionManager.PlaybackState.PLAYBACK_STATE_PLAY,
      position: posMs,
      speed: 1.0,
    });
  }
}

你发我两段信息,我可以直接帮你定位是哪一条没满足

  1. 你创建/激活 session 的代码片段(是否把 session 保存成成员变量?activate 放在哪里?)
  2. 你有没有调用 setAVPlaybackState,以及你上报的 state/position/duration 分别是多少(日志即可)

Sources:

尊敬的开发者,您好,

应用接入AVSession流程分为如下几个步骤:

  1. 确定应用需要创建的会话类型,创建对应的会话,不同类型决定了播控中心展示的控制模板样式。
  2. 按需创建后台任务。
  3. 设置必要的元数据(Metadata),以在播控中心展示相应的信息,包括不限于:当前媒体的ID(assetId),上一首媒体的ID(previousAssetId),下一首媒体的ID(nextAssetId),标题(title),专辑作者(author),专辑名称(album),词作者(writer),媒体时长(duration)等属性。
  4. 设置播放相关的状态,包括不限于:当前媒体的播放状态(state)、播放位置(position)、播放倍速(speed)、缓冲时间(bufferedTime)、循环模式(loopMode)、是否收藏(isFavorite)、正在播放的媒体Id(activeItemId)、自定义媒体数据(extras)等属性。
  5. 按需注册不同的控制命令,包括不限于:播放/暂停、上下一首、快进快退、收藏、循环模式、进度条。应用退出或者无对应业务时,注销会话。

具体可参考应用内直播切换后台后声音正常但无播控组件,可参考该文章的示例,如无法解决,请再次反馈。

这通可能因为AVSession的接入流程不完整所致。根据相关开发指南,要实现播控中心正常显示和控制,除了设置元数据,还必须完成以下几个关键步骤:

  1. 注册控制命令:即使元数据设置成功,如果未注册任何控制命令(如playpause),系统会认为你的应用不需要交互,从而不会在播控中心显示会话。你必须在创建AVSession后,立即为其注册命令监听器。
  2. 激活AVSession:创建AVSession后,必须调用其activate()方法,会话才会生效。
  3. 实时更新播放状态:播控中心上的播放/暂停按钮状态和进度信息,依赖于应用通过setAVPlaybackState方法主动更新的AVPlaybackState。你需要在播放器的状态(如开始、暂停、跳转)发生变化时,及时调用此方法同步状态。
  4. 确保AVSession对象持久化:应用在后台播放期间,必须确保AVSession对象实例一直存在,避免将其置于局部变量中而被系统回收。

检查下是否已经为AVSession注册了on('play')on('pause')等控制命令监听,播放器状态变化时调用了setAVPlaybackState。这两步是播控中心得以显示和交互的核心。

在鸿蒙Next中,播控中心未显示当前音频,通常因应用未正确创建并激活MediaSession。需在播放前调用MediaSession.create(context)并设置元数据(setMetadata),且调用setActive(true)。同时需确保Ability的onStart/onStop生命周期中回调播控会话。若上述均实现,检查应用是否注册了mediaSession权限。

您的问题可能是AVSession激活或元数据必要字段缺失导致。请检查:

  1. 创建AVSession后务必调用session.activate()激活会话,否则系统不会获取。
  2. 元数据必须至少包含AVMediaDescription.Builder中的KEY_TITLE,否则播控中心不予展示。示例:metaBuilder.setString(AVMediaDescription.KEY_TITLE, "歌名")
  3. 确认会话类型为AVSession.SESSION_TYPE_AUDIO
  4. 设置元数据后,必须调用session.setAVMetadata(metadata)并随后通过session.setAVPlaybackState(state)更新播放状态(如播放、暂停),即使不传完整状态对象也需提供一个含合法状态值的Builder构建。
  5. 若锁屏不显示,需在后台任务中保持AVSession前台服务属性(长时任务声明中关联session即可,无需额外代码)。

完成以上步骤后,播控中心应能正常展示当前音频信息。

回到顶部