开源鸿蒙PC三方库复现:把 MediaInfo CLI 跑到鸿蒙 PC 上
开源鸿蒙PC三方库复现:把 MediaInfo CLI 跑到鸿蒙 PC 上
欢迎加入开源鸿蒙 PC 社区:https://harmonypc.csdn.net/
本项目开源仓库:https://atomgit.com/OpenHarmonyPCDeveloper/ohos_mediainfo
本篇围绕多媒体信息探测工具 MediaInfo CLI 在鸿蒙 PC(OpenHarmony)上的移植,记录我自己在实践中的思路、踩坑与复盘。
相关适配方案最早由社区作者 wei_shuo 在其 CSDN 博客中分享(原文:https://weishuo.blog.csdn.net/article/details/161293782,本系列在其工作基础上做了二次实践与整理,特此致谢。
为什么选 MediaInfo 作为系列开篇
做鸿蒙 PC 生态,绕不开一件事:把 Linux/Windows 上那些成熟的 C/C++ 命令行工具搬过来。MediaInfo 这个工具很有代表性——它体量不大、依赖清晰(ZenLib + MediaInfoLib + zlib),但又恰好能把交叉编译里最常见的几个坑(musl 兼容、依赖联编、产物精简)都覆盖到。换句话说,啃下它,后面再去碰 FFmpeg、curl 这类工具就有底了。
我这次的目标很朴素:在鸿蒙 PC 上敲 mediainfo xxx.mp4,能正常吐出编码格式、分辨率、码率这些技术参数,体验跟在 Ubuntu 上基本一致。
| 关键信息 | 取值 |
|---|---|
| 目标库 | MediaInfo CLI |
| 版本 | 25.03 |
| 协议 | BSD-2-Clause |
| 依赖 | CMake、ZenLib、MediaInfoLib、zlib |
| 构建主机 | WSL Ubuntu 24.04 |
| 目标架构 | arm64-v8a |

先理清这套工具链的角色分工
鸿蒙 PC 的原生包格式叫 HNP(Harmony Native Package)。而真正帮我们把源码交叉编译成 arm64 产物、再打成 HNP 的,是社区维护的构建框架 lycium_plusplus。
我习惯把整个适配过程拆成两个角色来理解:
- 我要做的:写好一份「配方」,告诉框架这个库叫什么、源码在哪、怎么编、装到哪、打成什么包。
- 框架替我做的:按固定生命周期把配方跑一遍——下载/准备源码 → 打补丁 → 交叉编译 → 安装 → 生成 HNP。
这份「配方」就是 HPKBUILD 脚本,外加几个辅助文件。理解了这层分工,后面所有动作就都有归属了。
环境我是怎么搭的
我直接在 Windows 上的 WSL2 里装 Ubuntu 24.04,比纯虚拟机省事。核心要准备的就三样:
# 1. 基础编译工具
sudo apt-get install -y cmake git python3
# 2. 拉构建框架
git clone https://gitcode.com/OpenHarmonyPCDeveloper/lycium_plusplus.git
# 3. 指好鸿蒙 SDK(提供 aarch64-linux-ohos-clang 工具链)
export OHOS_SDK=/path/to/ohos-sdk/linux
一个小提醒:OHOS_SDK 这个环境变量后面会被反复用到,建议直接写进 .bashrc,省得每开一个终端都要重设。
适配的四个核心文件
一个库要进 lycium,我至少要准备这几样东西,放在 thirdparty/mediainfo/ 目录下:
- HPKBUILD —— 构建配方,绝对的核心。
- hnp.json —— 包的元信息,类似前端的 package.json。
- README.OpenSource —— 开源声明,合规必备。
- HPKCHECK —— 产物自检脚本。
如果遇到源码层面的兼容问题,还会多一个 .patch 补丁文件。下面我挑几个关键的说。
HPKBUILD:我对几个阶段的理解
HPKBUILD 是一个 bash 脚本,框架约定了几个函数,按 prepare → build → package → archive 的顺序调用。我自己的笔记是这样记的:
prepare():把源码准备到位。我这次用的是本地源码模式(源码提前放在Projects/MediaInfo),所以这里做的是「复制源码 + 清掉 Windows 残留文件 + 打补丁」。build():真正的交叉编译。这里要注意 MediaInfo 的 CMakeLists.txt 不在根目录,而是在Project/CMake/CLI/下,得用-S显式指过去;同时把 ZenLib、MediaInfoLib、zlib 几个开关全打开,让它们随主程序一起编。package():make install,但要带上DESTDIR,把产物收拢到框架约定的目录,方便后续打包。archive():生成tar.gz和.hnp。
hnp.json:极简就好
{
"type": "hnp-config",
"name": "mediainfo",
"version": "25.03",
"license": "BSD-2-Clause",
"arch": "arm64-v8a",
"install": {
"bin": ["usr/bin/mediainfo"]
}
}
这里我只声明了一个可执行文件入口,因为 ZenLib/MediaInfoLib 我都编成静态库直接打进去了,不需要再单独分发 .so。
全程绕不开的那个坑:musl 与 pthread_cancel
这是我觉得最值得单独拎出来讲的。鸿蒙 PC 用的 C 标准库是 musl,不是常见的 glibc。两者大体兼容,但有些 glibc 独有的函数 musl 没实现,pthread_cancel 就是典型。
ZenLib 里用到了它,于是编译直接报 undeclared identifier 'pthread_cancel'。我的处理方式很务实:MediaInfo CLI 根本不需要「线程取消」这个能力,所以写一个补丁把相关调用注释掉就行,没必要去模拟实现一套。补丁在 prepare() 阶段自动 patch -p1 打上。
这条经验是通用的:碰到 musl 缺函数,先判断「这个功能我到底用不用得上」,用不上就直接绕过,别硬刚。
一次完整的构建跑下来
cd lycium_plusplus/lycium
# 重新构建前,务必清掉缓存记录,否则框架会跳过
grep -v 'mediainfo' usr/hpk_build.csv > usr/hpk_build.csv.tmp
mv usr/hpk_build.csv.tmp usr/hpk_build.csv
rm -rf ../thirdparty/mediainfo/mediainfo-25.03
rm -rf output/*/mediainfo*
# 开干
./build.sh mediainfo
成功后,产物在 output/arm64-v8a/ 下,包含 tar.gz 和 .hnp。
在鸿蒙 PC 上验收
把产物拷到机器上,解压后还有一步容易被忽略——签名。鸿蒙对可执行文件有签名校验,不签直接跑会被拒:
tar -zxf arm64-v8a.tar.gz
cd arm64-v8a/bin
binary-sign-tool sign -inFile mediainfo -outFile mediainfo -selfSign "1"
chmod +x mediainfo
./mediainfo --version
./mediainfo test.mp4
能正常打印版本号、能解析出 mp4 的技术信息,这次适配就算落地了。

我的几条复盘
回头看,这次 MediaInfo 适配真正花时间的不是编译本身,而是这几个「环境差异」:
- 换行符:从 Windows 拷过来的脚本带 CRLF,bash 一跑就报
$'\r': command not found。用 Python 二进制方式批量转成 LF 解决。 - 构建缓存:lycium 用
hpk_build.csv记录构建状态,改完配方不清缓存,它会以为你没改而直接跳过。这个一开始让我很困惑。 - Windows 元数据:
:Zone.Identifier这类文件混进源码会干扰编译,得在 prepare/package 阶段顺手清掉。
这些坑看着琐碎,但几乎在后面每一个库的适配里都会复现,越早形成肌肉记忆越好。
小结
把鸿蒙 PC 三方库适配的「最小闭环」走通了:写 HPKBUILD → 处理 musl 兼容 → 交叉编译 → 签名验收。这套范式后面会反复用到。下一篇我会换个视角,聊聊适配好的 .so 产物怎么在 DevEco Studio 里被真正调用起来。
再次感谢原创适配作者 wei_shuo 的开源分享。如果你也想动手,建议直接从这个体量适中的库练起。
更多推荐

所有评论(0)