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

相关推荐
熊猫钓鱼>_>6 小时前
【开源鸿蒙跨平台开发先锋训练营】Day 19: 开源鸿蒙React Native动效体系构建与混合开发复盘
react native·华为·开源·harmonyos·鸿蒙·openharmony
Data_Journal6 小时前
Scrapy vs. Crawlee —— 哪个更好?!
运维·人工智能·爬虫·媒体·社媒营销
2601_949593656 小时前
基础入门 React Native 鸿蒙跨平台开发:BackHandler 返回键控制
react native·react.js·harmonyos
mocoding7 小时前
使用Flutter强大的图标库fl_chart优化鸿蒙版天气预报温度、降水量、湿度展示
flutter·华为·harmonyos
Cobboo7 小时前
i单词上架鸿蒙应用市场之路:一次从 Android 到 HarmonyOS 的完整实战
android·华为·harmonyos
2601_949593657 小时前
高级进阶 React Native 鸿蒙跨平台开发:LinearGradient 动画渐变效果
react native·react.js·harmonyos
熊猫钓鱼>_>8 小时前
【开源鸿蒙跨平台开发先锋训练营】鸿蒙应用开发 Day 10 - React Native for OpenHarmony 实战:多端响应式布局与高可用交互设计
华为·开源·交互·harmonyos·鸿蒙·rn·gridrow
摘星编程9 小时前
React Native鸿蒙:自定义useField字段状态绑定
react native·react.js·harmonyos
人工智能知识库9 小时前
华为数通HCIA-Datacom H12-811题库(26最新详细解析)
华为·hcia-datacom·题库·h12-811·最新题库
酣大智9 小时前
参考模型--数据链路层
运维·网络·网络协议·tcp/ip·华为