📚 鸿蒙专题与实战专栏 · 第 24 篇 / 共 30 篇(专题篇 21-30)
上一篇:服务卡片开发 | 下一篇:多模块工程:HAP、HAR、HSP 与按需加载

目录

一、能播放就先别造轮子

二、20 行实现视频播放

三、录制:AVRecorder

四、什么时候才需要 Native

五、下一篇预告


音视频是应用的高频需求,也是新手最容易一上来就想「自己写播放器」的坑。这篇给你一条正确的入门路径。

一、能播放就先别造轮子

95% 的播放需求,用系统自带的 AVPlayer 就够了:支持 mp4/mp3/m3u8/HLS,自带硬解码、缓冲、音视频同步。先把它用熟,再谈自定义。

二、20 行实现视频播放

import { media } from '@kit.MediaKit'
import { BusinessError } from '@kit.BasicServicesKit'

@Entry
@Component
struct PlayerDemo {
  private player: media.AVPlayer | undefined = undefined
  @State isPlaying: boolean = false

  async aboutToAppear() {
    this.player = await media.createAVPlayer()
    this.player.on('stateChange', (state: string) => {
      if (state === 'initialized') {
        this.player!.prepare()          // 准备好后进入 prepared
      } else if (state === 'prepared') {
        this.player!.play()
      }
    })
    // 设置播放源(网络地址或 fd)
    this.player.url = 'https://example.com/sample.mp4'
  }

  aboutToDisappear() {
    this.player?.release()              // 必须释放,否则泄漏
  }

  build() {
    Column() {
      // 播放画面绑定到 XComponent
      XComponent({ id: 'video', type: 'surface', libraryname: '' })
        .width('100%').height(220)
      Button(this.isPlaying ? '暂停' : '播放')
        .onClick(() => {
          this.isPlaying ? this.player?.pause() : this.player?.play()
          this.isPlaying = !this.isPlaying
        })
    }
  }
}
📌 AVPlayer 是状态机:idle → initialized → prepared → playing。几乎所有「播放没反应」的问题,都是没在正确的状态调用对应方法。老老实实监听 stateChange。

三、录制:AVRecorder

import { media } from '@kit.MediaKit'

const recorder = await media.createAVRecorder()
await recorder.prepare({
  audioSourceType: media.AudioSourceType.AUDIO_SOURCE_TYPE_MIC,
  videoSourceType: media.VideoSourceType.VIDEO_SOURCE_TYPE_SURFACE_YUV,
  profile: {
    audioBitrate: 48000, audioChannels: 1,
    audioCodec: media.CodecMimeType.AUDIO_AAC,
    audioSampleRate: 48000,
    videoCodec: media.CodecMimeType.VIDEO_AVC,
    videoFrameWidth: 1280, videoFrameHeight: 720, videoFrameRate: 30
  },
  url: 'fd://' + file.fd          // 输出文件
})
await recorder.start()
// ... recorder.stop() / release()
⚠️ 录制必须申请麦克风/相机权限(第 18 篇)。另外后台录音、长时间录制在各系统版本有额外限制,上线前务必按最新规范核对。

在进入 Native 之前,先用一张表把三种方案的定位理清楚:

对比维度AVPlayerAVRecorderNative(NDK + FFmpeg)
适用场景音视频播放,支持 mp4/mp3/m3u8/HLS 等常见格式音视频录制,麦克风采集与摄像头画面编码系统能力覆盖不到的自定义音视频处理链路
开发成本低,几十行代码即可跑通低到中,需处理权限、参数配置与文件输出高,涉及 C++、交叉编译、JNI 桥接与三方库集成
性能高,系统硬解码,自带缓冲与音视频同步高,系统硬编码,资源占用可控取决于实现,软解软编时 CPU 占用明显上升
可定制性低,仅能通过有限接口调整播放行为低到中,可配置编码参数与采集源高,滤镜、美颜、剪辑、推流均可自由实现
典型用途视频播放器、在线课程、短视频浏览录音、录像、直播采集端实时美颜相机、视频剪辑、RTMP 推流

选型结论:能用 AVPlayer 和 AVRecorder 解决的,就不要碰 Native;只有当业务明确需要自定义滤镜、实时美颜、视频剪辑或 RTMP 推流这类系统能力覆盖不到的功能时,才值得承担 NDK + FFmpeg 的开发成本。

四、什么时候才需要 Native

需要自定义滤镜、实时美颜、视频剪辑、RTMP 推流时,才考虑 NDK + FFmpeg。这条路线学习成本陡增(C++、交叉编译、JNI 桥接),建议放到独立专题。

五、下一篇预告

功能越来越多,工程该怎么组织?下一篇:多模块工程 HAP/HAR/HSP。


专题篇持续更新,点赞 + 收藏 + 关注不迷路。
想深入哪个方向,评论区留言,点赞高的先写。

Logo

作为“人工智能6S店”的官方数字引擎,为AI开发者与企业提供一个覆盖软硬件全栈、一站式门户。

更多推荐