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

第 5 课:裸数据有多可怕

# 第 5 课:裸数据有多可怕

嘿,我是小方。 这是「模块 1:音视频原材料」的收官课。前面四课,咱们把画面(像素、分辨率、颜色)和声音(采样、位深、声道)都拆开看遍了。今天我不塞新概念,就陪你踏踏实实算一笔账 —— 一笔会让你倒吸凉气的账。 算完这笔账,有件事你会刻进脑子里:从「采集」往后,每一步都非压缩不可。 这,正是下一个模块的主角 —— 编码 —— 存在的全部理由。 这一课我特意写得细,你跟着我一个数一个数地推,别跳。


# 5.1 算账之前,先扫清三个单位坑

📍我们在哪:模块 1 的收官课,不塞新概念,就踏实算一笔账。动手前先扫平三个最坑人的单位陷阱。

我知道你想直接看那个吓人的大数字。但小方先拦你一下 —— 这一整课全是数字,而我教书这些年发现,新手十有八九不是被概念绊倒,是被「单位」绊倒的。 咱们先花两分钟,把三个最容易踩的坑填平,后面你自己算才不会算歪。

三个单位坑

坑一:字节(Byte)和比特(bit),差 8 倍。 1 个字节 = 8 个比特。这俩老被混用,记个口诀:大写 B 是字节(量文件、量存储),小写 b 是比特(量网速、量码率)。所以 356 MB356 Mb 完全不是一回事,差了整整 8 倍。

坑二:体积用字节,速度用比特。 文件多大,用 MB / GB(字节);网络多快、码率多高,用 Mbps / kbps(比特每秒)。这就是为什么待会儿你会看到「356 MB/秒」一转身变成「2850 Mbps」—— 它俩说的是同一股数据流,只是一个按字节量、一个按比特量,中间差着 ×8。

坑三:1024 还是 1000? 你电脑里 1 KB 其实是 1024 字节,可硬盘厂商按 1000 算(所以你买的「1TB 硬盘」装进系统只剩 931 GB)。这点零头到了 TB 级会有点显眼,但本课一律取近似,咱不跟这 2% 较劲。

看图最底下那两行换算,后面我会反复用到,你先眼熟:

  • 356 MB/s × 8 ≈ 2850 Mb/s —— 裸视频流的「网速」,就是这么换算出来的;
  • 6 Mb/s ÷ 8 = 0.75 MB/s —— 压缩后的码率,换算成体积是这么小。

好,坑填平了,开算。


# 5.2 一帧画面,到底多大

📍承上启下:单位坑填平了,开算 —— 从最小的一块砖起步:一帧 1080p 的画面,到底占多大。

老规矩,以最常见的直播规格 1080p、60 帧/秒 为例。我带你一步一步推,每个数都讲清楚怎么来的:

第 1 步:一帧有多少像素?
   1920 × 1080 = 2,073,600 个像素          ← 第 2 课:分辨率

第 2 步:每个像素多少字节?
   3 字节(R、G、B 各 1 字节)              ← 第 3 课:RGB

第 3 步:一帧多大?
   2,073,600 × 3 = 6,220,800 字节 ≈ 6 MB
1
2
3
4
5
6
7
8

一帧,差不多 6 MB —— 跟你手机里一张高质量照片一样大。注意,这还只是静止的一帧

第 4 步:一秒多大?(60 帧)
   6 MB × 60 = 356 MB / 秒
1
2

停。你先把这个数嚼一下:一秒钟,356 MB。 打个比方 —— 你下一部高清电影(压缩过的)大概 5 GB,够看俩小时;而这里仅仅 14 秒的裸视频,体积就追平了一整部电影。

小方多嘴一句:你可能想起第 3 课说过「OBS 内部会转成 NV12,只要 1.5 字节」。对,转成 NV12(4:2:0)能砍一半,变成 ~178 MB/秒。但你别急着松气 —— 砍一半,它还是大得离谱。 这一课为了和第 2 课对得上,我先用 3 字节的 RGB 算;就算打对折,后面的结论一个字都不用改。


# 5.3 顺着时间往上叠,数字开始失控

📍承上启下:一帧不吓人,可视频是「每秒几十帧、一播好几小时」地连乘 —— 这一节看体积怎么滚雪球滚到失控。

一秒 356 MB 已经够呛了,可直播又不是只播一秒。咱们顺着时间往上乘,你盯着这个数怎么一路失控:

裸视频体积阶梯

  • 1 帧 ≈ 6 MB —— 一张照片;
  • 1 秒 ≈ 356 MB —— 大半张 CD;
  • 1 分钟 ≈ 21 GB —— 塞得下 4~5 部压缩电影;
  • 1 小时 ≈ 1.2 TB —— 塞爆一块 1TB 硬盘,还装不下。

你没看错,播一个小时,裸视频要 1.2 TB。 你辛辛苦苦买的那块 1TB 固态,连一小时直播的原始画面都存不下。想录三小时游戏实况?行,先去备三块盘。

这就是裸数据最反直觉的地方:单看一帧不起眼,可视频是「每秒几十帧、一播好几小时」地连乘,体积是滚雪球滚出来的。

# 换个旋钮,体积差几倍?

光看 1080p60 一个规格还不过瘾。我把常见的几档分辨率、帧率摆一张表,你直观感受一下「每调一个旋钮,体积怎么翻」:

多档规格裸体积对照

读这张表,你能立刻看出两条规律:

  • 帧率翻倍,体积翻倍(同一行,30fps → 60fps,数字 ×2);
  • 分辨率每升一档,体积涨得更猛(720p → 1080p → 4K,因为宽高同时变大,是相乘的关系)。

最右下角那个 4K60 的 4.9 TB/小时,颜色我都给它标成最红的了 —— 你要是拿它录裸数据,一块 8TB 的大硬盘也撑不过一个半小时。这下你该明白,为什么 OBS 里那两个不起眼的「分辨率」「帧率」下拉框,背后牵动的是这么夸张的数据量了吧。


# 5.4 别忘了音频那笔账

📍承上启下:画面的账算完,顺手补上声音这笔 —— 你会看到 PCM 虽也不小,和视频一比却几乎可以忽略。

讲了半天画面,声音呢?咱们第 4 课认识的 PCM(裸音频),也来记一笔账。用 OBS 默认的 48000 Hz、16 位、立体声:

   48000 次/秒 × 16 位 × 2 声道
 = 1,536,000 位/秒
 ≈ 1.5 Mbps
 ≈ 一小时约 0.68 GB
1
2
3
4

一小时,音频裸数据约 0.68 GB。 你把它和视频的 1.2 TB 放一起比比 —— 1.2 TB ≈ 1200 GB,音频那 0.68 GB,连零头的零头都算不上,占比 0.06%。

这恰好印证了第 4 课那句话:一条声波,远比一整幅画面信息少。 所以咱们这一课的主角始终是视频 —— 音频虽然也得压(MP3、AAC 那些),但它从来不是体积上的大头。后面凡是讲「数据太大」,你脑子里默认想的就是视频,八九不离十。


# 5.5 就算你存得下,也传不出去

📍转折:前面卡在「存不下」;这一节把矛头转向直播真正的堵点 —— 「传不出去」,家里那点上行带宽根本喂不动裸流。

你可能会说:硬盘便宜,我多买几块不就完了?

录制也许还能靠硬盘硬扛(这事 5.6 还要细说),但直播这条路,堵点根本不在「存」,在「传」—— 你得把数据通过网络,实时送到直播平台的服务器。而这里有一道绕不过去的窄门:你家宽带的上行带宽。

带宽闸门

把数字摆出来(还记得 5.1 的换算吧):

  • 裸视频流 = 356 MB/秒 ×8 ≈ 2850 Mbps;
  • 普通家庭宽带的上行,通常也就 几十 Mbps(对,上传往往比下载慢一大截)。

你品品:你要往外推 2850 Mbps,可你的管子只有 50 Mbps 粗 —— 裸流比你的上行粗了将近 60 倍。 这就像你想把消防水管里的水,全塞进一根吸管,物理上根本办不到。

我再给你换个更扎心的算法。假设你不嫌慢,就想把这一小时的裸视频(1.2 TB)用 50 Mbps 的小水管慢慢上传,要花多久?

   1.2 TB ≈ 9,600,000 Mb(比特)
 ÷ 50 Mbps
 = 192,000 秒 ≈ 53 小时
1
2
3

传 1 小时的裸视频,要花你 53 个小时。 直播讲究的是「实时」,而这个传输速度,比实时慢了 53 倍 —— 这哪是直播,这是「直播到下周」。

所以结论很硬,没有商量余地:

不压缩,直播这件事,在物理上就不成立。

这不是「慢一点、卡一点」,是压根做不到


# 5.6 录制 vs 直播:两种不同的「紧箍咒」

📍承上启下:一个怕存不下、一个怕传不出 —— 这一节把录制和直播两种压力拆开讲清,它直接决定你以后怎么设置 OBS。

