<!-- title: 宁丢不迟：实时语音传输原理 -->

# 宁丢不迟：实时语音传输原理

## 一、电话里的“喂喂喂”，其实是一门时间的手艺

先看两个场景。

你给朋友发微信，消息晚到了十秒，朋友回一句“刚看到”——一切正常，聊天照旧。但你打电话时，只要对方的声音比你慢上小半秒，对话立刻乱了套：你以为是沉默，开始说话，对方也同时在说，然后两个人一起停下来，一起说“喂？喂？听得到吗？”

这就是**交互式实时通信**和普通数据传输的根本区别：数据包晚到，叫“慢”；语音包晚到，叫“错”。播放器像一个按乐谱演奏的鼓手，第 20 毫秒的鼓点必须落在第 20 毫秒上。一个迟到了 200 毫秒的语音包，不是“晚点响”，而是**已经没有它的位置了**——乐章都翻篇了。

由此引出本文的主角：一套看起来“故意不可靠”的传输体系。它不用我们熟悉的可靠传输协议，不重传，不确认，甚至允许丢包。但这套体系恰恰撑起了全世界每一天的几十亿次通话。它的核心设计哲学只有一句话：

> **对实时语音来说，迟到的正确交付，等于错误的交付。与其把包追回来，不如把空缺藏起来。**

本文就拆解这套体系：为什么不能用可靠传输、RTP 协议的三个关键字段各管什么、抖动缓冲如何“用延迟换连续”、丢包之后靠什么瞒过你的耳朵。

## 二、时延预算：语音的钱包只有这么大

人对语音时延的容忍度，是国际上研究了几十年的经典课题。国际电联的经典结论（G.114 建议）大致是：

- 单向时延低于 **150 毫秒**：绝大多数通话者感觉不到延迟，交谈自然；
- 150～400 毫秒：可以接受，但开始出现“抢话”；
- 超过 **400 毫秒**：通话像对讲机，一问一答变成轮流向对方“广播”，体验难以接受。

这 150 毫秒，就是一次通话的“总预算”。而预算表上早就排满了花钱的项目：

$$D_{端到端} = D_{打包} + D_{编码} + D_{空口} + D_{传输} + D_{缓冲} \le 150\,\text{ms}$$

| 环节 | 在花钱做什么 | 典型量级 |
|---|---|---|
| 打包时延 | 攒够 20ms 的音频才凑成一个包 | 20ms |
| 编解码算法时延 | 编码器要看前后帧才能压缩 | 十几毫秒 |
| 空口传输 | 排队调度、混合重传纠错 | 几到几十毫秒 |
| 核心网与承载 | 光纤传输、路由器转发排队 | 几到几十毫秒 |
| 抖动缓冲 | 开播前先攒一层“垫底” | 几十毫秒 |

现在假设我们“聪明地”选择了可靠传输：丢一个包就重传一次。重传一次的代价是多少？至少一个往返时延（RTT）——无线网络里随便就是几十毫秒；如果这次重传又丢了，还要指数退避再等更久。两次重传下来，几百毫秒没了，预算当场爆仓。

更要命的是，语音是一股**连续的流**。可靠传输（如 TCP）有个特性叫**队头阻塞**：第 100 号包没送达，第 101、102、103 号包即使先到了也要在接收端排队等着。对文件下载，这无所谓，反正是按序拼装；对语音流，一个包卡住，后面所有包集体迟到——你为了救一个包，搭上了整条流的时延。

所以结论是结构性的，而不是调参能解决的：**实时语音从一开始就不该走可靠传输的路。**那可靠性问题怎么办？答案是下一节：把“可靠性”这件事整个搬出传输层，交给最懂语音的人自己处理。

## 三、把决策权搬回应用层：RTP 的设计哲学

实时语音选择在 UDP 之上自建一层轻量协议——**RTP（实时传输协议）**。它由 IETF 制定，1996 年首次发布，2003 年由现行标准接替，是 VoIP 技术大厦的地基。WebRTC 视频会议、运营商 VoLTE/VoNR 通话、IPTV，底层都跑着它。

RTP 的架构原则有个专门的名字：**应用层分帧（Application Layer Framing）**——协议该做什么、不该做什么，由应用自己决定，而不是塞进操作系统的协议栈里。为什么？因为只有应用层知道：

