Producer、Router与Consumer构成了mediasoup转发框架的核心数据流管道。Producer作为媒体流的注入点,负责接收、解析并标准化来自客户端的原始RTP报文;Router作为中枢交换单元,维护流订阅关系并进行高效的一对多分发;Consumer作为媒体流的出口,负责根据接收端能力与网络状况进行流适配与重写,确保终端兼容性。三者通过清晰的职责边界与数据接口,共同实现了高性能、可扩展的实时媒体流转发 。
一、Producer的核心职责:流标准化与元数据注入
Producer的核心功能是将异构的客户端媒体流转换为Router内部可统一处理的标准化流。其职责具体体现在三个层面的转换:
代码示例:Producer关键转换函数
// 简化示例:展示Producer对RTP报文的关键字段重写逻辑
bool Producer::ProcessIncomingRtpPacket(RTC::RtpPacket* packet) {
// 1. Payload Type 映射
uint8_t clientPt = packet->GetPayloadType();
uint8_t serverPt = MapPayloadType(clientPt); // 查找预定义的映射表
packet->SetPayloadType(serverPt);
// 2. SSRC 重写
uint32_t originalSsrc = packet->GetSsrc();
uint32_t mappedSsrc = GetMappedSsrcForStream(originalSsrc); // 获取为该流分配的服务器端SSRC
packet->SetSsrc(mappedSsrc);
// 3. 处理RTP扩展头(例如,更新AbsSendTime)
UpdateRtpHeaderExtensions(packet);
// 处理后,将报文传递给Router
this->router->ForwardPacketFromProducer(this, packet);
return true;
}
二、Router的核心职责:订阅关系管理与报文分发
Router是转发框架的“交换中心”,其核心职责是维护生产者(Producer)与消费者(Consumer)之间的订阅关系,并基于此关系进行高效的报文复制与分发。其工作不涉及媒体内容的解析或修改,专注于高效率的路由。
路由逻辑伪代码
void Router::OnProducerPacketReceived(Producer* producer, RtpPacket* packet) {
auto& consumerList = subscriptionMap[producer];
for (Consumer* consumer : consumerList) {
// 为每个Consumer更新MID(如果需要)
if (!consumer->GetMid().empty()) {
packet->UpdateMid(consumer->GetMid());
}
// 将报文分发给Consumer
consumer->SendPacket(packet);
}
}
三、Consumer的核心职责:流适配、过滤与发送端重写
Consumer是面向接收端的适配器,其核心职责是根据下游客户端的能力、当前的订阅策略(如选择Simulcast的某一层)以及网络状况,对从Router接收到的标准化流进行最终处理,然后发送出去。
Consumer职责对比表
| SimpleConsumer | 转发单路流,可选丢弃DTX(静音包)。 | SSRC重写、序列号重排。 |
| SimulcastConsumer | 从多路Simulcast流中,根据策略选择并转发特定空域/时域层。 | SSRC重写、序列号重排、时间戳同步与重写。 |
| SvcConsumer | 从SVC流中,根据策略选择并转发特定编码层(基础层+可选增强层)。 | SSRC重写、序列号重排。 |
| PipeConsumer | 用于服务器间流转发,通常转换最少。 | 根据配置进行基本字段转换。 |
四、协同工作流程与数据转换全景
数据包从进入Producer到离开Consumer,经历了一个完整的转换管道。以下表格概括了报文关键字段在各个环节的转换状态:
| Payload Type | 客户端定义的PT | 映射为服务端统一PT | 保持不变 | 保持不变(接收端期望的PT已在SDP中约定) |
| SSRC | 客户端SSRC | 重写为Producer内部映射SSRC | 保持不变 | 重写为接收端协商的SSRC |
| Sequence Number | 客户端序列号 | 保持不变 | 保持不变 | 可能重排,以维持连续性 |
| Timestamp | 客户端时间戳 | 保持不变 | 保持不变 | Simulcast下可能重写,以保持切换连续性 |
| MID | 客户端MID(如有) | 可能被处理/标准化 | 可能被Router更新为目标Consumer的MID | 保持不变 |
| 扩展头部 (如Frame-Marking) | 客户端原始值 | 被解析、可能部分更新 | 保持不变 | 基于解析信息进行过滤决策 |
通过以上分工,mediasoup的转发框架实现了高内聚、低耦合的设计:Producer专注于“输入标准化”,Router专注于“高效路由”,Consumer专注于“输出适配”。这种架构使得系统能够灵活支持WebRTC、Simulcast、SVC等多种复杂场景,同时保证了转发的高性能和可扩展性 。
参考来源
- 深入浅出mediasoup—媒体处理

