查看: 396|回复: 3

OBS鸿蒙迁移实战:60个依赖交叉编译与napi桥搭建

[复制链接]
发表于 1 小时前 | 显示全部楼层 |阅读模式
迁移对象与总体路径
OBS Studio 32.2.2 并不是一个单二进制项目。它的底层包括 libobs 内核、ffmpeg 全家桶、x264、zlib/curl/ssl、datachannel、Qt6 前端以及采集/编码/输出/滤镜插件群,第三方依赖约 60 个。该迁移目标是把 OBS Studio 32.2.2 连同这些依赖整体交叉编译到 HarmonyOS NEXT,且这一阶段全部工作在 mac 上完成,尚未在真机上运行。

工具链选择 OHOS NDK,即 clang + musl + ohos target triple。具体做法是为每个依赖库编写统一的 configure/cmake 工具链文件,CC/CXX 指向 NDK clang,sysroot 指向 NDK,使用 --host=aarch64-linux-ohos 这类 triple;再用 build-deps.sh 串行全量构建,产物落到 .deps-harmony/ 前缀下,并通过 OBS_HARMONY_PREFIX 传给 libobs 的 cmake 命令行。60 个库中有少数需要改源码才能过编译,问题基本是平台探测脚本不认识 linux-ohos,修改 configure 的 case 分支即可,没有改动业务逻辑。这也说明开源 C 库的跨平台能力往往比预想更好,缺的通常只是让构建系统知道新平台存在。

libobs 平台层要补什么
libobs 对平台的依赖收敛得比较干净,移植重点在平台层三件套。obs-harmony.c 对应桌面版的 obs-windows/obs-posix,负责路径解析、崩溃处理、字符编码等“向操作系统要答案”的函数,其中 configData 等目录要映射到鸿蒙应用沙箱的 filesDir。platform-harmony.c 是前端侧平台代码,涉及文件监控、进程启动等。另一个重点是 libobs-opengl 的 EGL 后端:桌面 OBS 的 GL 后端假设 WGL/GLX/Cocoa 之一加桌面 GL 3.3,而鸿蒙只有 EGL + GLES 3.2,因此建 context、建 surface、swap buffer 这一层要换成 EGL 实现,纹理格式映射表也要按 GLES 重写。

这里还有一个后续才会暴露的风险点:桌面版 OBS 的 ffmpeg muxer 依靠启动子进程做封装隔离,而鸿蒙沙箱禁止 fork/exec 自带 ELF。静态验证期它只是“没测”,到真机上就会成为录制链路的第一个钉子。原文把这个问题留给录制篇展开,但在工程骨架阶段就应把它标成高风险项。

napi 桥:ArkTS 壳与 C++ 内核的边界
该迁移放弃了 Qt,原因是 Qt for OpenHarmony 生态较浅,且 OBS 的 Qt 前端和平台代码纠缠太深;UI 改用 ArkTS 重写。ArkTS 世界与 libobs 的 C 世界之间通过 napi 桥通信,核心文件是 obs_bridge.cpp。典型调用链是:ArkTS 页面点击“开始录制”,进入 ObsController 中介层,再调用 ObsBridge.startRecording(configJson),由 native 侧执行 obs_output_start(recOutput),随后异步回调启动成功或失败,并通过 boolean 加 stats 轮询通道回传,最后由 @Trace 状态刷新驱动按钮翻牌。

搭桥时确定了三条纪律。第一,所有 native 调用只从 ObsController 这一个中介层走,UI 组件不直接碰 napi 函数,这样状态更新、错误处理和乐观 UI 的修法都集中在一个文件里。第二,配置用 JSON 字符串过桥,录制参数、推流参数由 ArkTS 侧拼 JSON,C++ 侧用 obs_data_create_from_json 解析,省掉 napi 对象逐字段转换的样板代码。第三,UI 线程、图形线程、编码线程三线程模型从第一天就画清楚:libobs 的图形循环跑在 XComponent 的渲染线程上,编码有自己的 obs gpu encode thread,ArkTS 只负责状态展示。后来录制链路出现 SIGSEGV,原因是编码线程没有 GL context,能定位到“哪条线程缺什么”,正是依赖这个线程模型。

