第13章 HarmonyOs开发图解 视频

HarmonyOS 学习系统 | 阶段三:高级深耕期


学习目标

序号 能力
1 掌握 HarmonyOS 视频播放(Player)的完整生命周期管理
2 能够使用 Codec 实现视频编解码能力查询
3 掌握视频录制(Recorder)的基本配置与使用

核心图解

HarmonyOS 多媒体框架全景图

内容讲解

13.1 视频能力总览

HarmonyOS 视频模块提供了完整的视频处理能力,涵盖三个核心方向:

  • 视频编解码:通过 Codec 类实现编码和解码,支持查询设备编解码能力
  • 视频播放:通过 Player 类实现,支持播放/暂停/拖拽/倍速/循环
  • 视频录制:通过 Recorder 类实现,支持配置音视频源和存储属性

生活化类比:视频编解码就像"翻译官"

原始视频数据(每一帧像素)就像一篇很长的中文文章,体积庞大。编码器(Encoder)把它"翻译"成精简的英文(压缩格式如 H.264),体积小了很多但保留了核心含义。解码器(Decoder)则做反向翻译,把压缩数据还原成可以显示的画面。而播放器(Player)就像朗读者,拿着翻译好的稿子按节奏"朗读"(播放)出来。

13.2 视频播放器 Player

Player 是 HarmonyOS 视频播放的核心类,支持多种媒体格式(MP4、H.264、H.265、AAC 等)。Player 的生命周期为:创建 -> 设置数据源 -> 准备 -> 播放/暂停 -> 停止 -> 释放。

// 创建播放器并设置数据源
Player player = new Player(context);
player.setSource(new Source("resources/rawfile/big_buck_bunny.mp4"));

// 设置视频渲染 Surface(关键步骤)
surfaceProvider.setSurfaceCreatedCallback(new SurfaceOpsCallback() {
    @Override
    public void onSurfaceCreated(SurfaceOps surfaceOps) {
        player.setVideoSurface(surfaceOps.getSurface());
    }
});

// 准备并播放
player.prepare();
player.play();

// 设置播放速度(0.75x ~ 2.0x)
player.setPlaybackSpeed(1.5f);

// 开启单曲循环
player.enableSingleLooping(true);

// 拖拽到指定位置(单位:微秒)
player.rewindTo(30000000); // 跳到30秒处

// 注册播放状态回调
player.setPlayerCallback(new Player.IPlayerCallback() {
    @Override
    public void onPrepared() { HiLog.info(TAG, "准备完成"); }
    @Override
    public void onPlayCompleted() { HiLog.info(TAG, "播放完成"); }
    @Override
    public void onError(int errorType, int errorCode) {
        HiLog.error(TAG, "播放错误: " + errorCode);
    }
});

13.3 视频资源释放

非常重要:Player 持有 Native 资源,必须在 Ability 的 onStop() 中释放,否则会导致内存泄漏。

@Override
protected void onStop() {
    super.onStop();
    if (player != null) {
        player.stop();
        player.release();
        player = null;
    }
}

13.4 视频录制

Recorder 类支持录制音视频并保存到文件,需要配置视频源(如相机)、音频源(如麦克风)和输出格式。

// 创建录制器
Recorder recorder = new Recorder();

// 配置录制参数
RecorderConfig config = new RecorderConfig.Builder()
    .setVideoSource(RecorderConfig.VideoSource.VIDEO_SOURCE_SURFACE)
    .setAudioSource(RecorderConfig.AudioSource.AUDIO_SOURCE_MIC)
    .setOutputFormat(RecorderConfig.OutputFormat.OUTPUT_FORMAT_MPEG_4)
    .setVideoEncoder(RecorderConfig.VideoEncoder.VIDEO_ENCODER_H264)
    .setAudioEncoder(RecorderConfig.AudioEncoder.AUDIO_ENCODER_AAC)
    .setVideoSize(new Size(1920, 1080))
    .setVideoFrameRate(30)
    .setOutputFile(new File("path/to/output.mp4"))
    .build();

recorder.setRecorderConfig(config);
recorder.prepare();
recorder.start(); // 开始录制