- 音频丢 20ms，可以用算法**藏**起来，几乎听不出来；
- 但迟到 200ms 的包，**谁也救不了**。

于是分工非常清晰：

- **UDP 只负责一件事：尽快发出去。**不确认、不重传、不排序。
- **RTP 负责“够用的智能”**：给每个包盖三个章——我是谁（源标识）、我带着什么（载荷类型）、我第几个出场、该几点响（序列号 + 时间戳）。
- **丢包、乱序、时延，怎么办？**接收端的应用自己看着办。这个“看着办”，就是后文的主角：抖动缓冲与丢包隐藏。

顺便说清一个常见误解：RTP 通常跑在 UDP 上，**不是**因为语音“不在乎可靠性”，而是因为语音在乎的是另一种可靠性——**时间的可靠性**。UDP 恰好把网络从“保证送达”的承诺中解放出来，让每一个包走最快的路，谁也不等谁。丢一两个包，损失 20～40ms 的声音，人耳的短时记忆和隐藏算法完全兜得住；而队头阻塞损失的是整条流的时间秩序，人耳立刻抗议。这笔账，工程师算得很清楚。

## 四、12 字节的三件武器：拆开 RTP 头

RTP 的头最小只有 12 字节，却解决了实时传输的几乎所有“知情权”问题。发送端每 20ms 发一个包，每个包头都写清楚了它的身份和时序。

| 字段 | 大小 | 作用 | 工程师视角 |
|---|---|---|---|
| 序列号 | 16 位 | 每发一包加 1，用于**发现丢包和乱序** | 收到 100、101、103——中间丢了 102 |
| 时间戳 | 32 位 | 本包第一个采样值的时刻，用于**决定何时播放** | 与到达时刻无关，只与采样节拍有关 |
| 载荷类型 PT | 7 位 | 标识载荷用哪种编码 | 通话前协商好的“暗号”，解码器按它选算法 |
| 同步源 SSRC | 32 位 | 标识这一路媒体流是谁发的 | 判断“单通”的关键线索 |
| 标记位 M | 1 位 | 应用自定义的特殊含义 | 如静音段后第一帧打标 |
| 版本等控制位 | 若干 | 协议版本、填充、扩展指示 | 一般不动 |

三个字段分工微妙，值得单独说透。

**序列号管“到了没有”**。发送端每发一包，序列号加一；接收端对着编号查缺，立刻知道丢了哪个、有没有乱序。初始值是随机的——这既让重放攻击更难，也意味着序列号本身**没有绝对含义**，只有“相对差值”有意义。

**时间戳管“什么时候播”**。它记录的不是发送时刻，而是**采样时钟的读数**。语音电话的经典采样率是 8000 赫兹（每秒 8000 个采样点），时间戳就按这个时钟走：一个 20ms 的包，无论里面压了多少字节，时间戳永远增加

$$\Delta TS = f_{采样} \times T_{打包} = 8000 \times 0.02 = 160$$

如果是静音、 comfort noise 之类的特殊帧，不携带正常语音，时间戳照样往前走——**播放节拍不能因为内容稀疏而乱**。视频流的时钟通常用 90kHz，同样是“粒度要足够细”的道理。

**序列号与时间戳的分工**，可以这么记：序列号回答“物流问题”（发了几件、到了几件、顺序乱没乱），时间戳回答“演出问题”（这一段声音该在乐曲的第几毫秒响起）。接收端用前者记账，用后者排节目单。

**RTCP：5% 带宽的体检报告**。与 RTP 配套的还有一个控制协议 RTCP，它周期性地发送接收质量报告：丢了多少包、抖动估计多大、往返时延多少。它占用的带宽通常只有媒体流的 5% 左右，却是整条链路唯一的“病人自述”——现网排障时，端点之间的丢包统计往往就是从 RTCP 报告里读出来的。

最后算一笔开销账，你会理解现网的一个优化点。以经典编码 G.711（每采样 1 字节）为例：20ms 打包，载荷 160 字节；加上 12 字节 RTP 头、8 字节 UDP 头、20 字节 IP 头，一个包 200 字节：

