1 / 32 课程导览与音视频基础

第 0 课:开篇 —— 课程地图与一条主线

# 第 0 课:开篇 —— 课程地图与一条主线

本课目标:不写一行代码,先在脑子里装下两样东西 —— 一条贯穿全课的流水线,和一张能让你不再害怕大型源码的地图。 学完这一课,你会知道「点一下『开始直播』,画面到底经历了什么」,也会知道这门课接下来要带你去哪。


# 0.1 先说人话:这门课到底教什么

📍我们在哪:还没上流水线,先站在最高处看一眼 —— 这门课到底在教什么、为什么拿 OBS 当教具。

先容我打个招呼:我是小方,这门课的向导,后面这几十讲都由我陪你一路走完。

「音视频」三个字,常常一上来就把人吓退:YUV、码率、I 帧、采样率、RTMP、封装格式…… 每个词背后好像都藏着一篇论文。

但其实,所有这些术语,都只是在回答同一个问题的不同环节:

怎么把现实世界里的,变成电脑能处理的数据,压缩到能通过网络传走,最后在另一个人的屏幕上重新变回光和声?

这条「从现实 → 数据 → 传输 → 还原」的路,就是一条流水线。音视频领域几乎所有知识,都能挂到这条流水线的某一站上。这门课要做的,就是带你顺着这条流水线走一遍,每到一站,讲清楚那一站在干什么、为什么这么干。

而我们的「教具」,是一个叫 OBS Studio 的真实软件。

为什么选它?

  • 它真的在被几千万人用。全世界的主播、网课老师、会议录制都在用它,不是玩具 demo。
  • 它是开源的,源码完全公开,我们可以直接翻开看「工业级的做法长什么样」。
  • 它的流水线最全。采集、合成、滤镜、编码、录制、推流……音视频该有的环节它一个不少,是一份天然的完整教材。
  • 它跨平台(Windows / macOS / Linux),逼着代码把「通用逻辑」和「平台细节」分得很清楚,这种分层本身就很值得学。

需要:会读一点 C / C++ 语法(看得懂函数、结构体、指针即可),有一台能装 OBS 的电脑。 你不需要:任何音视频、图形学、信号处理的专业背景 —— 这些我们都会从零讲起。


# 0.2 一条主线:一帧画面的旅程

📍承上启下:上一节说「所有知识都能挂到一条流水线上」,这一节就把这条线摆出来 —— 采集→合成→编码→封装→送出,五站先走一遍。

想象你正在直播打游戏。你按下那个「开始直播」按钮的瞬间,你的游戏画面要经过下面这 5 站,才能出现在观众的屏幕上:

OBS 的核心流水线

这张图,请你记一辈子 —— 整门课就是把它拆开,一站一站讲透。 下面先快速过一遍每一站在干嘛(都是背景知识,看个大概就行):

# ① 采集(Capture)—— 把现实变成数据

电脑没法直接处理「光」和「声」,第一步必须把它们数字化:

  • 你的游戏画面、摄像头、桌面 —— 被采集成一张张图片(每秒几十张);
  • 你的麦克风、游戏声音 —— 被采集成一串串数字(声波的高低,每秒采上万次)。

这一站的产物,是没有经过任何压缩的原始数据(raw data)。它非常「忠实」,但也非常巨大(后面 0.5 节你会被它的体积吓一跳)。

# ② 合成(Composite)—— 把多个画面叠成一幅

直播画面往往不止一个来源:游戏画面打底,角落里叠一个摄像头小窗,再压一行字幕和一个 logo。合成就是把这些图层按位置、大小、层级叠在一起,算出最终「你看到的那一幅画面」。给画面磨皮、抠绿幕(色键)这类滤镜,也发生在这一站。这部分计算量很大,通常交给**显卡(GPU)**来做。

# ③ 编码(Encode)—— 把数据压小

原始数据太大了,根本传不出去(具体有多大,马上算给你看)。编码就是用各种聪明办法把它压缩,常常能压到原来的几百分之一,而人眼几乎看不出差别。这是整条流水线里「最像魔法」、也最值得理解的一站。H.264HEVCAV1 这些词,说的都是不同的视频编码方法。

# ④ 封装(Mux)—— 装进一个「盒子」

压缩后,你手里有「一条压缩过的视频流」和「一条压缩过的音频流」。封装(英文叫 mux,muxing 的缩写)就是把这两条流,加上时间戳、字幕等信息,装进一个统一的「盒子」里。MP4MKVFLV 这些就是不同的盒子(容器格式)。

