第 21 课:音频编码与码率怎么选 —— AAC / Opus、CBR / VBR
# 第 21 课:音频编码与码率怎么选 —— AAC / Opus、CBR / VBR
嘿,我是小方。 模块 5 到最后一课了。前三课把视频编码讲透了(原理、统一接口、x264 vs NVENC)。这一课收尾,讲两件事: 一、音频编码 —— 它比视频简单,但我这次会像讲视频那样,把"一段声音怎么变成 AAC 字节"的完整流水线也摊开,不再只讲"扔掉听不见的"就带过; 二、一个贯穿视频和音频的大问题:码率(bitrate)怎么选?CBR 和 VBR 到底啥区别、直播录制为什么用不同的? 这一课我从零铺:声音为什么是"一堆频率"、比特(bit)到底是什么、音频编码的每一步、CBR/VBR 用生活比方讲清 —— 不需要你先懂任何东西。
# 21.1 声音也要编码 —— 但比视频简单太多了
📍我们在哪:还在"编码"这一站,视频那一路讲完了,轮到音频。先吃颗定心丸 —— 音频是整个编码里最轻松的部分,压 10 倍就够,几乎不吃 CPU。
先给你吃颗定心丸:音频编码,是整个编码里最轻松的部分。

为什么?对比一下体积就懂了:
- 裸视频(1080p60):≈ 356 MB/秒(第 5 课算过);
- 裸音频(48kHz 立体声、16 位):
48000 采样 × 2 声道 × 2 字节 ≈ 192000 字节/秒 ≈ 0.18 MB/秒(约 1.5 Mbps); - AAC 编码后(160 kbps):≈ 0.02 MB/秒。
视频要压几百倍,音频从 1.5 Mbps 压到 160k,只压了大约 10 倍就够了 —— 数量级差得远。原因有两个:
- 裸音频本来就小:它是"一维的波"(每秒几万个采样),不像视频是"二维的画 × 每秒几十帧",天生数据量小得多。
- 压缩也温和:音频没有视频那种"帧间"海量冗余可榨(第 18 课),压 10 倍左右就到头了。
而在代码里,音频编码器就是"音频版的 H.264" —— 概念和视频编码器一模一样(第 19 课那套登记表 + 回调),只是简单得多,几乎不吃 CPU。下面认识一下 OBS 的两个音频编码器。
# 21.2 两个音频编码器:AAC 与 Opus
📍接上一节:知道了音频编码简单,来认识 OBS 的两个主力 —— AAC 和 Opus。它们填的还是第 19 课那张登记表,只是 type 换成了音频。
OBS 里主要用两个音频编码器,它们和视频编码器一样,都是填同一张 obs_encoder_info 登记表(第 19 课),只是 type = OBS_ENCODER_AUDIO,而且都把活儿甩给了 FFmpeg 库去干。

