开源鸿蒙PC三方库实战复现:mpv 本体的 HPKBUILD 与真机验证
开源鸿蒙PC三方库实战复现:mpv 本体的 HPKBUILD 与真机验证
欢迎加入开源鸿蒙 PC 社区:https://harmonypc.csdn.net/
开源仓库地址:
https://atomgit.com/OpenHarmonyPCDeveloper/ohos_mpv_pc
本篇基于社区作者 Dream-Y.ocean 的《https://dream-yocean.blog.csdn.net/article/details/161747578》整理,结合我自己的复现重新讲述。验证截图复用自原作者公开素材,致谢。
mpv 适配的定位
先明确一件事:我们适配的核心产物是 libmpv.so——mpv 的嵌入式播放核心库。
mpv 大家熟悉的是那个命令行播放器,但它真正的价值在于把播放核心抽象成了 libmpv:一个可以被其他应用通过 API(甚至 NAPI)调用的库。这意味着鸿蒙应用可以基于 libmpv 去实现自己的视频播放器、媒体浏览器、带高级字幕的播放界面等等。所以这次适配不只是「编个能跑的命令行工具」,更是在为鸿蒙的多媒体应用生态打底座。
| 项目 | 信息 |
|---|---|
| 库 | mpv / libmpv |
| 版本 | 0.41.0 |
| 协议 | LGPL-2.1-or-later |
| 构建系统 | Meson + Ninja |
| 直接依赖 | FFmpeg、libplacebo、libass |
| 架构 | arm64-v8a |

