mediasoup源码走读(十)——producer

10.1、Producer 核心定位与模块交互

Producer 是 Mediasoup 的"媒体流源",它不是孤立组件,而是通过与 Router、Transport、RtpObserver 和 Consumer 的深度交互,构建完整的实时媒体流管理系统。
模块交互全景图
创建/管理 注册/质量监控 发送RTP包 分发媒体流 生命周期管理 网络传输 接收媒体流 Producer Router RtpObserver Transport Consumer Network 应用层


10.2、端到端工作流程

应用层 Mediasoup Router Producer Transport RtpObserver Consumer Network createProducer(track) 创建Producer实例 注册到Router管理 通知Producer创建 注册Transport回调 发送媒体轨道 初始化编码器 创建RtpObserver 注册RtpObserver回调 发送RTP包 SendRtpPacket(packet) 发送RTP数据包 OnTransportData(packet) OnRtpPacket(packet) 计算质量指标 trigger('qualityChange', stats) 执行自适应策略 分发RTP包 处理媒体流 loop [媒体流传输] close() 通知关闭 清理资源 通知关闭 通知已关闭 关闭RtpObserver 通知Consumer关闭 应用层 Mediasoup Router Producer Transport RtpObserver Consumer Network


10.3、关键模块交互代码

10.3.1 Producer 与 Router 的生命周期交互

Router 创建 Producer

cpp 复制代码
// mediasoup/src/Router.cpp
Producer* Router::CreateProducer(
  Transport* transport,
  const std::string& trackId,
  const std::string& trackKind,
  const std::string& codec,
  const std::string& codecOptions,
  const std::vector<Encoding>& encodings
) {
  // 1. 生成唯一ID
  std::string id = GenerateId("producer");
  
  // 2. 创建Producer实例
  Producer* producer = new Producer(
    this, id, transport, trackId, trackKind, codec, 
    codecOptions, encodings
  );
  
  // 3. 注册到Router管理
  producers_.insert({id, producer});
  
  // 4. 通知Transport
  transport->OnProducerCreated(producer);
  
  return producer;
}

Producer 关闭流程

cpp 复制代码
// mediasoup/src/Producer.cpp
void Producer::Close() {
  if (isClosed) return;
  
  isClosed = true;
  Emit("close");
  
  // 1. 通知Router
  router->CloseProducer(this);
  
  // 2. 通知所有Consumer
  for (auto& consumer : consumers_) {
    consumer->Close();
  }
}
10.3.2 Producer 与 Transport 的数据传输交互

Producer 发送RTP包

cpp 复制代码
// mediasoup/src/Producer.cpp
void Producer::SendRtpPacket(RtpPacket* packet) {
  if (isClosed || isPaused) return;
  
  // 1. 调用Transport发送
  transport->SendRtpPacket(packet);
  
  // 2. 通知RtpObserver
  if (rtpObserver) {
    rtpObserver->OnRtpPacket(packet);
  }
}

Transport 接收并处理RTP包

cpp 复制代码
// mediasoup/src/Transport.cpp
void Transport::SendRtpPacket(RtpPacket* packet) {
  // 1. 更新网络统计
  stats.totalPackets++;
  stats.totalBytes += packet->size();
  
  // 2. 发送到网络
  SendToNetwork(packet);
  
  // 3. 通知Producer传输状态
  if (producer) {
    producer->OnTransportData(packet);
  }
}
10.3.3 Producer 与 RtpObserver 的质量监控交互

Producer 创建RtpObserver

cpp 复制代码
// mediasoup/src/Producer.cpp
RtpObserver* Producer::CreateRtpObserver(const RtpObserverOptions& options) {
  // 1. 创建RtpObserver实例
  rtpObserver = new RtpObserver(this, options);
  
  // 2. 注册到Router
  router->RegisterRtpObserver(rtpObserver);
  
  return rtpObserver;
}

RtpObserver 质量监控触发

cpp 复制代码
// mediasoup/src/RtpObserver.cpp
void RtpObserver::OnRtpPacket(RtpPacket* packet) {
  // 1. 更新统计
  stats.totalPackets++;
  stats.lastPacketTime = packet->timestamp;
  
  // 2. 检查阈值
  if (CheckThresholds()) {
    // 3. 触发事件(关键交互点)
    producer->OnQualityChange(stats);
  }
}

Producer 响应质量变化

cpp 复制代码
// mediasoup/src/Producer.cpp
void Producer::OnQualityChange(const RtpQualityStats& stats) {
  // 1. 检查当前编码层
  int currentLayer = GetCurrentEncodingIndex();
  
  // 2. 根据质量调整码率
  if (stats.packetLossRate > 0.15 && currentLayer > 0) {
    SetPreferredEncoding(currentLayer - 1); // 降低码率
  } else if (stats.packetLossRate < 0.05 && currentLayer < encodings.size() - 1) {
    SetPreferredEncoding(currentLayer + 1); // 提高码率
  }
}
10.3.4 Producer 与 Consumer 的媒体分发交互

Consumer 创建流程

