鸿蒙开发入坑篇(十一):媒体娱乐 (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; 
  })

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

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

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

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

HarmonyOS 通过 AudioSessionAudioRendererInfo 管理这些策略。

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)

相关推荐
星空222336 分钟前
【HarmonyOS】day39:React Native实战项目+智能文本省略Hook开发
react native·华为·harmonyos
星空22232 小时前
【HarmonyOS】day40:React Native实战项目+自定义Hooks开发指南
react native·华为·harmonyos
Swift社区14 小时前
鸿蒙 PC 架构的终点:工作流
华为·harmonyos
左手厨刀右手茼蒿18 小时前
Flutter for OpenHarmony:dart_console 打造炫酷命令行界面,绘制表格、控制光标与进度条(CLI 交互库) 深度解析与鸿蒙适配指南
flutter·交互·harmonyos·绘制
加农炮手Jinx18 小时前
Flutter for OpenHarmony 实战:疯狂头像 App(三)— 复合动画与交互反馈 — 让 UI 跃动起来
flutter·ui·交互·harmonyos·鸿蒙
王码码203518 小时前
lutter for OpenHarmony 实战之基础组件:第六十二篇 SystemChannels — 探秘 Flutter 与系统交互的捷径
flutter·microsoft·交互·harmonyos
pvIaUtLZ1 天前
Comsol超表面折射率传感器。 电磁诱导透明EIT和典型连续体中的束缚态BIC
华为
Bowen_J1 天前
HarmonyOS 主流跨平台开发框架对比: ArkUI、Flutter、React Native、KMP、UniApp
flutter·react native·harmonyos
lili-felicity1 天前
基础入门 React Native 鸿蒙跨平台开发:react-native-easy-toast三方库适配
react native·react.js·harmonyos
星空22231 天前
【HarmonyOS】day38:React Native实战项目+输入格式化掩码Hook
react native·华为·harmonyos