$$\text{头部开销} = \frac{200-160}{160} = 25\%$$

四分之一的带宽花在头上。所以无线空口上普遍启用**头压缩**技术，把 40 字节的协议头压到几字节——这是 VoLTE 能高效承载语音的原因之一。

## 五、抖动：时间上的噪声从哪来

理想网络里，发送端每 20ms 发一个包，接收端就每 20ms 收到一个包，完美。现实是，包的**到达间隔忽长忽短**——这个时延的波动，术语叫**包时延变化**，俗称抖动。

抖动的来源很具体：

- **路由器排队**：转发设备按包处理，前面挤着大数据流，语音包就得等几个排队周期；
- **路由变化**：相邻两个包走了不同路径，一长一短；
- **无线重传**：空口的自动重传机制，第一次没纠对就再等一个重传周期——有的包一次过，有的包折腾两三次，时延方差直接被拉大；
- **调度周期**：基站按调度周期分配资源，语音包在不同周期里的等待时间天然不同。

对语音接收端来说，抖动带来两个必须解决的时间问题：

1. **到达时刻抖动**：第 n 包 20ms 到，第 n+1 包 65ms 才到。如果到了就播，声音忽快忽慢，全是毛刺。
2. **时钟漂移**：发送端和接收端是两块独立的晶振，快慢相差百万分之几（ppm 级）。看着微不足道，但一通十分钟的长途电话里，累积误差足以把接收缓冲慢慢**抽干**（收端时钟快）或**撑爆**（收端时钟慢）。

第一个问题靠缓冲，第二个问题靠缓冲的**自适应调节**——这正是接下来最核心的部件。

## 六、水塔：抖动缓冲器的取舍之道

理解抖动缓冲，用楼顶水塔就够了。

上游水泵供水忽大忽小（网络抖动），但楼下住户拧开水龙头，水流必须恒定（播放连续）。水塔的办法是：在中间存一层水，出水口按固定速率放水。水位高时多吃一点，水位低时少放一点，把上游的波动全部吸收在塔里。

抖动缓冲器干的就是这件事，而且它有一个铁律，值得原文式地记住：

> **抖动缓冲能对抗的最大抖动，恰好等于它开播前引入的那段缓冲延迟。**

想稳住 60ms 的到达波动？那就在开始播放前，先攒 60ms 的音频垫底。天下没有免费的平滑——**缓冲深度就是时延预算里的固定开销**。

于是出现了一个此消彼长的根本权衡。定义**有效丢包率**：

$$P_{有效} = P_{网络丢包} + P_{迟到被弃}(D)$$

- 缓冲深度 $D$ 越大，迟到的包越有机会在播放时刻前赶进缓冲区，$P_{迟到被弃}$ 越小；
- 但 $D$ 直接计入端到端时延，吃掉第二节的预算。

缓冲调优的本质，就是在这条曲线上找拐点：**再加深一毫秒缓冲所换来的“少丢包”，已经不值一毫秒时延了**。工程上常见的初始策略是按“平均到达时延 + 三四倍抖动标准差”来定深度——覆盖大部分到达时间的分布尾部，又不过分挥霍预算。

更精巧的是**自适应缓冲**。网络状况在通话中会变（走进电梯、切换小区、拥塞起伏），静态深度很快过时。自适应策略两条腿走路：

- **加深容易**：悄悄放慢取包速率，多攒一点，听众毫无察觉；
- **变浅要挑时机**：裁剪缓冲必须**借静音段动手**——对方不说话的那几十毫秒里悄悄跳过一点，听感无损。这也是为什么工程实现都配合**语音活动检测**（VAD）来做缓冲伸缩。更讲究的实现还会在连续语音段用“时光伸缩”算法，把播放速率微调百分之几，人耳同样无法分辨。

一句话总结这一节：**抖动缓冲是用时延买连续性的交易所，VAD 是它的低买高卖窗口。**

## 七、丢包三招：藏、补、换

缓冲解决“迟到”，但真丢了的包怎么办？接收端有三招，按代价从低到高排列。

