# 一份鸿蒙原生支持硬解的 ffmpeg 开发基座
项目简介:ffmpeg-for-HarmonyOS 是一个为纯血鸿蒙(HarmonyOS NEXT / OpenHarmony)打造的音视频基础库。它不仅打通了 FFmpeg 的全套音视频处理能力,还原生接入了鸿蒙的硬解/硬编接口,提供 HAR 和 C++ SDK 双形态。
项目:ffmpeg-for-HarmonyOS
当前版本:v0.2.2
定位:面向 HarmonyOS NEXT / OpenHarmony 的音视频基础库,不是一个成品播放器 App。
1. 开发背景与初衷
去年做鸿蒙音视频开发时,我遇到的最直接的问题是:找不到一个能直接在纯血鸿蒙上跑起来的完整 FFmpeg 库。
网上能搜到的方案大致有几类:
- 直接拿 Linux/Android 的
.so改后缀,ABI 和系统库对不上; - 只编译了 FFmpeg 的一两个组件,缺封装、缺重采样、缺滤镜;
- 只有示例代码,没有可复现的双 ABI 构建,也没有 release 包;
- 能跑软解,但没有接入鸿蒙的原生硬件
OH_AudioCodec/OH_VideoDecoder,高负荷作业下容易导致发热。
前两类是“编译不过”,后两类是“编译过了但不好用”。对于真正要做音视频功能的人来说,缺的不是一份 FFmpeg 源码,而是一套能和鸿蒙系统能力对接、能被工程化集成的基座。
这也是项目加入硬解的原因。
第一,纯软解在移动设备上的成本很直接。FFmpeg 的软件解码会持续占用 CPU,高分辨率、高码率视频尤其明显,设备发热、耗电、降频都会跟着来。对于播放器、转码器、相机处理这类场景,只靠软解很难长期维持体验。
第二,市面上不少同类开源产品,重点仍然放在“把 FFmpeg 编过鸿蒙”,对鸿蒙原生的硬件解码能力支持不完整。OH_AudioCodec、OH_VideoDecoder 这些系统接口和 FFmpeg 的 AVCodecContext 不是天然打通的,需要额外的解码器封装、Surface 绑定、时间戳和 EOS 处理。这部分工作不做,硬解就只是文档里的一个名词。
所以这个项目从开始就不是“再编译一遍 FFmpeg”,而是把三件事放在一起:
- FFmpeg 的完整封装、解复用、重采样、滤镜与封装能力;
- 鸿蒙原生硬解/硬编接口;
- 能被 ArkTS 和 C++ 项目直接消费的发布形态。
项目保持 LGPL-2.1-or-later,没有启用 GPL、nonfree、x264、x265。当前提供 arm64-v8a 和 x86_64 双 ABI,动态库按 16KB 页对齐。
2. 核心能力与边界
已具备的能力
- 音频:AAC / MP3 / FLAC / Opus / WAV 等常见格式的解码、转码和重采样;支持鸿蒙原生音频硬解,并在硬解不可用时回退软解。
- 视频:H.264 / H.265 的解封装、解码和 Surface 渲染;基础 H.264 硬编;MP4 / MKV / FLV 等常见容器的转码与提取。
- 水印:文字水印和图片水印可以同时叠加,支持位置、字号、颜色、透明度、加粗描边;图片支持 PNG / JPEG 解码。
- 滤镜:基于
libavfilter的scale、overlay、drawtext、format链路,支持original/720p/1080p输出。 - 工程形态:HAR 包和 ZIP SDK 双形态;8 个动态库;23 个 ArkTS 方法。

必须说清楚的边界
当前 v0.2.2 只是公测初版,不是最终完成版。
- 视频处理目前只覆盖基础能力,远没有达到原生 FFmpeg 的全功能覆盖。复杂的滤镜组合、更多编码器、更多容器、更多码流特性仍在后续计划中。
- 图片水印目前还不够完善。PNG/JPEG 解码、缩放和叠加已经跑通,但透明通道、边缘混合、异常图片输入等细节还需要继续打磨。
- 硬解能力依赖具体设备和系统版本。不同芯片、不同 HarmonyOS 版本支持的 codec、分辨率和像素格式并不完全一致,项目做了能力探测和软解回退,但不能保证所有设备行为一致。
- API 仍可能调整,v0.x 阶段不承诺二进制兼容。生产环境接入前,请用自己的素材、目标设备和目标容器做完整验证。
- 当前没有覆盖全部 FFmpeg 组件,也没有承诺替代系统媒体框架。它更适合作为“需要 FFmpeg 能力时的一块基础组件”,而不是万能播放器。
3. 双形态分发设计
不同开发者接入 FFmpeg 的方式不一样,所以 v0.2.2 同时提供两种形态。

