尧图网站设计 尧图网站设计YAOTU DESIGN
ARTICLE DETAIL

资讯详情

深耕网站设计与一线实操的经验洞察。

OBS Studio 模块(Module)API 参考:libobs 插件的声明、导出与加载全解

OBS Studio 模块(Module)API 参考:libobs 插件的声明、导出与加载全解 OBS Studio 模块ModuleAPI 参考libobs 插件的声明、导出与加载全解【免费下载链接】obs-studioOBS Studio - Free and open source software for live streaming and screen recording项目地址: https://gitcode.com/GitHub_Trending/ob/obs-studioOBS Studio 的可扩展性建立在 libobs 的模块Module机制之上模块本质上是一个共享库.so/.dylib/.dll向 libobs 注入源source、编码器encoder、输出output和推流服务service等自定义功能。本文基于仓库官方 API 参考文档 reference-modules.rst 完整展开先讲模块对象的定义与声明宏再逐一解析插件必须导出/可选导出的函数最后覆盖前端frontend用于发现、打开和批量加载模块的整套 API并结合 libobs/obs-module.h 与 libobs/obs-module.c 的源码实现印证其底层行为。读完本文你将掌握编写、本地化、注册一个 libobs 插件模块的全部 API 契约以及前端如何安全地驱动插件生命周期。1. 模块对象obs_module_t文档首先定义了核心类型#include obs-module.hobs_module_t是一个模块对象不采用引用计数。在 libobs 内部它由模块管理器统一持有插件作者通常不需要手动创建或释放它——你通过obs_current_module()获取当前模块指针即可。模块的定位在 reference-core.rst 所在 API 参考目录中与核心对象、图形、媒体 I/O 等参考并列是整个插件体系源、编码器、输出、服务的宿主容器。2. 模块宏Module Macros2.1 OBS_DECLARE_MODULE()必需的模块声明OBS_DECLARE_MODULE()是每个 libobs 插件都必需的宏用于声明一个 libobs 模块并导出模块自身、OBS 版本等核心函数。看 libobs/obs-module.h 中该宏的真实展开内容它实际生成了三样东西#define OBS_DECLARE_MODULE() \ static obs_module_t *obs_module_pointer; \ MODULE_EXPORT void obs_module_set_pointer(obs_module_t *module); \ void obs_module_set_pointer(obs_module_t *module) \ { obs_module_pointer module; } \ obs_module_t *obs_current_module(void) \ { return obs_module_pointer; } \ MODULE_EXPORT uint32_t obs_module_ver(void); \ uint32_t obs_module_ver(void) \ { return LIBOBS_API_VER; }要点obs_module_set_pointer被 libobs 在打开模块时调用把模块指针注入插件obs_current_module()因此成为插件内当前模块的获取途径即 2.3 节外函数obs_module_ver()返回LIBOBS_API_VER这就是加载时版本兼容性检查的依据见第 5 节源码分析。2.2 OBS_MODULE_USE_DEFAULT_LOCALE()标准 ini 本地化OBS_MODULE_USE_DEFAULT_LOCALE(module_name, default_locale)是一个辅助宏使用标准 ini 文件格式做本地化。它自动初始化/销毁本地化数据并自动提供obs_module_text()等模块外函数让你以最小代价获取本地化字符串。从 libobs/obs-module.h 的宏展开看它一次性实现了四个函数生成函数作用obs_module_text(val)查表返回翻译串查不到时原样返回valfallback 到英文键名obs_module_get_string(val, out)查表成功返回true失败falseobs_module_set_locale(locale)用obs_module_load_locale(obs_current_module(), default_locale, locale)重建lookup_tobs_module_free_locale()销毁lookup_t并置空仓库中所有内置 C 插件都按此模式使用例如 plugins/image-source/image-source.cOBS_DECLARE_MODULE() OBS_MODULE_USE_DEFAULT_LOCALE(image-source, en-US) bool obs_module_load(void) { obs_register_source(image_source_info); obs_register_source(slideshow_info); return true; }第一个参数是插件名用于定位数据目录下的 locale 子目录第二个是回退语言。本地化数据以 ini 文件存放于插件数据目录例如 plugins/image-source/data/locale/ 下按语言组织的翻译文件。3. 模块导出函数Module Exports以下函数是插件模块可以或必须导出、用于与 libobs 及前端通信的符号。3.1 obs_module_load() —— 必需bool obs_module_load(void);必需导出。模块被加载初始化时调用。在此实现中加载模块的所有 source/encoder/output/service或任何需要在启动时完成的工作。返回true继续加载返回false表示失败libobs 会放弃该模块并记录告警日志见 libobs/obs-module.c 中obs_init_module对返回值false的处理blog(LOG_WARNING, Failed to initialize module ...)。典型实现见上文image-source示例把模块持有的struct obs_source_info逐个obs_register_source()注册。其他模块类型对应obs_register_encoder()、obs_register_output()、obs_register_service()。3.2 obs_module_unload() —— 可选但关键void obs_module_unload(void);可选导出。libobs 关闭、模块即将卸载前调用。此时所有 libobs 对象仍然有效。文档给出的三条纪律非常重要用此函数保存用户设置并释放模块自身持有的对 libobs 对象sources、canvases、outputs、encoders、services的强引用不要释放/销毁仍在使用中的模块所提供对象——返回后 libobs 可能还会调用模块的回调如destroy来清理剩余实例函数返回后除 libobs 回调之外不得再发起任何 libobs API 调用。3.3 obs_module_post_load() —— 可选void obs_module_post_load(void);可选导出。所有模块都完成加载后调用适合做依赖其他插件的初始化如 A 插件要使用 B 插件提供的功能B 可能尚未注册。3.4 本地化相关导出void obs_module_set_locale(const char *locale); // 设置 locale 语言并加载 locale 数据 void obs_module_free_locale(void); // 模块销毁时释放 locale 数据若使用了OBS_MODULE_USE_DEFAULT_LOCALE这两个函数已被宏自动生成无需手写。3.5 元信息导出可选const char *obs_module_name(void); // 模块全名 const char *obs_module_description(void); // 模块描述均为可选。实际插件中常用于描述插件用途例如image-source返回Image/color/slideshow sourcesplugins/image-source/image-source.c。libobs/obs-module.h 还额外提供了OBS_MODULE_AUTHOR(name)宏来导出作者信息前端插件管理器类界面即靠这些元信息展示插件卡片。4. 模块外函数Module Externs以下函数在整个模块内部可用无需显式传模块指针函数说明const char *obs_module_text(const char *lookup_string)返回本地化字符串bool obs_module_get_string(const char *lookup_string, const char **translated_string)本地化查表助手找到返回true否则falseobs_module_t *obs_current_module(void)返回当前模块指针由OBS_DECLARE_MODULE提供char *obs_module_file(const char *file)返回当前模块数据文件的绝对位置用bfree()释放等价于obs_find_module_file(obs_current_module(), file)char *obs_module_config_path(const char *file)返回当前模块配置文件的绝对位置无论文件是否存在配置目录未设置时返回NULL用bfree()释放等价于obs_module_get_config_path(obs_current_module(), file)后两个宏在 libobs/obs-module.h 中定义为#define obs_module_file(file) obs_find_module_file(obs_current_module(), file) #define obs_module_config_path(file) obs_module_get_config_path(obs_current_module(), file)它们是插件定位自身资源effect 文件、locale 文件、配置文件等的标准入口替代了手工拼接路径的做法。5. 前端模块函数Frontend Module Functions这一组函数由前端如 OBS Studio 主程序用于加载插件并获取插件信息。下面逐一说明并用 libobs/obs-module.c 的实现印证。5.1 obs_open_module()打开单个模块int obs_open_module(obs_module_t **module, const char *path, const char *data_path);从指定路径直接打开插件模块。若模块已存在则直接成功并返回已有模块的指针。注意它只加载模块映像加载符号表并不初始化模块要初始化需再调用obs_init_module()。参数module输出的模块指针path模块库文件路径省略扩展名时自动使用操作系统对应的扩展名.so / .dylib / .dlldata_path模块数据文件目录无则传NULL。返回码定义见 libobs/obs-defs.h宏值含义MODULE_SUCCESS0成功MODULE_ERROR-1通用错误MODULE_FAILED_TO_OPEN-2模块打开失败未找到或符号缺失旧名MODULE_FILE_NOT_FOUND已标记废弃MODULE_MISSING_EXPORTS-3缺少必需的导出符号MODULE_INCOMPATIBLE_VER-4版本不兼容MODULE_HARDCODED_SKIP-5被硬编码规则跳过例如 macOS 上已废弃的旧版 obs-browser 插件从 libobs/obs-module.c 的obs_open_module实现可以看到完整的打开流程参数校验module/path/全局obs任一为空直接MODULE_ERRORmacOS 上有硬编码跳过逻辑路径同时包含Library/Application Support/obs-studio和obs-browser时返回MODULE_HARDCODED_SKIP——这正是文档中MODULE_HARDCODED_SKIP示例的来源os_dlopen(path)打开库映像失败返回MODULE_FAILED_TO_OPENload_module_exports(mod, path)解析并绑定导出函数失败返回MODULE_MISSING_EXPORTS版本检查取obs_module_ver()的高 32 位忽略 patch 版本若大于当前LIBOBS_API_VER则判定用更新的 libobs 编译返回MODULE_INCOMPATIBLE_VER填充bin_path/文件名/模块名/data_path初始化 sources/outputs/encoders/services 四个动态数组并调用obs_module_load_metadata()元数据加载若data_path下存在manifest.json解析其中的display_name、id、version、os_arch、description、urls等字段libobs/obs-module.c供插件管理器展示最后通过mod.set_pointer(*module)把模块指针注入插件并立即用obs-locale调用插件的set_locale。5.2 obs_init_module()初始化模块bool obs_init_module(obs_module_t *module);初始化模块实际调用其obs_module_load导出。返回true表示加载成功。实现libobs/obs-module.c中有两处细节值得注意已加载的模块直接返回true幂等调用obs_module_load期间设置全局loadingModule上下文并用 profiler 记录每个模块的初始化耗时——这就是obs_module_load中注册资源时可安全使用注册 API 的原因。5.3 模块信息查询函数void obs_log_loaded_modules(void); // 在日志中打印已加载模块列表 const char *obs_get_module_file_name(obs_module_t *module); // 模块文件名 const char *obs_get_module_name(obs_module_t *module); // 模块全名无则 NULL const char *obs_get_module_author(obs_module_t *module); // 作者 const char *obs_get_module_description(obs_module_t *module); // 描述 const char *obs_get_module_binary_path(obs_module_t *module); // 二进制路径 const char *obs_get_module_data_path(obs_module_t *module); // 数据路径 void *obs_get_module_lib(obs_module_t *module); // 模块底层库句柄dlopen 句柄其中obs_get_module_name的取值优先级从实现可见libobs/obs-module.c优先取manifest.json的display_name否则回退到插件导出的obs_module_name()。5.4 批量发现与加载obs_add_module_path()void obs_add_module_path(const char *bin, const char *data);为obs_find_modules添加模块搜索路径。路径字符串中的%module%占位符会在实际使用时被替换为模块名。obs_find_modules() / obs_find_modules2()在已添加的搜索路径中查找所有模块结果通过回调逐条返回struct obs_module_info { const char *bin_path; const char *data_path; }; typedef void (*obs_find_module_callback_t)(void *param, const struct obs_module_info *info); struct obs_module_info2 { const char *bin_path; const char *data_path; const char *name; }; typedef void (*obs_find_module_callback2_t)(void *param, const struct obs_module_info2 *info);obs_find_modules2是 v2 版本回调结构体额外携带模块name字段。两个类型定义同时可在 libobs/obs.h 中找到。obs_load_all_modules() / obs_load_all_modules2()void obs_load_all_modules(void); void obs_load_all_modules2(struct obs_module_failure_info *mfi);便利函数自动从所有模块路径加载全部模块。v2 版本额外提供加载失败信息struct obs_module_failure_info { char **failed_modules; // 加载失败的模块列表字符串指针数组 size_t count; };释放方式调用obs_module_failure_info_free(mfi)或直接对failed_modules成员bfree()即可。实现位于 libobs/obs-module.c。obs_add_safe_module() 与 Safe Modevoid obs_add_safe_module(const char *name);将name加入安全模式Safe Mode允许加载的模块白名单若白名单为空则允许所有模块。name是去掉扩展名的文件名。自 30.0 版本引入。源码中可以看到其判定逻辑libobs/obs-module.cis_safe_module()在obs-safe_modules为空时对任意模块返回允许否则做精确名字比较——这解释了文档空列表即全放行的语义。其他生命周期函数void obs_module_failure_info_free(struct obs_module_failure_info *mfi); // 释放失败信息内部 bfree failed_modules void obs_post_load_modules(void); // 通知所有模块全部加载完成即批量回调各插件的 obs_module_post_loadobs_enum_modules()枚举已加载模块void obs_enum_modules(obs_enum_module_callback_t callback, void *param); typedef void (*obs_enum_module_callback_t)(void *param, obs_module_t *module);枚举当前所有已加载模块前端遍历插件列表如插件管理器界面的基础设施。5.5 模块文件/配置路径查询前端视角char *obs_find_module_file(obs_module_t *module, const char *file); char *obs_module_get_config_path(obs_module_t *module, const char *file);obs_find_module_file返回插件模块数据文件的位置未找到返回NULL字符串用bfree()释放。obs_module_get_config_path返回插件模块配置文件的路径无论文件是否存在配置目录未设置返回NULL。两者文档都特别注明模块内部应使用 obs-module.h 中定义的obs_module_file()/obs_module_config_path()宏它们省去显式传模块指针是更优雅的用法。6. 完整示例一个最小插件的 API 契约综合以上内容一个注册单个源、启用标准本地化的最小模块所需 API 面如下示例取自 libobs/obs-module.h 的文档内嵌示例与 plugins/image-source/image-source.c 的真实结构一致#include obs-module.h OBS_DECLARE_MODULE() OBS_MODULE_USE_DEFAULT_LOCALE(my-plugin, en-US) extern struct obs_source_info my_source; bool obs_module_load(void) { obs_register_source(my_source); return true; }各部分对应的 API 职责OBS_DECLARE_MODULE()导出obs_module_set_pointer/obs_current_module/obs_module_verOBS_MODULE_USE_DEFAULT_LOCALE自动生成obs_module_text、obs_module_get_string、obs_module_set_locale、obs_module_free_localeobs_module_load()唯一的必需导出返回false即加载失败其余obs_module_unload、obs_module_post_load、obs_module_name、obs_module_description均按需导出可选地在数据目录放置manifest.json提供display_name/id/version/description等元数据供前端展示。7. 小结模块加载全链路把前端函数按实际执行顺序串起来即为 libobs 插件的完整生命周期obs_add_module_path(bin, data) // 注册搜索路径支持 %module% 占位 → obs_find_modules(2)(callback) // 发现候选模块 → obs_add_safe_module(name) // 可选安全模式白名单 → obs_open_module(mod, path, data) // dlopen 导出检查 版本检查 manifest 元数据 → obs_init_module(mod) // 调用插件 obs_module_load() → obs_post_load_modules() // 触发各插件 obs_module_post_load() → obs_log_loaded_modules() // 日志留痕任何一步失败的诊断入口都有据可查obs_open_module的返回码区分找不到/符号缺失/版本过新/被硬编码跳过四类失败obs_load_all_modules2struct obs_module_failure_info批量给出失败模块清单而obs_log_loaded_modules与obs_find_modules2则提供了成功侧的审计能力。适用前提本文所有行为均以当前仓库master代码为准API 声明集中在 libobs/obs.h 与 libobs/obs-module.h实现在 libobs/obs-module.c。obs_add_safe_module自 30.0 引入MODULE_FILE_NOT_FOUND已由MODULE_FAILED_TO_OPEN取代并标记废弃。参考文档docs/sphinx/reference-modules.rst同级 API 参考还包括 Core、核心对象、Graphics 与 Media I/O。【免费下载链接】obs-studioOBS Studio - Free and open source software for live streaming and screen recording项目地址: https://gitcode.com/GitHub_Trending/ob/obs-studio创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表