**第一招：藏（丢包隐藏 PLC）。**人耳对 20～40ms 内的声音空缺有相当强的掩蔽效应，尤其是有前后文参考时。PLC 算法利用相邻帧的信号特征，合成一段过渡音填进缺口——上一帧是浊音，就顺着基音周期外插；是清音，就填能量衰减的噪声。现代编解码器的 PLC 已经做得相当自然。上文那笔“丢 20ms 无所谓”的账，靠的就是这一招。

**第二招：补（前向纠错 FEC）。**发送端把第 n 帧的冗余副本**搭车**放进第 n+1 甚至 n+2 的包里。第 n 个包丢了？等 n+1 到达时从冗余字段里把它解出来。代价是带宽——相当于给语音上了双保险。它对抗的是孤立的单包丢失；连续突发丢包时，邻居包全没了，冗余也一起陪葬。更新的编解码器还引入**信道感知编码**——对最重要的信息位加大保护、次要位少保护，把冗余花在刀刃上。

**第三招：换（重传）。**你没看错，语音理论上也能重传——当往返时延足够小（同一局域网、同一机房）时，快速重传一帧的代价可以接受。但跨无线网的移动语音，RTT 几十毫秒起步，重传回来的帧十有八九已经迟到，所以**移动语音基本不用这招**。当年“能不能用可靠传输”的争论，在这里被实践画上了句号。

三招的分工与代价：

| 手段 | 原理 | 付出的代价 | 时延影响 | 适用场景 |
|---|---|---|---|---|
| PLC 隐藏 | 用相邻帧合成过渡音填补缺口 | 几乎为零（算力） | 无 | 兜底手段，永远开着 |
| FEC 冗余 | 下一包捎带上一帧副本 | 带宽翻倍或部分增加 | 增加一帧解包等待 | 单包随机丢失为主的网络 |
| 重传 | 缺失帧快速重发 | 带宽 + 信令 | 增加至少一个 RTT | 仅超低时延局域环境 |
| 加深缓冲 | 多垫底，减少迟到弃包 | 更多端到端时延 | 直接增加 | 抖动大而预算宽裕的场景 |

值得一提的是，新一代移动语音编解码器 EVS（为 VoLTE/VoNR 开发，支持最高 20kHz 音频带宽，采样率覆盖 8/16/32/48kHz，比特率最低 5.9kbps、最高 128kbps，且每 20ms 可动态切换）在标准层面就把**信道感知编码、改进的丢包隐藏、抖动缓冲管理**列为核心特性——换句话说，这套“藏、补、调”的实时传输哲学，已经内化进了编解码标准本身。它还向后兼容上一代宽带编码 AMR-WB（比特率 6.6～23.85kbps），保证新老终端能互通。

## 八、全景图：一句话的实时之旅

把前面的部件串起来。你对着手机说了一句话，它经历这样一条流水线：

```mermaid
flowchart TD
    A["说话：声波采样"] --> B["声码器：20ms一帧"]
    B --> C["RTP封装：12字节头"]
    C --> D["UDP：尽快发出"]
    D --> E["IP：路由转发"]
    E --> F["空口专用承载"]
    F --> G["IP骨干网"]
    G --> H["对端接收解包"]
    H --> I["抖动缓冲"]
    I --> J["解码与丢包隐藏"]
    J --> K["按本地时钟匀速播放"]
```

再看时间维度上发生了什么。注意接收端的两个关键动作：**序列号查缺**和**到点播、缺了藏**：

```mermaid
sequenceDiagram
    participant A as A手机
    participant N as 无线与IP网络
    participant B as B手机缓冲与播放
    A->>N: 每20ms发出序列号n的包
    N->>B: n包准时到达进入缓冲
    A->>N: 发出n+1包
    N--xB: n+1包在网络中丢失
    Note over B: 序列号出现空洞先记账
    A->>N: 20ms后发出n+2包
    N->>B: n+2包晚到但仍在播放时刻前入队
    B->>B: 播放时刻到n+1缺席启动PLC合成填充
    B->>B: 按本地播放时钟匀速取出解码
```

最后是接收端缓冲器每时每刻都在做的决策循环——它就是整个实时传输体系的“现场指挥”：