HAR 包:给 ArkTS 前端开发者
ffmpeg_ohos-v0.2.2.har,约 18MB,包含 ArkTS 接口和双 ABI native 库。
适合:
- 已经有 HarmonyOS 工程,只想在页面里调用转码、播放、水印;
- 不想维护 CMake、不想手动拷贝
.so; - 希望用
ohpm管理依赖。
HAR 不包含 libc++_shared.so,宿主 App 需要用自己的 NDK 版本提供 C++ runtime,避免和宿主工程的 C++ 运行时冲突。
ZIP SDK:给 C++ 底层开发者
ffmpeg-ohos-sdk-v0.2.2.zip,约 18.5MB,包含:
include/ FFmpeg + freetype + harfbuzz + lame 头文件
lib/arm64-v8a/ 7 个 FFmpeg/lame 库 + libffz.so.1
lib/x86_64/
CMakeLists.txt 可直接 add_subdirectory 的示例
BUILD-INFO.txt ABI、SONAME、sha256 清单
NOTICE.md
LICENSES/
适合:
- 独立转码器、离线处理工具、C++ 服务;
- 需要直接拿
AVFormatContext、AVCodecContext做更底层的控制; - 想把 FFmpeg 当成一个普通 C/C++ 依赖接入现有构建系统。
其中 libffz.so.1 是重命名后的 zlib。这样做的原因是鸿蒙系统环境里没有稳定可用的 libz.so,而宿主工程可能自带 zlib,直接叫 libz 会冲突。重命名后,libavcodec.so.63 和 libavformat.so.63 的 NEEDED 都指向 libffz.so.1。
4. 极简接入指南
4.1 ArkTS:通过 HAR 调用转码
先把 HAR 放进工程,作为本地依赖:
// entry/oh-package.json5
{
"dependencies": {
"@sirius/ffmpeg_ohos": "file:../ffmpeg_ohos"
}
}
然后调用:
import { FFmpegOhos } from '@sirius/ffmpeg_ohos';
const src = `${ctx.filesDir}/input.mp4`;
const dst = `${ctx.filesDir}/output.mp4`;
const r = FFmpegOhos.videoTranscode(
src,
dst,
'mp4', // 容器格式
'720p', // original | 720p | 1080p
1.0 // 音量 0.0 - 2.0
);
if (!r.ok) {
console.error('transcode start failed:', r.data);
}
带文字 + 图片水印时,format 使用下面这串参数:
watermark|<text>|<position>|<fontSize>|<color>|<fontPath>|<alpha>|<bold>
示例:
const fontPath = `${ctx.filesDir}/SourceHanSansCN-Regular.otf`;
const logoPath = `${ctx.filesDir}/logo.png`;
const format =
`watermark|FFmpeg-ohos|bottom-right|42|white@0.8|${fontPath}|80|1`;
FFmpegOhos.videoTranscode(
src,
dst,
format,
'1080p',
1.0,
logoPath // 第 6 个参数:图片水印
);
position 支持 top-left / top-right / bottom-left / bottom-right / center;alpha 为 0–100;bold 为 0 或 1。字体和图片需要先放到 App 可读的沙箱路径。
转码是异步任务,可以通过状态接口查询进度:
const status = JSON.parse(FFmpegOhos.videoTranscodeStatus().data);
// status.state: 1 运行中,2 完成,3 失败
4.2 C++:通过 ZIP SDK 链接
解压 SDK 后,在 CMake 工程里直接引入:
cmake_minimum_required(VERSION 3.16)
project(my_media_tool CXX)
set(OHOS_ARCH arm64-v8a)
add_subdirectory(ffmpeg-ohos-sdk)
add_executable(my_tool main.cpp)
target_link_libraries(my_tool PRIVATE ffmpeg_ohos_sdk)
target_link_libraries(my_tool PRIVATE c++_shared)
ffmpeg_ohos_sdk 会自动带上 include 路径和 8 个 imported 库。业务代码可以直接使用 FFmpeg 原生头文件:
extern "C" {
#include <libavformat/avformat.h>
#include <libavcodec/avcodec.h>
}
AVFormatContext *fmt = nullptr;
if (avformat_open_input(&fmt, path, nullptr, nullptr) < 0) {
// error
}
如果宿主工程已经有自己的 C++ 运行时,请确保 libc++_shared.so 的版本和 SDK 的编译工具链一致;SDK 不会再随包携带一份 C++ runtime。
5. 踩坑与技术深度
这个项目里比较难的部分,大多不是“调通一个 API”,而是系统边界上的问题。
- 海思芯片随机花屏:早期手写 AVCC 封装在特定帧上出现随机花屏,最终改成 AnnexB → MPEG-TS → FFmpeg 原生 remux → MP4 的两段式封装,绕开了自己维护 AVCC 的风险。
- 单声道上混吞音:单声道源被强制上混成立体声时,瞬态峰值从 31517 掉到 22286,正好 -3dB。改成保留源声道数后,FLAC/WAV/Opus 的峰值和起音都恢复正常。
- 假 zlib 桩:系统里没有可直接用的
libz.so,早期链到的是一个 8.9KB 的空壳,PNG 解码时avcodec_open2返回AVERROR_EXTERNAL。最后交叉编译了真正的 zlib,并重命名为libffz.so.1。 - 全量重链:增量构建曾经留下过依赖旧
libz的libavformat.so.63,所以现在每次 FFmpeg 构建前都会强制删除build/<abi>,发布门禁会检查所有.so的 DT_NEEDED 闭包。
这些工作不一定体现在 API 数量上,但决定了库拿到陌生工程里能不能直接跑。
6. 开源号召
开源基建不容易。一个人维护交叉编译、双 ABI、硬解适配、滤镜链、发布包和文档,进度不会像商业项目那样快,但每一步都尽量留下可复现的构建和验证记录。
当前 v0.2.2 只是初版,欢迎各位同行:
- 在自己的鸿蒙设备上试用 HAR 或 ZIP SDK;
- 遇到问题提 Issue,最好带上设备型号、系统版本、输入素材和完整日志;
- 对 API 设计、容器支持、图片水印、硬解适配提出改进方向;
- 如果这个项目帮你省下了几天编译和踩坑时间,点一个 Star 就很有帮助。
仓库与下载
- GitHub:
https://github.com/Sirius-Ji/ffmpeg-for-HarmonyOS - GitCode:
https://gitcode.com/Sirius_Ji/ffmpeg-for-HarmonyOS - Release(HAR / SDK ZIP / per-ABI ZIP / SHA256SUMS):
https://github.com/Sirius-Ji/ffmpeg-for-HarmonyOS/releases/tag/v0.2.2
更多推荐



所有评论(0)