cpp 复制代码
// mediasoup/src/Router.cpp
Consumer* Router::CreateConsumer(
  Transport* transport,
  Producer* producer,
  const std::string& trackId,
  const std::string& trackKind
) {
  // 1. 生成Consumer ID
  std::string id = GenerateId("consumer");
  
  // 2. 创建Consumer实例
  Consumer* consumer = new Consumer(
    this, id, transport, producer, trackId, trackKind
  );
  
  // 3. 添加到Router管理
  consumers_.insert({id, consumer});
  
  // 4. 通知Producer
  producer->OnConsumerCreated(consumer);
  
  return consumer;
}

Producer 分发媒体流

cpp 复制代码
// mediasoup/src/Producer.cpp
void Producer::SendRtpPacket(RtpPacket* packet) {
  // ... [之前代码] ...
  
  // 1. 通知所有Consumer
  for (auto& consumer : consumers_) {
    consumer->OnRtpPacket(packet);
  }
}

10.4、Producer 的完整生命周期管理

10.4.1 生命流程图

Creating Active Closed Paused

10.4.2 关键生命周期方法

创建

cpp 复制代码
// mediasoup/src/Producer.cpp
Producer::Producer(
  Router* router,
  Transport* transport,
  const std::string& trackId,
  const std::string& trackKind,
  const std::string& codec,
  const std::string& codecOptions,
  const std::vector<Encoding>& encodings
) : 
  router(router),
  transport(transport),
  trackId(trackId),
  trackKind(trackKind),
  codec(codec),
  codecOptions(codecOptions),
  encodings(encodings),
  isClosed(false),
  isPaused(false) {
  
  // 1. 注册到Router
  router->CreateProducer(this);
  
  // 2. 初始化编码器
  InitializeCodecs();
}

暂停/恢复

cpp 复制代码
// mediasoup/src/Producer.cpp
void Producer::Pause() {
  if (isPaused) return;
  isPaused = true;
  Emit("pause");
}

void Producer::Resume() {
  if (!isPaused) return;
  isPaused = false;
  Emit("resume");
}

关闭

cpp 复制代码
// mediasoup/src/Producer.cpp
void Producer::Close() {
  if (isClosed) return;
  
  isClosed = true;
  Emit("close");
  
  // 1. 通知Router
  router->CloseProducer(this);
  
  // 2. 通知所有Consumer
  for (auto& consumer : consumers_) {
    consumer->Close();
  }
  
  // 3. 清理RtpObserver
  if (rtpObserver) {
    rtpObserver->Close();
    rtpObserver = nullptr;
  }
}

10.5、Producer 的模块交互与生命周期总结

模块交互

模块 交互方式 关键作用 交互点体现
Router 创建/管理/关闭 全局生命周期管理 router->CreateProducer()
Transport 发送RTP包/接收回调 网络传输通道与状态反馈 transport->SendRtpPacket()
RtpObserver 注册/质量监控/事件触发 自适应码率决策基础 rtpObserver->OnRtpPacket()
Consumer 媒体流分发/接收回调 多接收端媒体流同步 producer->OnConsumerCreated()

生命周期关键点

  1. 创建:Router 生成唯一ID,Producer 初始化编码器
  2. 激活:Transport 注册回调,RtpObserver 创建
  3. 传输:Producer 通过 Transport 发送RTP包,RtpObserver 监控质量
  4. 自适应:质量变化触发 Producer 码率调整
  5. 关闭:Router 清理资源,通知所有关联组件
相关推荐
历程里程碑3 小时前
普通数组----轮转数组
java·数据结构·c++·算法·spring·leetcode·eclipse
李日灐3 小时前
C++进阶必备:红黑树从 0 到 1: 手撕底层,带你搞懂平衡二叉树的平衡逻辑与黑高检验
开发语言·数据结构·c++·后端·面试·红黑树·自平衡二叉搜索树
汉克老师3 小时前
GESP2025年6月认证C++二级( 第一部分选择题(1-8))
c++·循环结构·表达式·分支结构·gesp二级·gesp2级
byte轻骑兵3 小时前
从HCI报文透视LE Audio重连流程(3):音频流建立、同步与终止
音视频·蓝牙·le audio·cig/cis·广播音频
rainbow68893 小时前
C++高性能框架Drogon:后端开发新标杆
c++
杜子不疼.3 小时前
【Linux】库制作与原理(二):动态库的制作与使用
linux·运维·服务器
Q741_1473 小时前
C++ 优先级队列 大小堆 模拟 力扣 703. 数据流中的第 K 大元素 每日一题
c++·算法·leetcode·优先级队列·
小白电脑技术4 小时前
飞牛漏洞焦虑?别瞎折腾WAF了!用Lucky五步搞定“防爬墙”
服务器·网络·安全
消失的旧时光-19434 小时前
Nginx 是什么?为什么它不写在代码里?——从 0 认识 Nginx
运维·服务器·nginx
RisunJan4 小时前
Linux命令-lpq(查看打印队列状态)
linux·运维·服务器