```mermaid
flowchart TD
    P["RTP包到达"] --> Q{"序列号连续吗"}
    Q -->|连续| R["按序入缓冲"]
    Q -->|有空洞| S["记账并启动短暂等待"]
    S --> T{"播放前补齐了吗"}
    T -->|补齐| R
    T -->|超时| U["对缺口启用PLC"]
    R --> V{"缓冲水位与目标比"}
    V -->|偏高| W["静音段悄悄收紧"]
    V -->|偏低| X["放慢取包垫深缓冲"]
    U --> V
```

## 九、现网连接：你在哪里会用到这套原理

这套原理不是纸上谈兵，它直接对应你排障时的每一个动作。

**抓包看 RTP 流，是语音质量分析的基本功。**用 Wireshark 打开一份通话抓包，Telephony 菜单下的 RTP 流分析能直接画出三条曲线：丢包率、抖动、估算 MOS 分。解读思路完全来自本文：

- **抖动曲线锯齿密、丢包率不高** → 缓冲吃紧，听感是“断续、机器人音”，重点查传输路径排队；
- **丢包率高、抖动平稳** → 大概率空口误码或承载异常，重点查无线侧；
- **两侧抓包对比**（基站出口 vs 对端入口）：丢包出现在哪一段，责任就在哪一段。

**“单通”的判决书写在 SSRC 里。**用户投诉“听得见对方、对方听不见我”，先看双向 RTP 流：如果只有一个方向的 SSRC 在跳序列号，说明反向媒体流压根没建立——常见原因是媒体地址/端口协商失败、NAT 或防火墙拦了 UDP。这一眼，省掉一圈无头绪的排障。

**打包周期是一场微交易。**20ms 一包（ptime=20）是主流；改成 40ms 一包，头开销减半、包速率减半，但打包时延多了 20ms，且一个包丢了损失翻倍。预算紧张的链路倾向大包，时延敏感的场景用小包——没有标准答案，只有预算分配。

**空口 QoS 是在给抖动缓冲减负。**VoLTE 通话会建立一条专用语音承载，保证比特率、调度优先级最高。它的真正作用之一，是**压住空口这一段的时延方差**——而空口恰恰是移动链路里抖动最大的源头。专用承载把抖动源头摁住了，终端的缓冲就可以开得浅，端到端时延预算就省下来了。空口 QoS 与媒体面，在这里握手。

**跨网互通的“音质刺客”。**工程师都遇到过：两端手机都支持新一代编码，通话音质却回到了窄带时代。原因往往在运营商间的互联互通路由按最保守能力对接，通话被降级到老编码——这也是为什么有时换一个拨号路径（例如走另一种互通方式），音质会突然变好。这提醒我们：**编解码能力是协商出来的，不是设备单方面决定的。**

## 十、三个常见误解

**误解一：“UDP 不可靠，所以 VoIP 音质天生差。”**恰恰相反。语音放弃了“包包送达”的可靠性，换来了“时间秩序”的可靠性；丢包的窟窿由 PLC 和 FEC 来补，而队头阻塞的窟窿无人能补。对实时流，UDP 是更可靠的选择。

**误解二：“丢包率 0%，音质一定好。”**MOS 是时延与丢包的联合判决。一条零丢包但端到端 500ms 的链路，听感同样崩溃。看质量要看两个轴，别只盯丢包率。

**误解三：“抖动缓冲开大点总没错。”**缓冲深度就是时延。开得越深，抢话越明显，而省下的那点“迟到弃包”未必有人耳能感知。缓冲调优永远是在预算曲线上找拐点，不是越大越好。

## 常见问题

**Q1：RTP 和 RTCP 到底什么关系？为什么要有两个协议？**
A：RTP 搬货，RTCP 交体检单。RTP 承载媒体本身（序列号 + 时间戳 + 载荷）；RTCP 周期性地向对端汇报接收质量——丢包率、抖动估计、往返时延——占用约 5% 的带宽。没有 RTCP，端点就成了“哑巴打电话”，只能猜对端听得好不好；有了它，码率自适应、质量监控才有数据来源。

**Q2：语音为什么是 20ms 一包？**
A：20ms 是编码帧长与打包周期的主流约定，是三方平衡的结果：太短（如 5ms），包头开销占比暴涨，包处理负担剧增；太长（如 80ms），打包时延吃光预算，且一个包丢失对应一大段声音，PLC 很难藏住。20ms 恰好让头开销（压缩前约 25%）、时延（20ms）和单包损失（20ms）都落在可接受区间。EVS 等新编码保持 20ms 帧长，但支持每帧切换比特率，灵活性体现在帧内而不是帧长上。