// plugins/obs-ffmpeg/obs-ffmpeg-audio-encoders.c:459
struct obs_encoder_info aac_encoder_info = {
.id = "ffmpeg_aac",
.type = OBS_ENCODER_AUDIO, // ← 音频类型
.codec = "aac",
.encode = enc_encode,
.get_frame_size = enc_frame_size, // 音频专属(第 19 课那个"一帧多少采样")
...
};
// :474 opus_encoder_info —— 除了 .id="ffmpeg_opus"、.codec="opus",其余和 AAC 完全一样
2
3
4
5
6
7
8
9
10
- AAC:最通用、最兼容 —— 几乎所有平台、播放器、直播服务都认它。是 OBS 的默认音频编码器,成熟稳定,中高码率下音质很好。不知道选啥,就用它。
- Opus:更新的开放编码器,低码率下音质明显更好,被 Discord、YouTube、WebRTC 广泛使用;但有些老平台/服务不支持。平台支持、又想省码率时,用它。
🔧 它们其实是"同一段代码":这个文件里 7 个音频编码器(AAC、Opus,以及无损的 PCM、FLAC、ALAC)共用一套实现(
enc_create→enc_encode),差别只在.id、.codec,和创建时传给 FFmpeg 的编码器名字。真正的编码委托给 FFmpeg 的libavcodec——avcodec_find_encoder_by_name("aac")(:182)找到编码器,avcodec_open2(:128)打开它。这正是第 19 课那套"统一接口"的又一次兑现。AAC、Opus 有损(扔掉听不出的),PCM/FLAC/ALAC 无损(录音棚级、体积大)。
实用建议:直播绝大多数场景,AAC 160k,闭眼选,够用又稳妥。 但音频到底"怎么"压、为什么 160k 就够?接下来三节,把地基一块块铺实。
# 21.3 先补课:任何声音,都是一堆"频率"叠出来的
📍承上启下:选哪个编码器清楚了,可音频"怎么"压还没讲。先补一个模型 —— 任何声音都是一堆频率叠出来的,这是理解"扔掉某些频率"的前提。
要理解音频压缩,得先有一个模型:声音,是一堆"纯音"叠加出来的。 这是第 4 课(PCM = 随时间的采样点)之后,你需要补上的另一半。

- 纯音:一个单一频率的正弦波(比如音叉的"嗡"、口哨的"嘶")。低频 = 沉闷的嗡嗡,高频 = 尖细的嘶嘶。
- 任何真实声音(人声、音乐、环境声),都可以看成许多不同频率的纯音,按各自的响度叠加而成。
- 换个角度看:与其画"随时间起伏的波",不如画一张频谱 —— 横轴是频率(低→高),纵轴是每个频率有多响。同一段声音,时域的"波"和频域的"频谱",是一体两面(数学上靠"傅里叶变换"来回换算,你不用会算,知道能换就行)。
为什么这个模型重要? 因为一旦声音能拆成"各频率有多响",编码器就能按频率下手:人耳听不到的频率、或被别的声音盖住的频率,整段扔掉。这就是下一节"听觉掩蔽"的舞台 —— 没有"频谱"这个视角,"扔掉某些频率"这句话就无从谈起。
# 21.4 音频凭什么能压?为什么 128/160k 就够了?
📍接上一节:有了"频谱"这个视角,就能讲清音频有损压缩的两根支柱 —— 听觉掩蔽扔掉听不见的,加上码率的边际递减。
有了频谱视角,现在能讲清音频有损压缩的两个支柱了。

# ① 靠"听觉掩蔽"扔掉你听不见的
音频有损压缩(AAC/Opus)的核心,是**心理声学(psychoacoustics)**里的事实:人耳有一堆"听不见"的东西——
- 听觉掩蔽:一个响的频率,会盖住它旁边较轻的频率(你在轰鸣的机器旁听不清小声说话)。既然反正听不见,那些被盖住的频率成分,编码时直接扔掉;
- 听不到的频率:超高频(>18kHz 左右)、超低频,人耳本就感知不到,也扔掉。
编码器专挑"你注意不到的地方"下手 —— 这和第 18 课视频量化"扔掉不敏感的高频"是同一种哲学,都叫感知编码。
# ② 码率的"边际递减":上到一定程度就听不出差别了
音质随码率上升,但不是线性的——过了某个点,再加码率,耳朵基本分辨不出:
- 立体声音乐:128k 够用,160k 从容,192k 以上基本是"心理安慰"(多数人盲听分辨不出);
- 语音为主(播客、连麦):64~96k 就很好,还省带宽。
所以音频码率不用像视频那么纠结。 花码率的大头永远是视频;音频给个 160k,然后忘掉它,是最省心的做法。(代码里,OBS 音频编码器默认码率是 128k(enc_defaults,:413),但前端配置把每条音轨的实际默认设成了 160k(OBSBasic.cpp:737)。)
# 21.5 音频编码的完整流水线:PCM 怎么变成 AAC
📍承上启下:讲了"扔什么、为什么能扔",现在把整条流水线摊开 —— 一段 PCM 怎么一步步变成 AAC,和第 18 课视频那条是姊妹篇。
上面讲了"扔什么、为什么能扔",现在把整条流水线摊开 —— 一段 PCM 到底怎么一步步变成 AAC 字节。这和第 18 课视频那条流水线是"姊妹篇"(OBS 不做这些,FFmpeg 内部做,就像视频交给 x264)。