刚才说录制能靠硬盘硬扛 —— 但其实录制也逃不开编码,只是它头上的紧箍咒和直播不一样。这俩的区别值得专门拎出来讲一下,因为它直接关系到你以后怎么设置 OBS。

录制 vs 直播的两种压力

  • 录制(存到本地),怕的是「存不下」:

    • 压力来源:硬盘容量 + 写入速度;
    • 对编码的要求宽松些 —— 码率可以给高一点(本地盘够大,追求画质),而且能「慢工出细活」(不用实时,编慢点没人催);
    • 翻车点:盘写满,或者写入速度跟不上。你想啊,要是真存裸数据,得每秒持续往盘里写 356 MB,普通硬盘根本扛不住,直接掉帧给你看。
  • 直播(推到网络),怕的是「传不出」:

    • 压力来源:上行带宽 + 实时性;
    • 对编码的要求苛刻 —— 码率必须死死卡在带宽以内,必须实时编码(慢一帧观众就卡一下),还得能扛住网络抖动、断流重连;
    • 翻车点:带宽不够 → 画面卡顿、掉线。

你看,两条路的痛点不同,但都绕不开「编码」这一关。 录制是「能存得更省、写得更快」,直播是「能传得出去、还得实时」。正因为需求不一样,OBS 才在「录制」和「直播」里给了你两套独立的编码设置 —— 这些咱们留到**模块 6(输出)**分头细讲。这里你先记住这个「一个怕存、一个怕传」的框架。


# 5.7 编码登场:把 1.2 TB 变成 2.7 GB

📍转折:账算到这儿,主角终于该登场了 —— 在「采集」和「传输」之间插一步魔法「编码」,把 1.2 TB 狠狠压成 2.7 GB。

那为什么我们今天还能流畅地直播、刷视频?因为在「采集」和「传输」之间,有一步魔法,把数据狠狠压小 —— 它就叫编码(也叫压缩)。

到底能压多狠?咱们把一小时直播的账,压缩前后并排放:

一小时直播的总账

左边没压缩:1.2 TB(视频占 99.9%,音频那 0.68 GB 几乎可忽略,又一次印证了 5.4)。 右边压缩后,用 OBS 默认码率:只要 2.7 GB

 1.2 TB  ──编码──►  2.7 GB     体积砍到约 1/460
1

同一块 1TB 硬盘,装裸数据撑不到一小时;装压缩后的,能存约 370 小时。这就是编码的威力。

再换个角度,看看这个压缩比有多离谱:

压缩比

同样一秒 1080p60 的画面,从 356 MB 压到 不到 1 MB(0.75 MB),约 500 倍。而最神的是 —— 压完之后,你用肉眼几乎看不出差别

你肯定憋着一个问题:凭什么能压这么狠,还几乎不掉画质?我先剧透三个直觉,正菜留给模块 5:

  1. 相邻两帧,大半是重复的 —— 你打游戏,这一帧和上一帧,可能只有准星附近动了动,背景一动没动。那何必把整张图重存一遍?只记「变了的那点」就够了。
  2. 一帧之内,大片颜色是相近的 —— 一面白墙、一块蓝天,成千上万个像素几乎一个色。这种「扎堆」的信息,能用很省的方式描述。
  3. 人眼看不清的,干脆丢掉 —— 还记得第 3 课的 YUV 吗?人眼对颜色迟钝,那就少存颜色。编码把这套「欺负感官」的思路用到了极致。

这三招(帧间、帧内、感知),就是模块 5「编码」的全部精髓。


# 5.8 顺手破三个常见误会

📍承上启下:懂了编码这步魔法,顺手把新手最容易犯的三个误会一次说清,省得你以后犯迷糊。

讲到这儿,新手脑子里通常会冒出三个疑问。小方一次性给你说清,省得你以后犯迷糊:

误会一:「我硬盘里的 .mp4 不就是裸数据吗?」 不是。.mp4 是个盒子(容器),里面装的是已经编码压缩过的数据(还记得第 0 课分清的「编码 ≠ 封装」吗?)。事实上,你平时根本接触不到裸数据 —— 相机存卡里是压缩的,网上下的是压缩的,微信发的还是压缩的。裸数据只活在采集到编码之间那一瞬,转眼就被压掉了。

误会二:「既然有硬盘,录制为什么不直接存裸数据?」 两个原因。一是存不起:一小时 1.2 TB,谁顶得住;二是写不动:每秒持续往盘里写 356 MB,普通硬盘的持续写入速度跟不上,会直接掉帧。所以录制也必须先编码再落盘,这不是为了省空间那么简单,是硬件物理上的硬限制。