**Q3：时延和抖动是一回事吗？**
A：不是。时延是一个包从 A 到 B 花的时间；抖动是**多个包时延的波动幅度**。缓冲器对付的是抖动，但买缓冲花的钱是时延。网络可以时延很大而抖动很小（恒定 300ms，像卫星链路——能通话但抢话），也可以平均时延很小但抖动巨大（突发毛刺——听感断续）。两者必须分开诊断。

**Q4：微信电话这类 OTT 通话和 VoLTE 通话，走的也是这套机制吗？**
A：媒体面基本同源——IP 语音都建立在 RTP（或其衍生、WebRTC 同族协议）加抖动缓冲加丢包隐藏这套机制上，微信电话的“通话”模式底层逻辑与此同源。差别在承载与优先级：VoLTE 有运营商网络保障的专用承载，时延方差被空口调度压住；OTT 通话跑在普通上网承载里，和视频、下载抢资源，只能靠应用层自己的缓冲与编码自适应硬扛。这就是弱网下两者体验差距的根源。

**Q5：RTP 头里的时间戳能用来对时吗？**
A：不能。RTP 时间戳是**相对量**——记录本包第一个采样在媒体时钟上的位置，初始值随机，时钟粒度等于采样率。它回答“该在曲目的第几毫秒播放”，不回答“现在几点”。通话两端要对墙钟，得靠别的机制；而 RTP 时间戳的真正用途，是让接收端把网络打乱的时间秩序，重新排回一条均匀的播放时间线。

## 参考来源

1. [Real-time Transport Protocol - Wikipedia](https://en.wikipedia.org/wiki/Real-time_Transport_Protocol) — RTP/RTCP 设计原理、头部字段、UDP 选型依据、8kHz/90kHz 时钟粒度与 RTCP 5% 带宽的出处
2. [Enhanced Voice Services - Wikipedia](https://en.wikipedia.org/wiki/Enhanced_Voice_Services) — EVS 编解码参数（采样率、比特率、20ms 帧长切换）、信道感知编码与抖动缓冲管理特性
3. [Jitter - Wikipedia](https://en.wikipedia.org/wiki/Jitter) — 包时延变化定义、抖动缓冲“最大对抗能力等于缓冲延迟”铁律、借静音段自适应调整的机制
4. [RFC 3550: RTP - A Transport Protocol for Real-Time Applications](https://datatracker.ietf.org/doc/html/rfc3550) — RTP 标准文档本体，应用层分帧与序列号/时间戳机制的权威定义

---
> 本文由「51学通信」技术团队出品。51学通信由通信行业18年老兵**爱卫生**（微信ID: gprshome201101）维护，聚焦5G/6G核心网、3GPP标准解读、通信前沿技术深度分析。
> 出版作品有《5G核心网原理与实践》《IMS原理与实践》等4本通信专业书籍。知识星球「51学通信」提供深度技术答疑和行业洞察。

> [!tip] 51学通信知识星球
> **星主：爱卫生**（微信：gprshome201101）——公众号「51学通信」创办者，19 年通信行业运维与讲师经验，著有《GPRS网络信令实例详解》《EPC原理与实践》《5G核心网原理与实践》三本纸质书（各大电商平台有售）。
> **星球定位**：深耕 5G 核心网、IMS、NFV/AI、云原生等 ICT 领域，主打运维岗位与信令分析。
> **当前规模**：5200 篇主题 / 990 个回答，198 元/年。
> **加入福利**：加入星球后请加爱卫生微信，拉您进知识星球年度陪伴与答疑群——不限量回复您的各种问题，另有群内分享。
> **AI 加持**：51学通信知识星球已作为 skill 接入 WorkBuddy，使用 deepseek-4-flash 在海量星球帖子中精准找贴、找视频、找 FAQ 和案例，做总结、找文档和 PPT 等场景全覆盖。

![51学通信知识星球海报-扫码加入](https://wiki.500nian.com/images/zhixingqiu_qrcode.png)