五步:
- ① 分帧:把连续的 PCM 采样,切成每 1024 个采样一帧(编码器的
get_frame_size,第 19 课,AAC 就是 1024;和第 16 课混音"一拍 1024 采样"恰好一样)。编码一帧一帧地来。 - ② 变换到频域(MDCT):把这一帧的"波",变换成"频谱"(21.3 那张图)——看清这一帧里有哪些频率、各多响。
MDCT是改良版的离散余弦变换,和视频的DCT是近亲。 - ③ 心理声学模型:★ 这是音频压缩的灵魂。它精确算出哪些频率被掩蔽、或人耳听不到,给量化下达指令:"这些可以大胆扔"。
- ④ 量化:★ 按模型的指令,该扔的频率扔掉、不敏感的粗略化。有损,就发生在这一步(和视频一样)。
- ⑤ 熵编码:把剩下的数据无损紧凑打包 → AAC 字节。
和视频一比,骨架几乎一样:
| 视频(第 18 课) | 音频(本课) |
|---|---|
| 分块 → DCT → 量化 → 熵编码(在二维画面上) | 分帧 → MDCT → 量化 → 熵编码(在一维声波频谱上) |
核心哲学同一个:变换到"能分辨轻重"的域(频域),扔掉感知不到的,再无损打包。 但有两个和视频不同、值得记住的点:
- 多了个"心理声学模型"(第③步):专门算"哪些听不见",这是音频压缩最精巧的部分;
- 音频没有"帧间预测(P/B 帧)":每一帧都独立编码,不参考前后帧。所以每个音频包都是"关键帧" —— 这一点在代码里看得一清二楚(21.11 见)。
# 21.6 再补一个地基:"比特(bit)"到底是什么
📍转折:音频这条线讲完了。接下来的重头戏是码率策略(CBR/VBR),视频音频都要面对 —— 但先把"比特"这个最小地基补上,不然码率、流量永远算不明白。
音频讲完了。接下来的重头戏是码率控制策略(CBR vs VBR),视频音频都要面对。但在那之前,先把"比特"这个最小的地基补上 —— 不然码率、流量永远算不明白。

# 比特 vs 字节,别搞混
- 比特(bit) = 一个
0或1,信息的最小单位。 - 1 字节(Byte)= 8 个比特。
- 关键:
1 Byte = 8 bit,所以两者的速率差 8 倍!这是新手最常踩的坑:kbps/Mbps里小写的 b = 比特(bit);KB/s/MB/s里大写的 B = 字节(Byte);6 Mbps= 每秒 600 万比特 ÷ 8 = 750 KB/s(不是 6 MB/s!)。
# 换算成流量/体积,找找感觉
- 直播
6 Mbps视频 +160k音频 ≈6.16 Mbps→ 每秒约 770 KB → 一小时约 2.7 GB 上传; - 录制
20 Mbps→ 一小时约 9 GB 文件; - AAC 音频
160k→ 一小时约 70 MB(很小,可忽略)。
所以:视频码率决定了你的带宽/硬盘压力,音频那点码率可以忽略不计。
# 为什么"更多比特 = 更好质量"?
码率(每秒比特)就是编码器的"预算"。比特越多 → 量化能越精细(少扔细节)→ 越清晰;比特越少 → 量化越粗(多扔细节)→ 越糊/越多杂音。 这正是第 18 课"量化 = 有损"和码率的直接联系 —— 码率不是玄学,它就是"你给编码器多少位去存细节"。
# 21.7 码率:每秒的"预算",怎么"分配"
📍接上一节:有了比特,码率就是"每秒多少比特的预算"。关键问题随之而来 —— 同样是平均 6 Mbps,这份预算到底该怎么花?
有了比特的概念,码率就好懂了。

