第 1 课:认识 OBS 与它的源码全景
# 第 1 课:认识 OBS 与它的源码全景
本课目标:把这套源码真正编译运行起来,亲手得到一个能跑的
obs64.exe; 然后把第 0 课那张「四大支柱」地图填上完整细节 —— 顶层每个目录是干嘛的,引擎和界面内部又是怎么分块的。 从这一课开始,我们动手了。
上一课我们建立了两样东西:一条流水线(采集→合成→编码→封装→输出)和一张源码地图(四大支柱)。这一课不引入新的音视频概念,而是把「地图」走实 —— 因为后面每一课都要回到这套源码里翻代码,你得先能把它跑起来、找得到路。
# 1.1 先补一点背景:一个 C/C++ 项目是怎么「变成」程序的
📍我们在哪:这一课不碰新的音视频概念,只把「地图」走实。开头先补个背景 —— C/C++ 源码是怎么一步步变成能跑的程序的。
如果你之前只写过 Python、JavaScript 这类「写完直接跑」的语言,那么 C/C++ 项目的「构建」过程可能有点陌生。先花两分钟把它讲清楚,后面才不会懵。
C/C++ 是编译型语言:你写的源码(.c / .cpp 文本文件)电脑没法直接执行,必须先经过两步,翻译成机器能跑的二进制:
- 编译(compile):把每个源文件翻译成「目标文件」(机器码片段);
- 链接(link):把所有目标文件、加上用到的第三方库(比如负责编解码的 FFmpeg、负责界面的 Qt),拼装成最终的可执行文件
.exe和动态库.dll。
这里有三个新手常卡住的概念,用一个「盖房子」的比喻一次说清:
| 概念 | 是什么 | 盖房子比喻 |
|---|---|---|
| 源码 | 你写的 .c / .cpp | 设计图纸 |
| 依赖库(dependencies) | 别人写好的现成功能(FFmpeg、Qt…) | 预制好的门窗、水管 |
| 编译器(MSVC / Clang / GCC) | 把源码翻译成机器码的工具 | 施工队 |
| 构建系统(CMake) | 指挥「先编什么、后链接什么、去哪找依赖」 | 施工说明书 / 总包 |
OBS 用 CMake 当「施工说明书」。你不直接跟编译器打交道,而是告诉 CMake「我要在 Windows 上构建」,它替你生成一份 Visual Studio 工程,再驱动编译器干活。
关键的好处:同一份 CMake 说明书,在 Windows 上生成 VS 工程、在 macOS 上生成 Xcode 工程、在 Linux 上生成 Ninja 工程 —— 一套源码,三个平台都能构建。这就是第 0 课说的「跨平台」在工程上的落地方式。
# 1.2 依赖从哪来:你不用自己编译 FFmpeg
📍承上启下:知道了要「编译 + 链接」,那 FFmpeg、Qt 这些大零件从哪来?这一节讲 OBS 怎么替你把依赖自动拉下来。
新手做 C/C++ 多媒体项目,最大的拦路虎往往是「依赖地狱」—— 光是把 FFmpeg、Qt 这些大块头编译出来就能耗掉一整天。
OBS 的做法很贴心:这些大依赖你完全不用自己编译,构建时会自动下载官方预编译好的包。 我们来看看这套机制长什么样。
打开仓库根目录的 CMakePresets.json,里面有一段 dependencies,把每个依赖的版本和哈希值钉得死死的:
// CMakePresets.json(节选)
"prebuilt": { // 通用依赖:FFmpeg、x264、curl…
"version": "2025-08-23",
"hashes": { "windows-x64": "8de229cff6f1..." }
},
"qt6": { // 界面框架 Qt6
"version": "2025-08-23",
"hashes": { "windows-x64": "c62e82483bc7..." }
},
"cef": { // 浏览器源用的 Chromium 内核
"version": "6533", ...
}
2
3
4
5
6
7
8
9
10
11
12
那「下载」这个动作是谁、什么时候触发的?答案在构建脚本里。顶层 CMakeLists.txt 会 include(defaults),而在 cmake/windows/defaults.cmake:24 有这么一行:
# cmake/windows/defaults.cmake:24
include(buildspec)
2
这个 buildspec 模块的结尾(cmake/windows/buildspec.cmake:84 的 _check_dependencies_windows())会在你配置(configure)阶段自动:读取上面那些版本和哈希 → 从 OBS 官方服务器下载对应的 zip → 校验哈希 → 解压到项目根目录的 .deps/ 文件夹。
下载解压完,.deps/ 大概是这样:
.deps/
├── obs-deps-2025-08-23-x64/ # FFmpeg、x264、curl、librist… 一大堆通用库
├── obs-deps-qt6-2025-08-23-x64/ # Qt6 界面框架
└── windows-deps-*.zip # 下载下来的原始压缩包(缓存)
2
3
4
一句话:
.deps/不是源码,是构建时自动拉下来的「预制零件」,不需要你手动管。 这也是为什么这个目录通常不进版本库。
# 1.3 动手:把 OBS 编译运行起来
📍承上启下:背景和依赖都清楚了,这一节真刀真枪跑一遍 —— 四条命令,把源码编成一个能启动的 obs64.exe。
理论铺垫够了,现在真刀真枪跑一遍。下面以本课环境 Windows x64 为例。
# 前置工具
- Visual Studio 2022(含「使用 C++ 的桌面开发」工作负载,自带 MSVC 编译器和较新的 Windows SDK)
- CMake ≥ 3.28(VS 2022 一般自带,也可单独装)
- Git
# 四步走
# 1) 拉源码 —— 注意 --recursive,OBS 有几个子模块(下面 1.3 会解释)
git clone --recursive https://github.com/obsproject/obs-studio.git
cd obs-studio
# 2) 配置:用预设生成 Visual Studio 工程;依赖会在这一步自动下载到 .deps/
cmake --preset windows-x64
# 3) 编译:把引擎、所有插件、界面一次性全部编出来
cmake --build --preset windows-x64
2
3
4
5
6
7
8
9
这套「配置 → 编译 → 产物」的流程,正是第 0 课那条流水线在构建层面的样子:

第 4 步:运行。 编译产物全在
build_x64/rundir/<配置>/下,双击build_x64/rundir/RelWithDebInfo/bin/64bit/obs64.exe(或Debug/,取决于你编的配置)就能启动。偏好图形界面?第 2 步之后,直接用 Visual Studio 打开
build_x64/obs-studio.sln,把obs-studio设为启动项目,按 F5 即可 —— 因为windows-x64预设用的就是「Visual Studio 17 2022」生成器。
# 关于子模块:为什么要 --recursive
刚才让你加 --recursive,是因为 OBS 把几个组件以 git 子模块的形式挂在仓库里,源码并不直接躺在主仓库中。看 .gitmodules:
# .gitmodules
[submodule "plugins/obs-browser"] # 浏览器源(基于 CEF)
[submodule "plugins/obs-websocket"] # WebSocket 远程控制
[submodule "plugins/win-dshow/libdshowcapture"] # DirectShow 采集库
2
3
4
如果忘了 --recursive,这几个目录会是空的,构建时报错。补救命令:
git submodule update --init --recursive
⚠️ 顺带记一条坑:
.github/scripts/Build-Windows.ps1是给 CI 自动化用的,它开头就检查$env:CI,在你本地直接跑会报错退出。本地开发请用上面的cmake --preset命令,别去碰那个脚本。
# 一次成功的构建产出了什么
构建跑完,build_x64/rundir/<配置>/ 就是一个自包含的、可直接运行的 OBS:

bin/64bit/—— 主程序obs64.exe和它运行所需的一堆 DLL(Qt 界面框架、FFmpeg、三套渲染后端libobs-d3d11/opengl/winrt…);obs-plugins/64bit/—— 编译出来的 26 个插件 DLL(屏幕采集、x264 编码、RTMP 推流、各种滤镜……),OBS 启动时会扫描并加载它们;data/—— 运行时资源:主题、多语言文案、内置着色器(.effect)、脚本运行时等。
把这三块放在一起,就是你平时双击运行的那个 OBS。注意「程序」和「插件」是分开的两块 —— 这个「功能即插件」的设计,是理解 OBS 的关键,模块 2 会专门讲。
# 1.4 填满地图(一):顶层目录全景
📍接上一节:程序能跑起来了,回头把第 0 课那张「四大支柱」草图,填成完整的顶层目录清单。
能跑起来了,现在把第 0 课的「四大支柱」展开成完整的顶层目录清单。第 0 课我们说过,这张图几乎就写在顶层 CMakeLists.txt:22 的 add_subdirectory(...) 列表里:

按职责分成三组看:
- 引擎核心与渲染后端:
libobs是发动机;libobs-d3d11(Windows)、libobs-opengl(跨平台)、libobs-metal(macOS)是三套显卡渲染后端,运行时挑一套用;libobs-winrt封装 Windows 特有能力。 - 应用层与扩展:
frontend(界面)、plugins(功能插件)、shared(公共库)。我们日常开发改动最多的就是这三块。 - 依赖、构建与文档:
deps(随源码自带的小型第三方库,和上面自动下载的大依赖不是一回事)、cmake(构建脚本)、test、docs。
小心区分两个「依赖」:
deps/—— 随源码自带的小型库(blake2、glad、json11…),直接参与编译;.deps/—— 构建时自动下载的大型预编译包(FFmpeg、Qt…)。一个带点(隐藏目录)、一个不带,别搞混。
# 1.5 填满地图(二):拆开引擎 libobs
📍承上启下:顶层看完,钻进最重要的那块 —— 引擎 libobs,看它内部怎么分「核心对象」和「底层系统」两层。
libobs 是整门课的主战场(模块 2~6 几乎都在它里面打转),值得现在就拆开看看内部结构:

它分两层:
顶层的 obs-*.c 文件 = 核心对象的实现。 还记得第 0 课在 libobs/obs.h:60 看到的那几个主角吗?它们各自的实现就在这里:obs-source.c(源)、obs-scene.c(场景)、obs-output.c(输出)、obs-encoder.c(编码器)、obs-service.c(服务)。文件名和概念一一对应,非常好找。
子目录 = 支撑这些对象的底层系统:
util/(57 个文件)—— C 语言工具层:内存管理、线程、动态数组、obs-data(类 JSON 的配置载体);graphics/—— 渲染抽象:纹理、着色器(.effect文件)、矩阵运算;media-io/—— 音视频帧的管线:audio-io、video-io、格式转换、重采样 —— 这是流水线里「数据怎么流动」的地基;callback/—— 信号与回调系统(模块 2 的重点);audio-monitoring/—— 音频监听回放;data/—— 内置着色器和多语言文案。
阅读引擎时,libobs/obs.h 就是大门 —— 它把所有核心对象一次性声明齐全,从它出发顺藤摸瓜最省力。
# 1.6 填满地图(三):界面 frontend
📍收束:最后扫一眼界面这一侧 frontend,把地图的最后一块补齐 —— 记住 main() → OBSApp → OBSBasic 这条启动线就够了。
最后看一眼界面这一侧。frontend 是用 C++ / Qt6 写的桌面程序,它的结构可以先建立个印象(细节留到模块 7):

启动链路就三步,记住这条线,以后想从界面追代码就有了起点:
frontend/obs-main.cpp:857 → OBSApp → OBSBasic
main() 入口 Qt 应用 主窗口(你看到的一切)
初始化 libobs
2
3
程序从 frontend/obs-main.cpp:857 的 main() 启动,创建 OBSApp(它继承自 Qt 的应用类,负责初始化 libobs),最后把主窗口 OBSBasic 显示出来。
界面的其余部分按功能拆成一堆目录:widgets/(主窗口和控件)、dialogs/(对话框)、docks/(可停靠面板)、settings/(设置)、components/(可复用组件)、forms/(Qt Designer 的 .ui 界面文件)、api/(给前端插件用的 obs-frontend-api)等。
你可能会好奇:主窗口
OBSBasic怎么会有OBSBasic_Streaming.cpp、OBSBasic_Recording.cpp、OBSBasic_Scenes.cpp这么多文件?那是因为主窗口功能极多,OBS 把同一个类按功能切分到几十个.cpp文件里实现,避免单个文件几万行。这是大型 Qt 项目的常见手法,模块 7 细讲。
# 1.7 本课小结
- C/C++ 项目要经过编译 + 链接才变成可执行文件;OBS 用 CMake 当「施工说明书」统一指挥,从而做到一套源码跨三平台构建。
- 大依赖(FFmpeg / Qt / CEF)不用自己编译:
configure阶段由buildspec按CMakePresets.json里钉死的版本和哈希,自动下载预编译包到.deps/。 - 本地构建就四步:
git clone --recursive→cmake --preset windows-x64→cmake --build --preset windows-x64→ 运行build_x64/rundir/<配置>/bin/64bit/obs64.exe。(Build-Windows.ps1是 CI 专用,本地别用。) - 一次构建产出一个自包含可运行目录:
bin/(主程序+DLL)、obs-plugins/(26 个插件)、data/(资源)。 - 顶层目录可归为三组:引擎与渲染后端 / 应用层与扩展 / 依赖构建文档;引擎
libobs内部是「顶层obs-*.c核心对象 + 子目录底层系统」;界面从obs-main.cpp的main()经OBSApp到OBSBasic。
# 1.8 动手 / 观察(本课作业)
- 跑通构建(有环境的话):按 1.3 的四步编译出
obs64.exe并运行。第一次构建会下载依赖、耗时较长,泡杯茶等它。 - 数插件:进到
build_x64/rundir/<配置>/obs-plugins/64bit/,数一数有多少个.dll;再到data/obs-plugins/看看每个插件还带了哪些资源文件。 - 认一个插件:打开
plugins/win-capture/(屏幕采集),看一眼它的CMakeLists.txt和源码文件名 —— 不用读懂,只要感受一下「一个插件大概由哪些文件组成」。我们模块 3 会真正把它拆开。
# 下一课预告
铺垫到此结束,从下一课起进入正题。
第 2 课:视频的本质就是连续的图片 —— 我们会离开源码一小会儿,先把「像素、分辨率、帧、帧率」这些最基础的视频概念用大白话讲透,再回到 libobs/media-io/ 看 OBS 是怎么定义「一帧」的。这是理解整条视频链路的第一块砖。
📁 本课配图:
imgs/01-01~imgs/01-05📌 源码锚点:CMakePresets.json、cmake/windows/defaults.cmake:24、cmake/windows/buildspec.cmake:84、CMakeLists.txt:22、.gitmodules、libobs/obs.h:60、frontend/obs-main.cpp:857
本留言区仅对应当前文章,欢迎补充观点、提出问题或帮助修正文中疏漏。 留言由 GitHub/Gitalk 提供,需要使用 GitHub 登录。
社区交流
讨论与留言