环境准备
mpv 用 Meson + Ninja,所以构建机上这两样要先装好:
sudo apt-get install -y meson ninja-build
meson --version # 建议 0.60+
ninja --version
export OHOS_SDK=/path/to/ohos-sdk/linux
mpv 的 HPKBUILD 关键点
有了前面的铺垫(第五篇 Meson cross file、第七篇依赖树),mpv 的配方就是把这些整合起来。我重点关注三处。
1. depends 要把直接依赖都列上
depends=("ffmpeg" "libplacebo" "libass" ...)
这让 lycium 在编 mpv 之前先确认这些依赖都已经就绪。配合上一篇说的「自底向上」,到了编 mpv 这一步,下面三层应该都已经编好了。
2. cross file 里串好所有 pkgconfig 路径
这是 mpv 整个适配里最繁琐、最容易出错的地方。Meson 通过 pkg-config 查找依赖,而 mpv 的依赖(含传递依赖)有十几个。我要在交叉编译配置里把它们的 pkg_config_path 一条条列清楚:
# ohos-cross.ini (节选示意)
[binaries]
c = 'aarch64-linux-ohos-clang'
cpp = 'aarch64-linux-ohos-clang++'
ar = 'llvm-ar'
strip = 'llvm-strip'
pkg-config = 'pkg-config'
[built-in options]
# 把所有依赖的 pkgconfig 目录串起来
pkg_config_path = '/path/usr/ffmpeg/.../pkgconfig:/path/usr/libplacebo/.../pkgconfig:/path/usr/libass/.../pkgconfig:...'
[host_machine]
system = 'linux'
cpu_family = 'aarch64'
cpu = 'aarch64'
endian = 'little'
少串一个路径,meson setup 阶段就会报 Dependency "xxx" not found。这也是为什么上一篇我反复强调「pkg-config 路径靠手动传」。
3. 禁用鸿蒙不支持的后端
mpv 默认会探测一大堆平台特性。其中有些在鸿蒙上根本不存在,必须显式关掉,否则配置阶段直接挂:
- Android 的 OpenSLES 音频后端:报
dependency SLES/OpenSLES_Android.h not found,关掉。 - X11 / Wayland 图形后端:鸿蒙不是这套图形栈,关掉。
处理方式就是在 Meson 选项里把对应特性设为 disabled 或 false。这又回到系列里那条「做减法优先」的原则——先把不支持的统统关掉,编通了再说。
4. 头文件路径的手动修补
libplacebo 这个依赖有个老毛病:它装完之后头文件位置不太规范,pkg-config 给的路径不一定能让编译器找到 libplacebo/colorspace.h、libplacebo/config.h。这时候光靠 pkg-config 不够,要手动给 mpv 的编译补上 -I 指向 libplacebo 头文件的真实目录。链接同理,如果报 unable to find library -lplacebo,就要在链接参数里补上 libplacebo 库文件所在的目录。
hnp.json:库 + 头文件一起发
因为 libmpv 是要给别人调用的,所以除了 bin,还要发 lib 和 include:
{
"type": "hnp-config",
"name": "mpv",
"version": "0.41.0",
"description": "A free, open source, and cross-platform media player",
"license": "LGPL-2.1-or-later",
"arch": "arm64-v8a",
"install": {
"bin": ["usr/bin/mpv"],
"lib": ["usr/lib/libmpv.so*"],
"include": ["usr/include/mpv"]
}
}
两个细节:
libmpv.so*用通配符,是因为它有版本号软链(如libmpv.so→libmpv.so.2→libmpv.so.2.5.0),要把这一串都打进去;include把头文件也发出去,这样下游应用集成 libmpv 时才有 API 声明可用(呼应第二篇 DevEco 集成那一套)。
完整构建流程
cd lycium_plusplus/thirdparty
mkdir -p mpv && cd mpv
vim HPKBUILD # 写配方,同目录放 hnp.json / README.OpenSource / HPKCHECK
cd ../../lycium
# 清缓存(重编必做)
grep -v 'mpv' usr/hpk_build.csv > usr/hpk_build.csv.tmp
mv usr/hpk_build.csv.tmp usr/hpk_build.csv
rm -rf ../thirdparty/mpv/mpv-0.41.0
rm -rf output/*/mpv*
# 构建(前提:依赖树各层已编好)
./build.sh mpv
真机验证:怎么确认 libmpv 是「真有效」的
mpv 这种库类产物不像命令行工具能直接 --version 看结果。验证 .so 有效性,我用了三招组合,这套方法对所有「不能直接运行」的库都适用:
# 解压产物
tar -zxf mpv_0.41.0.tar.gz
cd usr/lib
ls # 确认 libmpv.so* 在
# 招式 1:file 看架构对不对
file libmpv.so.2.5.0
# 期望输出:ELF 64-bit LSB shared object, ARM aarch64 ...
# 招式 2:od 看 ELF 魔数,确认是合法 ELF 文件
od -N 4 libmpv.so.2.5.0
# 期望开头是 7f 45 4c 46(即 \x7f E L F)
# 招式 3:strings + grep 抠版本号,确认确实是 0.41.0 编出来的
strings libmpv.so.2.5.0 | grep "0.41.0"
# 能匹配到 mpv v0.41.0-UNKNOWN 之类的标识
三招分别回答三个问题:架构对不对(file)、文件完不完整合不合法(od 看魔数)、内容是不是我们要的版本(strings)。三关都过,这个库基本就可以放心交给下游了。

常见报错的应对
原文列了 11 个 Q&A。结合第七篇的「依赖树定位法」,它们大多能被快速归类、快速解决。我整理成对照表:
| 报错 | 病根 | 处理 |
|---|---|---|
Unknown options: libplacebo_ldflags |
Meson 选项名/版本不符 | 对照该版本 meson_options 核对 |
libplacebo/colorspace.h: No such file |
libplacebo 头文件路径没加 | 手动补 -I 到真实目录 |
libplacebo/config.h: No such file |
同上 | 同上 |
unable to find library -lplacebo |
libplacebo 库路径没配 | cross file/链接参数补库目录 |
Dependency "libass" not found |
libass pkgconfig 没传 | 串进 pkg_config_path |
fribidi.h: No such file |
fribidi 头文件没进搜索路径 | 补 -I |
OpenSLES_Android.h not found |
没关 Android 音频后端 | 显式 disable |
| package 阶段只有 hnp.json | 库没拷进产物目录 | 检查 package/archive 路径 |
cp: -r not specified; omitting directory |
复制库时漏了 -r | 复制目录加 -r |
| 改完 HPKBUILD 被跳过 | 构建缓存 | 清 hpk_build.csv |
| 没有 mpv 可执行文件 | 只编了 libmpv | 确认配置里开了 CLI 构建 |
可以看到,除了「关后端」和几个手滑型问题,其余基本都是上一篇说的「上层找不到下层」的变体——定位到断在哪一层,对症补路径就行。
小结
mpv 这两篇(第七篇依赖树 + 本篇本体)合起来,是整个系列复杂度的天花板。把它跑通,意味着我掌握了复杂多层依赖项目的系统化适配能力,这套能力可以拆成一条清晰的流水线:
理清依赖树 → 自底向上逐层编 → cross file 串好 pkg-config → 关掉不支持的特性 → 手动补头文件/链接路径 → 用 file/od/strings 验收
这套流程可以平移到 VLC、GStreamer 等同类项目。下一篇换个完全不同的领域——Java 生态的 JNA 库,看看「Java 库里藏着的 C 组件」该怎么适配,那会带来一批全新的坑。感谢原创适配作者 Dream-Y.ocean 的开源分享。
更多推荐



所有评论(0)