码率(bitrate)= 每秒钟用多少比特来表示这段视频/音频 = 编码的"预算"。 视频常见 2.5~8 Mbps,音频常见 128~192 kbps。预算高→清晰但大,预算低→糊但省。编码器的活,就是把画面/声音塞进这个预算里。
现在关键问题来了:同样是"平均 6 Mbps",这份预算怎么"花"? 有两种花法:
- 每一秒都严格花 6 Mbps(不多不少)→ CBR(恒定码率);
- 难的画面多花、简单的少花,只要平均是 6 → VBR(可变码率)。
这两种"分配策略",就是接下来的主角。
# 21.8 CBR vs VBR:恒定码率 vs 可变码率
📍承上启下:预算的两种花法正式登场 —— 每一秒都花一样多的 CBR,和难的多花、简单少花的 VBR。稳 vs 聪明的取舍。

想象一段视频,画面难易在变:静止(简单)→ 打斗(复杂)→ 过场(简单)→ 粒子特效(复杂)。同样要"平均 6 Mbps",两种策略表现完全不同:
- CBR(Constant Bit Rate,恒定码率):码率是一条平线 —— 每一秒都花固定码率。好:平稳、可预测(网络好安排);差:简单画面"浪费"码率,复杂画面又不够。
- VBR(Variable Bit Rate,可变码率):码率跟着画面难易起伏 —— 难的多花、简单的少花,平均达标。好:同样平均码率下,整体画质更高/体积更省;差:码率忽高忽低,不好预测(直播突然飙高易卡)。
💡 "恒定"没那么死板 —— 缓冲(VBV)在起作用。 CBR 也不是逐帧都精确等于目标值:编码器有一个码率缓冲区(VBV),允许在一个很短的窗口内"这帧多花一点、下帧省一点",只要窗口内平均守住目标就行。VBR 则给一个峰值上限(max bitrate)——平均达标、但峰值不许超过某个值,防止某段突然飙太高。所以更准确地说:CBR = "短窗口内严格恒定",VBR = "平均达标、峰值封顶"。
一句话:CBR 稳但不够聪明,VBR 聪明但不够稳。 这个取舍,决定了直播和录制的选择(21.10)。
# 21.9 再进一步:到底"什么"保持恒定?
📍接上一节:CBR 锚码率、VBR 锚平均,那有没有锚"质量"的?把 CBR、VBR、CQP/CRF 三种放一起,看各自到底锚住了什么。
CBR、VBR 之外,还有一种(尤其录制/NVENC 常见):CQP / CRF(恒定质量)。三种放一起,看各自"锚"住什么:

| 策略 | 恒定的是 | 浮动的是 | 适合 | OBS 里 |
|---|---|---|---|---|
| CBR | 码率恒定 | 质量随内容浮动 | 直播(带宽固定) | x264: ABR + filler |
| VBR | 码率浮动(有上限) | 质量较稳 | 点播 / 录制 | x264/nvenc: VBR |
| CQP / CRF | 质量恒定 | 码率随内容浮动(无上限) | 存档 / 母带 | x264: CRF / nvenc: CQP |
- CBR:锚住码率,让质量去浮动。
- VBR:半锚 —— 码率可浮动但有上限,平均达标、峰值封顶。
- CQP / CRF(Constant QP / Constant Rate Factor):锚住质量 —— 你设一个"质量目标",码率随内容自由浮动、无上限。
🔢 CRF/CQP 那个数字怎么理解? 它是个"质量档位"(x264 CRF 范围 0~51),数字越小 = 质量越高 = 文件越大:
CRF 18≈ 视觉无损(很大)、CRF 23(x264 默认)= 质量好、体积合理、CRF 28= 明显更糊但很小。NVENC 的CQP类似(值越小越清晰)。它和码率是反过来的旋钮:码率模式是"我给你多少位、你尽量做好";CRF 模式是"我要这个质量、你该花多少位就花多少"。存档最爱用它——一次设定,全程画质稳定。
一句话:CBR 保码率稳、CRF 保质量稳、VBR 在两者之间。
# 21.10 直播 vs 录制:码率策略怎么选
📍承上启下:三种策略都认识了,落到你手上该选哪个 —— 就看你面对的是"固定宽度的网络管道",还是"能装多少装多少的硬盘"。
核心看:你面对的是"固定宽度的网络管道",还是"能装多少装多少的硬盘"。