// 停止录制
recorder.stop();
recorder.release();

13.5 编解码能力查询

不同设备支持的编解码器差异很大,开发前务必查询设备能力:

// 查询设备支持的编解码格式
CodecDescriptionList codecList = new CodecDescriptionList();
List<CodecDescription> supported = codecList.getSupportedMimes(CodecDescription.CodecType.CODEC_TYPE_DECODER);
for (CodecDescription desc : supported) {
    HiLog.info(TAG, "支持格式: " + desc.getMimeType());
}

代码速查卡

API 功能 示例
Player(context) 创建播放器实例 new Player(context)
setSource(source) 设置媒体源 player.setSource(new Source(path))
prepare() / play() / pause() / stop() 准备/播放/暂停/停止 player.prepare(); player.play();
rewindTo(microseconds) 拖拽到指定位置 player.rewindTo(30000000)
setPlaybackSpeed(speed) 设置播放速度 player.setPlaybackSpeed(1.5f)
setVideoSurface(surface) 设置视频渲染 Surface player.setVideoSurface(surface)
enableSingleLooping(true) 开启单曲循环 player.enableSingleLooping(true)
setPlayerCallback(cb) 注册播放状态回调 player.setPlayerCallback(callback)
getCurrentTime() 获取当前播放位置 player.getCurrentTime()

与 Android/iOS 对比

特性 HarmonyOS Android iOS
播放器类 Player MediaPlayer / ExoPlayer AVPlayer
Surface 渲染 SurfaceProvider + SurfaceOps SurfaceView / TextureView AVPlayerLayer
倍速播放 setPlaybackSpeed() setPlaybackParams() rate 属性
录制类 Recorder MediaRecorder AVAssetWriter
编解码查询 CodecDescriptionList MediaCodecList supportedVideoTypes

⚠️ 踩坑回忆录

为什么视频播放黑屏?

我第一次写视频播放器时,prepare()play() 都调用了,但画面始终是黑的。排查了半天,发现 SurfaceProvider 的回调还没触发就调了 play()——Surface 还没准备好,画面往哪渲染?正确做法是在 onSurfaceCreated 回调中设置 Surface 后再 play。

另外,不同设备支持的编解码器差异很大,一定要先用 CodecDescriptionList.getSupportedMimes() 查询设备能力,别假设所有设备都支持 H.265。我曾在一台中端机上硬编码 H.265 播放,结果只有声音没有画面。


必做实操任务

序号 任务 难度
1 实现一个完整的视频播放器,支持播放、暂停、拖拽和倍速
2 添加播放进度条,实时更新播放位置
3 查询当前设备的编解码能力,列出支持的格式
4 实现视频播放器的单曲循环和列表播放功能
5 实现视频录制功能并保存到本地

学习检查清单

  • 能说出 Player 的完整生命周期(创建 -> 释放)
  • 能正确使用 SurfaceProvider 显示视频画面
  • 知道为什么必须在 onSurfaceCreated 回调中设置 Surface
  • 能实现视频的播放、暂停、拖拽和倍速功能
  • 能正确释放 Player 资源(在 onStop 中)
  • 能查询设备的编解码能力
  • 了解 Recorder 的基本配置方式
  • 理解视频格式与编解码器的关系(H.264、H.265 等)

进阶方向

  • 结合第 15 章相机能力,实现自定义视频录制 App
  • 学习 HLS/DASH 流媒体协议,实现网络视频播放
  • 探索视频帧的实时处理(如滤镜、美颜)
    ayer 资源(在 onStop 中)
  • 能查询设备的编解码能力
  • 了解 Recorder 的基本配置方式
  • 理解视频格式与编解码器的关系(H.264、H.265 等)

进阶方向

  • 结合第 15 章相机能力,实现自定义视频录制 App
  • 学习 HLS/DASH 流媒体协议,实现网络视频播放
  • 探索视频帧的实时处理(如滤镜、美颜)
Logo

讨论HarmonyOS开发技术,专注于API与组件、DevEco Studio、测试、元服务和应用上架分发等。

更多推荐