mediasoup数据转发 源码剖析

一. mediasoup重要类说明

Worker:mediasoup 流媒体处理进程

Router:路由对象,类似于房间的功能,保存了流之间的订阅关系,它接收 Producer 的数据并转发给订阅该 Producer 的 Consumer

Producer:音视频流生产者,一路音频就算一个单独的生产者,一路视频也算一个单独的生产者

Consumer:音视频流消费者

Transport:传输通道,有 WebRtcTransport,PlainRtpTransport 以及 PipeTransport

        上图解释如下:一个 Worker 可以有多个 Router,客户端通过 Transport 与后台进程产生连接,并通过 Transport 发送流数据或者消费流数据。通道有多种类型,有基于 WebRTC 协议的通道,也有普通的 RTP/RTCP 通道,还有不同 Router 间转发数据的 PipeTransport。

二. 数据路由代码剖析

1. 创建 Router

         Websocket 监听连接请求并创建媒体层的路由对象。

 

 

2. 创建 Transport

        通过 Websocket 信令创建房间路由后,客户端与媒体需要建立通道,客户端可以通过通道把媒体流发送给服务端(生产),也可以通过通道消费其他流的数据(消费)。Transport 有 PlainTransport,WebRtcTransport 等,我们以 WebRtcTransport 为例。

 

        WebRtcTransport 的构造函数中通过 listenIp, port 创建 UdpSocket,UdpSocket 继承自 UdpSocketHandler,UdpSocketHandler 包含了 uv_udp_t* 对象,它是一个 libuv 的 UDP 事件处理对象,我们通过注册相应的回调函数即可在有事件发生时调用回调函数处理。

        在服务端创建 WebRtcTransport 对象后,还需要通过 connectWebRtcTransport 才能让客户端与该通道对象产生关联,该流程主要是进行 DTLS 认证。

 

3. 生产流数据 Produce

        创建连接通道后,客户端可以通过该通道发送流媒体数据,每一路流称为一个 Producer。

 

        调用 produce 后,Transport 会回调 Router::OnTransportNewProducer 告知 Router 该路由对象产生了一个新的生产者,Router 会记录 producer_id 与 Producer 对象的映射关系,相当于保存了该路由对象当前有哪些生产者。

4. 消费流数据 consume

        Router 有了流数据的生产者,还需要有消费该 Producer 的 Consumer,这样 Router 才会将收到的 Producer 数据转发给 Consumer。

        在这篇博客中介绍了信令的交互流程,通过 join 加入房间时,已经为准备加入房间的用户订阅了所有存在于房间的 Producers。

 

        C++ Transport 收到 TRANSPORT_CONSUME 请求后,根据 type 创建出相应类型的 Consumer,然后通知 Router::OnTransportNewConsumer,在该函数中最重要的就是存放 Producer 与 Consumers 的映射关系,该结构体对象为:std::unordered_map<RTC::Producer*, std::unordered_set<RTC::Consumer*>> mapProducerConsumers,即将新的 Consumer 加入到Producer 对应的 Consumer 集合中。 

 

 

5. 数据转发

        当生产者发送媒体数据后,首先得到通知的是 UDP socket,因为我们使用 libuv 注册了读事件的回调,因此会回调 onRecv,再调用 UdpSocketHandler::OnUvRecv,之后再调用 WebRtcTransport::OnUdpSocketPacketReceived,之后的调用流程如下所示。

 

 

 

 

         最终可以看到 WebRtcTransport::OnRtpDataReceived 处理完再交给父类 RTC::Transport::ReceiveRtpPacket,其根据 Packet 的 ssrc 确认 Producer 源对象后,调用 Produer 的 ReceiveRtpPacket 处理,之后再通知 Transport::OnProducerRtpPacketReceived 处理,Transport 再通知 Router::OnTransportProducerRtpPacketReceived 处理,Router 根据保存的订阅关系,调用 Consumer::SendRtpPacket 将数据包给相应通道的客户端。

  • 6
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

椛茶

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值