# 直播 → 用 CBR
- 上行带宽固定(比如 10 Mbps),像一根固定宽度的管道;
- 码率一旦突然飙高,管道塞不下 → 卡顿、丢帧、观众缓冲;
- CBR 让码率像心跳一样稳,平台和网络都好安排。所以 OBS 直播默认就是 CBR(
obs-x264.c:110)。
# 录制 / 存档 → 用 VBR 或 CQP/CRF
- 存到硬盘,没有"固定管道"约束——码率忽高忽低无所谓,只在乎最终质量;
- VBR / CRF:难的地方多花、简单的省着点,换来"每字节最好的画质"、体积更合理;后期要剪辑更该用高质量的 VBR/CQP。
记忆口诀:直播怕"卡" → 要稳 → CBR;录制怕"糊/大" → 要质量/体积 → VBR 或 CQP/CRF。
# 21.11 源码印证:码率与编码,在 OBS 里怎么落地
📍接上一节:概念选完,回到真实代码 —— 音频的 encode 怎么委托 FFmpeg、每个音频包为什么都是关键帧、x264 的 CBR 底层竟是"ABR + 填充"。
把概念对回真实代码。
# 音频 encode():一帧进,一个包出,委托 FFmpeg
音频的 enc_encode 里,真正编码就是把一帧 PCM 交给 FFmpeg、取回一个压缩包(obs-ffmpeg-audio-encoders.c:369):
// plugins/obs-ffmpeg/obs-ffmpeg-audio-encoders.c:369(节选)
ret = avcodec_send_frame(enc->context, enc->aframe); // 一帧 PCM 送进 FFmpeg
if (ret == 0)
ret = avcodec_receive_packet(enc->context, &avpacket); // 取回一个压缩包
...
packet->pts = rescale_ts(avpacket.pts, ...); // 时间戳
packet->type = OBS_ENCODER_AUDIO;
packet->keyframe = true; // ★ 音频每个包都是「关键帧」!
2
3
4
5
6
7
8
看那句 packet->keyframe = true(恒真) —— 呼应 21.5:音频没有帧间预测,每一帧都独立可解,所以每个包都是关键帧。(对比第 18 课视频:只有 I 帧是关键帧,P/B 帧不是。)真正的分帧→MDCT→量化→熵编码,全在 avcodec_send_frame 背后的 FFmpeg 里。
# 音频码率:只有一个"目标",没有 CBR/VBR
音频简单到连码率模式都没有 —— 你只给它一个目标码率(:219):
// plugins/obs-ffmpeg/obs-ffmpeg-audio-encoders.c:215
if (codec_desc->props & AV_CODEC_PROP_LOSSLESS)
enc->context->bit_rate = 0; // 无损:不设码率
else
enc->context->bit_rate = bitrate * 1000; // 有损:kbps → bps
2
3
4
5
# 视频:x264 的 CBR = ABR + 填充
x264 把你选的模式映射成内部方法(obs-x264.c:465):
// plugins/obs-x264/obs-x264.c:465(节选)
if (rc == RATE_CONTROL_CBR || rc == RATE_CONTROL_ABR) {
obsx264->params.rc.i_rc_method = X264_RC_ABR; // CBR 底层是 ABR
if (rc == RATE_CONTROL_CBR)
obsx264->params.rc.b_filler = true; // ★ CBR 靠「填充」把码率填满到恒定
} else {
obsx264->params.rc.i_rc_method = X264_RC_CRF; // CRF:恒定质量
obsx264->params.rc.f_rf_constant = (float)crf;
}
2
3
4
5
6
7
8
9
有意思的真相:x264 的 CBR,底层是"ABR(平均码率)+ filler(填充)" —— 当某段画面简单、编不满目标码率时,就塞填充数据把码率"撑"到恒定(b_filler = true)。这就是"恒定码率"在实现层面的样子:不是画面真需要这么多,而是填满它,好让网络流量平稳。
# 视频:NVENC 同一套概念
NVENC 设的是它自己的 rateControlMode(nvenc.c:347):NV_ENC_PARAMS_RC_CBR / VBR / CONSTQP —— 和 x264 的 CBR/VBR/CRF 一一对应,同一套概念的硬件版(第 20 课那个规律又出现了)。
# 21.12 模块 5 收官:编码,全讲完了
📍收束:四课走完,整个编码模块通关 —— 视频流 + 音频流都成了带时间戳的 encoder_packet。下一步就是把它们打包送出,交棒模块 6。
到这一课,整个编码模块通关了:

