鸿蒙开发入坑篇(十一):媒体娱乐 (Audio & Video)

可以体验下鸿蒙Ai:CodeArts Doer代码智能体

🔗 项目地址 :https://github.com/briefness/HarmonyDemo
MediaKit: 在短视频时代,视频播放能力是 App 的必备技能。

HarmonyOS NEXT 提供了强大的 media.AVPlayer,支持音视频播放。与简单组件不同,媒体播放涉及状态机 (State Machine) 、渲染管道 (Rendering Pipeline) 和 音频并发策略 (Concurrency Policy)。

一、核心理论:AVPlayer 状态机

AVPlayer 是一个严谨的状态机。理解状态流转是保证稳定性的关键。
创建
设置资源
准备
播放
暂停
播放
流结束
播放
停止
停止
停止
准备
释放
idle
initialized
prepared
playing
paused
completed
stopped
released
error

1.1 关键状态详解:

  • idle: 刚创建,无资源。
  • initialized : 设置了 url。系统知道要播什么,但未知是否支持。
  • prepared : 这里系统加载完元数据(时长、尺寸)。只有到了这一步,才能安全地获取视频信息并控制 UI。
  • playing/paused: 播放/暂停。网络缓冲时可能仍维持 playing 状态。
  • released : 销毁。注意:退出页面时必须 release,否则解码器资源无法释放,可能导致后续播放失败。

务必熟悉官方的状态流转图,并根据当前状态做防御性编程。

二、渲染原理:生产者与消费者模型

HarmonyOS 推荐使用 XComponent,因为其效率更高。

2.1 Surface 与 BufferQueue

视频播放是一个典型的 生产者-消费者 模型:
Buffer(YUV/RGB)
获取
合成
AVPlayer(解码器)
BufferQueue(缓冲区)
XComponent(Surface)
屏幕显示

  1. 生产者 : AVPlayer (解码器)。输出原始图像数据 (Buffer)。
  2. 消费者 : XComponent (Surface)。接收 Buffer 并合成上屏。

两者通过 BufferQueue (图形缓冲区队列)连接。

将 surfaceId 传给 AVPlayer,相当于把解码器输出直接接到屏幕输入。

优势:

  • 零拷贝 (Zero-Copy):数据在 GPU 内存流转,极大降低 CPU 占用。
  • 低延迟:硬件解码直接上屏。

这也是 XComponent 必须选 surface 类型的原因。

2.2 为什么不用 <Video> 组件?

<Video> 组件简单,但如果需要以下功能,必须用 AVPlayer + XComponent:

  • 自定义控制栏 UI
  • 实现弹幕
  • 滤镜处理
  • 复杂的埋点统计
  • 高性能渲染

三、代码实战要点:绑定 Surface

typescript 复制代码
XComponent({ type: XComponentType.SURFACE, controller: this.mXComponentController })
  .onLoad(() => {
    // 拿到"画布"ID,告诉播放器把画面画到这上面
    this.surfaceId = this.mXComponentController.getXComponentSurfaceId();
    this.avPlayer.surfaceId = this.surfaceId; 
  })

注意:XComponent 的 onLoad 时机非常关键,必须确保 Surface 创建成功后,再把 ID 给 AVPlayer。

四、音频焦点与并发策略 (Concurrency)

这部分常被忽略,但对体验影响巨大。

当视频播放时,如何处理后台音乐、闹钟、导航语音?

HarmonyOS 通过 AudioSession 和 AudioRendererInfo 管理这些策略。

4.1 音频流类型 (StreamUsage)

创建 AVPlayer 时,需指定用途:

  • MUSIC (音乐): 高优先级。导航说话时,通常会"压低音量"继续播放。
  • MOVIE (电影): 类似音乐,需沉浸体验。
  • GAME (游戏): 游戏音效。
  • VOICE_COMMUNICATION (通话): 极高优先级,会打断音乐。

系统默认的焦点模式:

  1. 独占 (Exclusive): 如电话。
  2. 共享 (Mixable): 如游戏音效和背景音乐。
  3. 压低 (Duck): 如导航播报。

播放中
开始
Duck(压低音量)
正常
开始
暂停
静音
音乐播放器(STREAM_MUSIC)
导航(STREAM_VOICE_ASSISTANT)
通话(STREAM_VOICE_COMMUNICATION)
音频策略
音乐(低音量)
导航(正常音量)
中断

最佳实践 :

在 AVPlayer 初始化时正确设置 audioRendererInfo,系统会处理大部分逻辑。

typescript 复制代码
// 电影模式,通常会被通话打断,但可能跟导航共存(压低)
avPlayer.audioRendererInfo = {
  usage: audio.StreamUsage.STREAM_USAGE_MOVIE,
  rendererFlags: 0 
}

五、媒体会话 (AVSession)

若希望在锁屏或控制中心控制播放,需要使用 AVSession。

AVSession 是 App 与系统媒体控制器之间的桥梁。

  1. App 告诉系统:正在播放的内容信息。
  2. 系统告诉 App:用户操作(如"下一首")。

AVSession 还有助于 App 在后台持续运行,通过系统判定为重要任务。

六、总结

媒体开发不仅是调用 API,更是在管理资源 和策略。

  • 状态机保证流程健壮。
  • Surface 保证渲染性能。
  • AudioSession 保证听感和谐。

掌握这些理论,能够显著提升应用质量。

下一篇,将探讨如何让 App 在后台"活"下来:通知与后台任务 (Notifications)。

相关推荐
xq95273 小时前
HDC Assistant 插件横空出世
harmonyos
垆边人似月.4 小时前
华为机试题 :两数之和
c++·算法·华为
垆边人似月.4 小时前
华为机试题 :有效的括号
c++·算法·华为
高德开放平台7 小时前
高德开放平台×华为:一句话,开启腕上打车
华为
垆边人似月.7 小时前
华为机试题 :字符串压缩
算法·华为
ggb喔7 小时前
52pojie 的图片工具:为什么无损转换后体积涨了 6 倍、照片方向还是歪的
图像处理·python·算法·计算机视觉·图形渲染·媒体
EasyDSS10 小时前
告别视频资源浪费!云点播/本地点播/网络点播EasyDSS平台点播实现企业视频高效复用
音视频·媒体·easydss
镭封10 小时前
做电视剧解说视频用什么软件?配音、文案处理一次解决
人工智能·小程序·音视频·语音识别·媒体
OH_TPC10 小时前
【鸿蒙优选三方库】@ohos/aki:一行代码让 ArkTS 调 C++
harmonyos
kjmkq10 小时前
区块链项目出海宣发,依托全球Web3垂直媒体快速建立行业背书
web3·区块链·媒体