误会三:「那用无损压缩(像 zip / PNG 那种)行不行?」 不行,差得远。像 zip 那种无损压缩,因为一个比特都不许丢,在视频上顶多压到 2~3 倍。可咱们需要的是 500 倍,差了整整两个数量级。所以视频、直播只能用有损压缩 —— 主动丢掉「人眼看不见」的信息来换体积。有损 vs 无损,是理解所有视频编码的一道分水岭,你先把这个概念立住,模块 5 会展开。


# 5.9 在源码里,这一步发生在哪?

📍承上启下:直觉都通了,回 OBS 源码落地 —— 看「编码」这一步的一「进」一「出」:裸帧进去、压缩包出来。

讲了半天「编码」,它在 OBS 里到底是哪个环节?回到那张从第 0 课就陪着你的主线图:

流水线里的编码环节

采集 → 合成 → 【编码】 → 封装 → 输出。 数据被压小,就发生在中间这个被点亮的「编码」环节。代码里,这一步有清清楚楚的一「进」一「出」:

进去的是裸帧。 合成阶段产出的一整张像素网格,就是咱们前几课认识的 struct video_framestruct obs_source_frame(第 2 课见过,libobs/obs.h:283),一帧 ≈ 6 MB,一个像素不少。

出来的是压缩包。 编码器(obs_encoder)把裸帧嚼一遍,吐出一个小巧得多的 struct encoder_packet:

// libobs/obs-encoder.h:99
struct encoder_packet {
	uint8_t *data;     /* 压缩后的数据 */
	size_t   size;     /* 包有多大 */
	int64_t  pts;      /* 显示时间戳 */
	int64_t  dts;      /* 解码时间戳 */
	bool     keyframe; /* 是不是关键帧 */
	...
};
1
2
3
4
5
6
7
8
9

同样一帧的内容,装进 encoder_packet 可能就几 KB —— 进去 6 MB,出来几 KB,缩了上千倍。

小方让你留意那个 keyframe(关键帧)字段。它正是 5.7 第一招(「相邻两帧大半重复」)在代码里的影子:有的帧是「完整一张图」(关键帧),有的帧只记「相对上一帧变了啥」。背后的 I 帧 / P 帧 / B 帧,模块 5 第 18 课专门拆,这儿你先混个脸熟。

想顺藤摸瓜的同学,给你留个线头: 各家编码器(obs-x264obs-nvenc…)是通过 struct obs_encoder_info(obs-encoder.h:197)把自己注册进 OBS 的,核心就是一个 encode 回调:

// libobs/obs-encoder.h:247
bool (*encode)(void *data, struct encoder_frame *frame,
               struct encoder_packet *packet, bool *received_packet);
1
2
3

一句话:喂进一帧(encoder_frame),吐出一个压缩包(encoder_packet)。 至于「具体怎么压」的算法,藏在 plugins/obs-x264plugins/obs-nvenc 这些插件里 —— 那是模块 5 的正菜,这里点到为止。

至于「压到多少」由谁说了算?是码率(bitrate)。OBS 的默认值就写在前端:

// frontend/widgets/OBSBasic.cpp:736
config_set_default_uint(activeConfiguration, "SimpleOutput", "VBitrate", 6000);  // 视频 6000 kbps
config_set_default_uint(activeConfiguration, "SimpleOutput", "ABitrate", 160);   // 音频 160 kbps
1
2
3

视频 6 Mbps、音频 160 kbps,加起来 6 Mbps 出头。还记得 5.5 那根 50 Mbps 的吸管吗?6 Mbps 轻松就钻过去了。 难题,迎刃而解。


# 5.10 小方唠两句:这套「魔法」从哪来的

📍收束:正课收尾,扯点轻松的 —— 从 JPEG、MP3 到 H.264,这套「骗过感官就不必存」的思路,几十年来其实一脉相承。

最后扯点轻松的。你别以为「丢掉感官察觉不到的信息」是什么新发明 —— 这套思路,几十年来一脉相承。

上世纪 90 年代,人们想在硬盘和网络都还很金贵的时候塞下照片和音乐,于是有了 JPEG(照片)和 MP3(音乐)。它俩干的是同一件事:研究人的眼睛和耳朵到底有多「迟钝」,然后把那些你反正也察觉不到的细节,统统扔掉。 MP3 当年能把 CD 音乐压到十分之一,靠的就是「人耳听不见的频率、被强音盖住的弱音,删了你也发现不了」。