一个常见的误区:MP4 不是一种编码,而是一种封装容器。同一个 .mp4 文件里,装的可能是 H.264 也可能是 AV1。「编码」和「封装」是两件事,这门课会反复帮你分清。

# ⑤ 推流 / 录制(Output)—— 送出去

最后一站有两个去向:

  • 录制:把封装好的数据写成本地文件,存到硬盘;
  • 推流:把数据通过网络协议(最常见的是 RTMP)实时发往直播平台的服务器,平台再分发给千千万万观众。

注意图最下面那行小字:声音和画面是两条并行的流水线。它们各自采集、各自处理,直到「编码 / 封装」阶段才汇合在一起。「音画同步」之所以是个需要专门解决的难题,根源就在于此 —— 我们会在模块 4 详谈。

🗒️ 术语速记:采集(拿到原始画面/声音)· 合成(把多个源叠成一画面)· 编码(压缩成小体积字节)· 封装(把音视频装进一个容器文件)· 推流/录制(发到服务器/写进硬盘)。特别注意:编码 ≠ 封装 —— 编码是"压得小",封装是"装进盒子",两回事。


# 0.3 第一次打开源码:OBS 的四大支柱

📍接上一节:流水线画完了,可它跑在几十万行源码上。这一节第一次翻开代码库,先把它归成四大支柱。

光有流水线还不够,我们的教材是几十万行的真实源码。第一次面对这么大的代码库,几乎所有人都会懵:「这么多文件夹,我该从哪看?」

别慌。再大的项目,顶层结构通常就那么几块。OBS 的源码可以归纳成四大支柱:

OBS 源码的四大支柱

  • libobs/ —— 引擎核心,用 C 语言写成。它是整台机器的「发动机」:定义了所有核心概念(源、场景、编码器、输出……),实现了图形和音视频管线。它不带任何界面,理论上别的程序也能拿它来做音视频处理。
  • frontend/ —— 桌面界面,用 C++ / Qt6 写成。就是你打开 OBS 看到的那个窗口:预览区、场景列表、混音器、那些按钮和设置对话框。它调用 libobs 来干活。
  • plugins/ —— 功能插件,运行时才被加载。采集屏幕、编码视频、推流到 RTMP、各种滤镜和转场…… 这些具体功能大多不在引擎里,而是一个个独立的插件。这是 OBS 最聪明的设计之一,我们模块 2 会专门讲。
  • shared/ —— 公共库,被界面和插件复用的「零件箱」,比如自动生成属性面板的控件、Lua / Python 脚本支持等。

图最下面那行还提到 libobs-d3d11 / libobs-opengl / libobs-metal —— 这是三套显卡渲染后端,分别对应 Windows、跨平台、macOS。libobs 在运行时挑一套来用。第 11 课会讲到它们。

# 看一眼真实代码:架构其实写在「构建脚本」里

不信「四大支柱」?我们直接翻开项目最顶层的构建脚本 CMakeLists.txtadd_subdirectory(X) 的意思就是「把 X 这个子模块纳入构建」,所以这一段几乎就是 OBS 的架构清单:

# CMakeLists.txt:22
add_subdirectory(libobs)              # ① 引擎核心
if(OS_WINDOWS)
  add_subdirectory(libobs-d3d11)      #   Windows 显卡后端
  add_subdirectory(libobs-winrt)      #   Windows 系统能力封装
endif()
add_subdirectory(libobs-opengl)       #   跨平台显卡后端
if(OS_MACOS)
  add_subdirectory(libobs-metal)      #   macOS 显卡后端
endif()
add_subdirectory(plugins)             # ③ 所有功能插件

add_subdirectory(test/test-input)

add_subdirectory(frontend)            # ② 桌面界面
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15

读懂这 13 行,你就已经掌握了 OBS 的「骨架」。注意那几个 if(OS_WINDOWS) / if(OS_MACOS) —— 这就是前面说的「通用逻辑」和「平台细节」分离的实际样子:核心和插件大家共用,只有平台相关的部分才按系统挑着编译进去。

顺带一提,这门课的运行环境是 Windows,所以举例多用 win-* 插件(如 win-capture 屏幕采集);但 macOS / Linux 都有结构对称的对应实现(mac-* / linux-*),换平台时思路完全一样。