签名与 profile 核验
鸿蒙 HAP 必须签名才能装机。常规路径是打开 DevEco Studio 图形界面走向导,但整个移植是脚本化流水线,签名也要命令行化。使用 devecocli signature generate 一条命令完成密钥库、CSR、证书、profile 四件套。签完并不等于结束,profile 要核验三件事,每一件都对应一类“装上了但起不来”的故障:bundle-name 是否等于应用包名 com.obsproject.studio.harmony,不一致会直接拒装;目标设备的 UDID 是否在调试白名单里,换设备忘记加白名单时 install 报错很有误导性;受限权限是否进了 allowed-acls,例如 CUSTOM_SCREEN_RECORDING 录屏和 INPUT_MONITORING,这类权限不是声明了就给,profile 里没有 ACL 批准记录,运行时 API 就拿不到数据。

三段构建链与缓存陷阱
最终固化下来的构建链是三段:
  1. ./build-aux/harmony/build-obs.sh --skip-deps
  2. ./build-aux/harmony/stage-native.sh
  3. hvigorw assembleHap
复制代码
第一段用 cmake 编 libobs 和插件,产物进 staging;第二段把 staging 产物同步到 entry/libs 和 rawfile 资源;第三段做 ArkTS 编译、打 HAP 和签名。三段都有缓存,每一段都可能骗人:cmake 段改 effect 文件不重编,因为依赖跟踪没覆盖 data 目录;stage 段改了 libobs/data/*.effect 要手工同步源目录、rundir、rawfile 三处,漏一处真机行为纹丝不动;hvigor 段 PackageHap 在产物时间戳相近时会跳过重打包,HAP 里还是旧 .so。对策是打包前 mv 走旧 HAP 强制全链重打,装之前用 unzip -p HAP里的so | strings | grep 新日志标记 做进包验证。这种字符串级端到端验证,是多段构建链下排查问题的基础设施。

静态验证的边界
这一阶段最后产出了 check-contracts.sh,包含 38 项静态契约自检,例如 HAP 里 .so 齐不齐、rawfile 资源在不在、依赖闭包完整不完整,结果 38/38 PASS;verify-deps.sh 为 60/60 PASS;17MB 的 HAP 构建成功。但装机后图形后端起不来、插件一个加载不了、日志一行看不到,项目由此进入真机黑盒期。原文的提醒很关键:静态验证证明的是“你没写错”,真机验证证明的是“平台理解对了”,两者之间隔着的是另一整个工程学科。验证机为 HUAWEI MatePad Edge 的 PC/2in1 模式,HarmonyOS 7.0.0.109,API 26;OBS Studio 32.2.2,fork 分支为 qingkouwei/obs-studio@harmonyos-port。从系列最终结果看,这套交叉编译加 napi 骨架可以在 HarmonyOS PC/2in1 真机上实现插件全载、双轨混音出电平,但本篇阶段的核心仍是把 60 个依赖和 ArkTS/C++ 桥搭起来,真机问题才是下一阶段的入口。
回复

使用道具 举报

发表于 1 小时前 | 显示全部楼层

Re: OBS鸿蒙迁移实战:60个依赖交叉编译与napi桥搭建

看完很有收获,这篇把迁移路径、平台层、napi 桥、签名和构建缓存这几块串得很清楚,尤其认同把 fork/exec 和编码线程缺 GL context 提前标成高风险,这种在骨架阶段就记录“后面会炸”的做法很实用。三条桥接纪律也很关键,尤其是 UI 不直接碰 napi、配置走 JSON 字符串、三线程模型第一天画清楚,后面定位 SIGSEGV 时能少走很多弯路。构建缓存那段写得很真实,三段都可能骗人,用 strings 做进包验证确实是多段流水线下的基础手段。静态契约 38/38 和依赖 60/60 PASS 很漂亮,但最后对静态验证边界的说明也很诚实。真机阶段建议先做最小闭环烟测:确认 HAP 装机后图形后端能起、插件能加载、日志能落出来,再逐项验证录屏 ACL、napi 异步回调和录制链路;静态 PASS 不等于运行时可用,最好把 so 加载、EGL context、插件加载和日志通道也补成运行时契约。另外旧 HAP 强制移走、三处资源同步这类操作如果能固化进脚本入口,会比依赖记忆更稳。整体是很有工程价值的实战记录,期待录制篇展开。
回复 支持 反对

使用道具 举报

发表于 1 小时前 | 显示全部楼层

Re: OBS鸿蒙迁移实战:60个依赖交叉编译与napi桥搭建

这篇实战记录信息量很大,尤其是把“构建通过”和“真机能跑”之间的鸿沟讲得很清楚。几个点我印象比较深。 一是把 fork/exec 受限提前标成高风险,这个判断很关键。桌面 OBS 靠子进程做 muxer 隔离,到了鸿蒙沙箱里这条路直接走不通,静态验证阶段完全测不出来,等到真机录制才会炸。能在工程骨架阶段就把它拎出来,比后面救火强得多。 二是三段构建链的缓存陷阱总结得很实在。effect 文件改了 cmake 不重编、stage 要手工同步三处、hvigor 时间戳相近就跳过重打包,这几个坑几乎每段流水线都会踩。用 unzip 加 strings grep 新日志标记做进包验证,属于很土但极有效的办法,值得固化进脚本。 三是签名和 profile 那三件事拆得清楚。bundle-name、UDID 白名单、allowed-acls,各自对应一类“装上但起不来”的故障,比笼统说“签名失败”有用多了。尤其受限权限不是声明就给、还要 profile 里有 ACL 批准,这条对后来者能省不少时间。 关于 napi 桥那三条纪律,只从 ObsController 一个中介层走、JSON 字符串过桥、三线程模型第一天就画清楚,这套约束对 ArkTS 壳加 C 内核的组合挺合理。SIGSEGV 能定位到编码线程缺 GL context,靠的就是线程模型先立住了。 最后那段静态验证 38/38 通过
回复 支持 反对

使用道具 举报

发表于 1 小时前 | 显示全部楼层

Re: OBS鸿蒙迁移实战:60个依赖交叉编译与napi桥搭建

这篇实战记录信息密度很高,几个点特别有共鸣。 一是“60个库大部分只用改 configure 的 case 分支”这个判断。跨平台移植经常卡在构建系统的平台识别上,而不是代码本身。把这一点讲清楚,能让后来者少走很多弯路。 二是提前把 ffmpeg muxer 依赖 fork/exec、而鸿蒙沙箱禁止自带 ELF 这个风险标出来。静态验证期它“只是没测”,但真机上录制链路第一颗钉子就是它,这个判断很准。工程骨架阶段能把它列成高风险项,比后面踩坑了再回溯强得多。 napi 桥那三条纪律也很实在,尤其是用 JSON 字符串过桥,省掉逐字段转换的样板代码。ArkTS 和 C 世界边界越窄,后面出问题时要翻的文件越少。线程模型第一天就画清楚,后来 SIGSEGV 能定位到编码线程缺 GL context,这个收益很直观。 签名和 profile 那段是纯经验值。bundle-name 不一致、UDID 白名单、受限权限的 allowed-acls,这三件事都属于“装上了但起不来”的故障类型,排查时又很容易往代码方向想。命令行化签名的做法也符合脚本化流水线的思路。 三段构建链的缓存陷阱写得很真实,尤其“cmake 改 effect 不重编”和“hvigor 时间戳相近跳过重打包”这两类。用 mv 走旧 HAP 强制全链重打,再用 unzip 加 strings 抓新日志标记做进包验证,这种字符
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

本版积分规则

指导单位

江苏省公安厅

江苏省通信管理局

浙江省台州刑侦支队

DEFCON GROUP 86025

Hacking Group 021A

旗下站点

态势感知中心

应急响应中心

红盟安全

联系我们

官方QQ群:112851260

官方邮箱:security#ihonker.org(#改成@)

官方核心成员

关注微信公众号

Archiver|手机版|小黑屋| ( 沪ICP备2021026908号 )

GMT+8, 2026-10-31 01:53 , Processed in 0.025934 second(s), 28 queries , Gzip On.

Powered by ihonker.com

Copyright © 2015-现在.

  • 返回顶部