视频编码(MPEG 系列、到今天直播的主力 H.264)是这条路的集大成者 —— 它把「帧间重复、帧内相近、感知冗余」三招全用上,才换来了那 500 倍的压缩比。所以你看,从一张 JPEG 照片到一场 4K 直播,背后是同一个朴素到有点「狡猾」的念头:

能骗过你眼睛和耳朵的东西,就没必要存。

记住这句话,模块 5 学起来会顺很多。


# 5.11 本课小结

这一课没有新名词,但有一个一旦想通就再也忘不掉的结论。小方帮你收一下:

  • 算账先过单位关:字节(B)和比特(b)差 8 倍;体积用字节、码率用比特;1024 与 1000 取近似。
  • 裸数据大得离谱:1080p60 一帧 ≈ 6 MB,一秒 ≈ 356 MB,一小时 ≈ 1.2 TB;分辨率、帧率每升一档,体积成倍涨(4K60 高达 4.9 TB/时)。音频(PCM)相比小到可忽略(一小时仅 0.68 GB)。
  • 既存不下,更传不出去:裸流 ~2850 Mbps,家用上行才几十 Mbps,慢着传要 53 小时 —— 不压缩,直播在物理上不成立
  • 录制怕「存不下」,直播怕「传不出」:紧箍咒不同,但都绕不开编码。
  • 编码是那步魔法:压到约 1/500,肉眼几乎无损;靠「帧间重复、帧内相近、感知冗余」三招,本质是「有损压缩」(无损只能压 2~3 倍,救不了场)。
  • 在 OBS 里:裸帧(video_frame/obs_source_frame,~6 MB)进 → 编码器(obs_encoder,核心是 encode 回调)→ 压缩包(encoder_packet,~几 KB)出;压多狠由码率定(默认视频 6 Mbps、音频 160 kbps)。

更重要的是,你现在拿到了一个贯穿整个模块 1 的「为什么」:前面四课讲的所有「原材料」,最终都指向同一个工程难题 —— 数据太大,必须压缩。 带着这个问题往下走,后面的编码、封装、传输,你就不会觉得是一堆零散术语,而是一环扣一环地在解同一道题。

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

  1. 自己算一遍 720p 的账:别抄我的,自己动手 —— 1280 × 720、30 帧、每像素 3 字节,算它一秒、一分钟、一小时各多大,再和我表格里的数对一对。算完你对「分辨率、帧率怎么撑大体积」会有肌肉记忆。
  2. 眼见为实:用 OBS 录一段 10 秒视频(默认设置),看生成的文件多大;再心算一下,如果不压缩,这 10 秒该是多大(≈ 356 MB × 10 = 3.5 GB)。两个数一比,你就知道编码替你省了多少。
  3. 找到那个码率开关:OBS → 设置 → 输出,找到「视频比特率」,看默认是不是 6000 Kbps —— 它就是 OBSBasic.cpp:736 里那个 VBitrate。把它调大调小,想想会怎么影响画质和带宽。
  4. (进阶)做个单位换算:你家宽带上行如果是 50 Mbps,换算成「每秒能传多少 MB」是多少?(提示:÷8。)再想想:OBS 默认 6 Mbps 的直播流,占了你上行的几分之几?

# 下一课预告

模块 1 到这里全部讲完了 —— 恭喜你拿下了音视频的「原材料」:画面怎么存、声音怎么存、为什么非压缩不可。

但在真正动手研究「OBS 怎么采集、怎么编码、怎么推流」之前,咱们得先停一停,搞懂一件更根本的事:OBS 自己,是怎么把这一整套东西组织起来的?

下一课起,进入模块 2:OBS 的世界观

第 6 课:一切皆 Source(源) —— 我会带你认识 OBS 最核心、也最妙的一个设计:不管是摄像头、屏幕、文字,还是滤镜、转场,在 OBS 眼里竟然都是同一种东西。想读懂这套源码,这是你必须先拿到的第一把钥匙。下节课见。


📁 本课配图:imgs/05-01 ~ imgs/05-08 📌 源码锚点:frontend/widgets/OBSBasic.cpp:736(默认视频码率 6000)、:737(音频 160)、libobs/obs-encoder.h:99(encoder_packet)、:197(obs_encoder_info)、:247(encode 回调)、libobs/obs.h:283(obs_source_frame)、libobs/media-io/video-frame.h:27(video_frame)

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

社区交流

讨论与留言

前往 GitHub Issues →

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

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