# 0.4 把两张图对上:流水线 ↔ 源码

📍承上启下:一手拿着流水线(0.2)、一手拿着源码地图(0.3),这一节把两张图对上 —— 流水线的每一站,到底由哪段代码负责。

现在我们手上有了流水线(0.2)和源码地图(0.3),最关键的一步,是把它们对上 —— 流水线的每一站,到底由哪段源码负责?

流水线到源码的映射

这张对照表,就是这门课模块 3 ~ 6 的内容索引。你现在完全不需要看懂这些文件里的代码,只要建立起「哦,要研究采集就去 plugins/win-capture,要研究推流就去 plugins/obs-outputs」这种条件反射就够了。

# 再看一眼真实代码:认识五个主角

流水线的每一站,在引擎里都对应一种核心对象。打开引擎的总头文件 libobs/obs.h,有这么一段类型声明,把这门课后面要反复打交道的「主角」一次性介绍齐了:

// libobs/obs.h:60  (节选)
typedef struct obs_source     obs_source_t;       // 源:摄像头/屏幕/麦克风/滤镜/转场……一切皆源
typedef struct obs_scene      obs_scene_t;        // 场景:一组源的组合
typedef struct obs_scene_item obs_sceneitem_t;    // 场景里的一项(某个源 + 它的位置/大小)
typedef struct obs_output     obs_output_t;       // 输出:录制 / 推流的目的地
typedef struct obs_encoder    obs_encoder_t;      // 编码器:负责压缩
typedef struct obs_service    obs_service_t;      // 服务:Twitch / YouTube / B 站等平台定义
1
2
3
4
5
6
7

把它们和流水线对照一下,关系就清楚了:

流水线阶段 主角对象 一句话职责
采集 / 合成 obs_source_tobs_scene_tobs_sceneitem_t 产出和叠加画面/声音
编码 obs_encoder_t 把原始数据压小
封装 / 输出 obs_output_t 把数据写成文件或发往网络
推流目标 obs_service_t 描述「发到哪个平台、用什么地址」

这里有个 OBS 最核心、也最反直觉的设计:摄像头是 source,屏幕采集是 source,文字是 source,连「滤镜」和「转场」本质上也是 source。一个 obs_source_t 几乎能代表流水线前半段的一切。为什么这么设计、它带来了什么好处 —— 这是模块 2「OBS 的世界观」的核心,也是你真正读懂这套代码的钥匙。

(留意上面这些类型都是 typedef struct X *X_t 的「不透明指针」 —— 你只拿得到一个句柄,看不到结构体内部。这是 C 语言里实现「封装」的经典手法,第 7 课会讲它怎么管理对象的生与死。)

至于那个界面:程序的入口 main() 函数,就老老实实待在 frontend/obs-main.cpp:857。它启动 Qt 应用、初始化 libobs,然后把主窗口 OBSBasic 显示出来。这条线我们留到模块 7 再走。


# 0.5 临门一脚:为什么「编码」非有不可

📍转折:地图都铺好了,临进正课前先撞一次墙 —— 算一笔账,亲身体会流水线里「编码」那一站为什么生死攸关。

在进入正式课程前,做一道小学算术题,你就能亲身体会到流水线里编码那一站为什么是「生死攸关」的。

我们来算算:1080p、60 帧/秒的原始视频,一秒钟有多大?

  • 一帧画面是 1920 × 1080 个像素 = 约 207 万个像素;
  • 每个像素如果用 RGB 三个字节表示颜色,就是 3 字节;
  • 每秒 60 帧。

把它们乘起来:

1920 × 1080 × 3 字节 × 60 帧
≈ 3.73 亿字节/秒
≈ 356 MB/秒
≈ 2.85 Gbps(千兆比特/秒)
1
2
3
4

一秒钟接近 356 MB。 这意味着:

  • 你的硬盘大概几分钟就被一段视频塞满;
  • 而家用宽带的上传速度通常只有几十 Mbps —— 传输这条原始流,需要的带宽是它的几十上百倍,根本不可能。

所以你看,不压缩,直播这件事在物理上就不成立。而经过 H.264 编码后,同样这条 1080p60 的流,通常只需要 6 Mbps 左右就能获得很好的画质 —— 压缩比高达几百倍。这中间到底用了什么魔法,正是模块 5 要揭晓的。