- 第 18 课 · 原理:为什么能压(冗余、I/P/B、关键帧、GOP);
- 第 19 课 · 统一接口:
obs_encoder登记表 + 回调,x264/NVENC 长得一样; - 第 20 课 · 视频编码器:x264(CPU)vs NVENC(显卡芯片),preset 怎么调;
- 第 21 课 · 音频 + 码率:AAC/Opus 的流水线(和视频姊妹篇),CBR vs VBR(稳 vs 聪明)。
现在,视频流 + 音频流都编码好了 —— 一串串带时间戳(pts/dts)的 encoder_packet。 下一步:把这两条流"打包"进一个文件(.mp4/.mkv)或发往直播服务器(RTMP)。这就是**模块 6"打包与送出"**的故事。编码,交棒。
# 21.13 本课小结
- 音频编码简单:裸音频 ≈ 1.5 Mbps,压到 160k 约 10 倍(视频压几百倍)。音频编码器 = "音频版 H.264",几乎不吃 CPU。
- AAC vs Opus:同填
obs_encoder_info(type=AUDIO,:459/:474),委托 FFmpeg。AAC 通用/默认,Opus 低码率更好但兼容稍差;另有无损 PCM/FLAC/ALAC。直播 AAC 160k 闭眼选。 - 声音 = 频率的叠加:任何声音 = 一堆纯音之和;时域"波" ↔ 频域"频谱"(傅里叶变换)。有了频谱,才能"按频率取舍"。
- 音频为什么能压:① 听觉掩蔽(响频率盖轻频率、听不到的频率直接扔,感知编码,同第 18 课哲学);② 边际递减(立体声过 ~160k 分辨不出)。
- 音频编码流水线:分帧 → MDCT(波→频谱)→ 心理声学模型(算哪些听不见)→ 量化(有损)→ 熵编码(无损)→ AAC。与视频"分块→DCT→量化→熵编码"骨架相同;不同:多了心理声学模型、没有 P/B 帧(每个音频包都是关键帧)。
- 比特(bit):0/1,
1 Byte = 8 bit;kbps的小 b=比特、KB/s的大 B=字节,差 8 倍;6 Mbps = 750 KB/s。更多比特 = 量化更精细 = 更清晰(接第 18 课量化)。 - 码率 = 每秒比特预算;两种分配:CBR(平线,稳但简单画面浪费)、VBR(跟画面起伏,同码率画质更高/体积更省但不稳)。缓冲(VBV)让 CBR"短窗口恒定"、VBR"峰值封顶"。
- 三种策略:CBR 锚码率、CRF/CQP 锚质量(数字越小越清晰越大,x264 默认 CRF 23)、VBR 居中。
- 怎么选:直播 → CBR(网络管道固定,
obs-x264.c:110);录制 → VBR 或 CQP/CRF(硬盘不限,要质量/体积)。 - 源码:音频
avcodec_send_frame/receive_packet(:369)、packet->keyframe=true(:394,每包关键帧)、bit_rate=bitrate*1000(:219);x264 CBR=ABR+filler(:465);NVENC RC_CBR/VBR/CONSTQP(nvenc.c:347)。模块 5 完。
# 21.14 动手 / 观察(本课作业)
- 算一算比特与流量:你直播设 6000 kbps 视频 + 160 kbps 音频。每秒上传多少 KB?一小时多少 GB?(提示:总 ≈ 6.16 Mbps ÷ 8 ≈ 770 KB/s ≈ 2.7 GB/时。)
- 看音频编码设置:OBS →"设置 → 输出"→ 音频,看编码器(默认 AAC)和码率(默认 160);试改 Opus、改成 96 或 320,感受差别。
- 看视频码率控制:切到"输出(高级)"→ 视频编码器,找到"码率控制"下拉(CBR/VBR/CQP/CRF)。你的直播默认哪个?录制呢?
- 理解 CBR 的 filler:用自己的话说清,为什么 x264 的 CBR 要"填充"?(提示:简单画面编不满目标码率时,填充撑到恒定,让网络流量平稳。)
- 做选择:①Twitch 直播打游戏、②录高质量教程存档,分别用什么码率控制?为什么?(答:①CBR ②VBR 或 CQP/CRF。)
- 翻源码:打开
plugins/obs-ffmpeg/obs-ffmpeg-audio-encoders.c:369,看avcodec_send_frame/receive_packet和packet->keyframe = true;再到plugins/obs-x264/obs-x264.c:465,看 CBR 那个b_filler = true。
# 下一课预告
编码交出了两条流:视频流 + 音频流,各是一串带时间戳的数据包。可它们现在还是两条分开的流,得合到一起才能用 —— 要么装进一个文件让你双击就能播,要么打成一路发给直播服务器。这个"合流 + 打包"的过程,叫封装(muxing)。
第 22 课:容器格式 —— MP4 / MKV / FLV / TS,obs_output —— 我们进入模块 6:打包与送出,搞清"容器"到底是什么(第 21 课那个"盒子"),MP4/MKV/FLV 各有什么脾气(为什么录制别用 MP4?),以及 OBS 用哪个抽象(obs_output)统管"录制到文件"和"推流到服务器"。下节课见。
📁 本课配图:
imgs/21-01~imgs/21-11📌 源码锚点:plugins/obs-ffmpeg/obs-ffmpeg-audio-encoders.c:459(aac_encoder_info)、:474(opus_encoder_info)、:411/:413(enc_defaults,默认码率 128)、:421(bitrate 属性 64~1024)、:215/:219(bit_rate = bitrate*1000,无损=0)、:369/:371(avcodec_send_frame / receive_packet)、:394(packet->keyframe = true,每包关键帧)、:453/:142(frame_size,回退 1024)、:182/:128(find_encoder / avcodec_open2);frontend/widgets/OBSBasic.cpp:737(前端默认音频码率 160);plugins/obs-x264/obs-x264.c:110(rate_control 默认 CBR)、:388(模式选择 CBR/VBR/ABR/CRF)、:465/:468/:472(CBR = ABR + b_filler)、:478(CRF = X264_RC_CRF + f_rf_constant);plugins/obs-nvenc/nvenc.c:347(默认 VBR)、:355(CQP/lossless = CONSTQP)、:365(CBR)。 注:MDCT / 心理声学模型 / 量化 / 熵编码是通用音频编码原理,由 FFmpeg(libavcodec)内部实现,OBS 不含这部分代码。
本留言区仅对应当前文章,欢迎补充观点、提出问题或帮助修正文中疏漏。 留言由 GitHub/Gitalk 提供,需要使用 GitHub 登录。
社区交流
讨论与留言