这就是这门课的讲法:先让你撞上「为什么需要它」的墙,再去讲「它是什么」。 概念因此不再是凭空记忆的术语,而是一个个具体问题的答案。


# 0.6 这门课怎么学

📍收束:概念和源码都亮过相了,最后交代这门课怎么走 —— 每课固定三步、整体路线,再给你三条学习建议。

# 每一课,固定走三步

每课的三段式结构

  1. 直觉 —— 先用生活里的比喻把概念讲懂,不碰代码;
  2. 源码印证 —— 打开 OBS 的真实文件,看工程上到底怎么落地;
  3. 动手 / 观察 —— 给你一个小练习,或一个能在 OBS 界面里亲眼看到的现象,把知识坐实。

# 整体路线

课程路线图

路线的设计就是顺着流水线来的:先认识原材料(模块 1),再建立 OBS 的世界观(模块 2,全课地基,建议放慢),然后沿着视频 → 音频 → 编码 → 输出一路走(模块 3 ~ 6),接着把所有环节用前端串成整体(模块 7),最后动手写个插件收尾(模块 8)。

# 给你的三条学习建议

  • 不必一次看懂所有代码。本课程引用源码,目的是让你「看到真实工程的样子」,而不是逐行精读。看懂结构和主干即可,细节会在对应模块展开。
  • 善用 路径:行号。课程里所有源码引用都写成 libobs/obs.h:60 这种形式 —— 在编辑器里直接跳过去对照着看,效果远胜于干读文字。
  • 从模块 3 起,维护一份「探索笔记」。每课记下一个你在源码或 OBS 界面里亲眼观察到的现象。到第 29 课写插件时,这些笔记会自然串成你自己的理解。

关于「跑起来」:这一课我们只动眼不动手,还不需要你编译 OBS。如果你现在就想试,可以先装一个官方发行版的 OBS (opens new window) 用界面跟读;而从源码编译(用 CMake 预设,如 cmake --preset windows-x64)的完整步骤,我们放在第 1 课专门讲。


# 0.7 本课小结

  • 音视频的一切知识,都能挂到一条流水线上:采集 → 合成 → 编码 → 封装 → 推流 / 录制
  • 声音和画面是两条并行的流水线,到「编码 / 封装」才汇合 —— 这是「音画同步」难题的根源。
  • OBS 源码有四大支柱:libobs(引擎)、frontend(界面)、plugins(插件)、shared(公共库);它的架构几乎就写在顶层 CMakeLists.txt 里。
  • 流水线的每一站都对应源码里的具体位置和核心对象(obs_source_t / obs_encoder_t / obs_output_t …),其中 obs_source 是贯穿前半段流水线的灵魂
  • 不压缩,直播在物理上不成立 —— 这就是「编码」存在的理由,也是这门课「先撞墙、再讲解」讲法的缩影。

# 0.8 动手 / 观察(本课作业)

不需要写代码,只做两件「找一找」的小事:

  1. 在界面里找流水线:打开你电脑上的 OBS(没有就去官网装一个),试着指出界面上哪里对应「采集」(添加来源)、哪里对应「合成」(预览区里多个来源叠在一起)、哪里对应「输出」(开始录制 / 开始直播按钮)。
  2. 在源码里找支柱:用编辑器打开本仓库,确认 libobs/frontend/plugins/shared/ 四个目录都在;再打开 plugins/ 看一眼,数数里面大概有多少个插件子目录,感受一下「功能即插件」的设计。

# 下一课预告

第 1 课:认识 OBS 与它的源码全景 —— 我们将真正把这套源码编译运行起来(CMake 预设、依赖怎么来),并带你逐个目录走一遍,把今天这张「四大支柱」地图填充上更多细节。从下一课开始,我们就要动手了。


📁 本课配图:imgs/00-01 ~ imgs/00-05 📌 源码锚点:CMakeLists.txt:22libobs/obs.h:60frontend/obs-main.cpp:857libobs/obs-config.h(版本号)

上次更新: 2026/07/14, 19:37:40

社区交流

讨论与留言

前往 GitHub Issues →

本留言区仅对应当前文章,欢迎补充观点、提出问题或帮助修正文中疏漏。 留言由 GitHub/Gitalk 提供,需要使用 GitHub 登录。

最近更新
第 1 课:专栏导论与安全边界
07-01
第 3 课:安装编译与调试环境
07-01
第 4 课:第三方库下载、编译与依赖管理
07-01
更多文章>