【流媒体服务器Mediasoup】 源码中重要类基本概念 、上层代码作用详解、底层C++类关系详解(四)_gjy_it的博客-程序员宅基地

技术标签: webrtc  源码分析  流媒体  mediasoup  

目录

 

前言     

MediaSoup的特性 

特性一

特性二

特性三

 

MediaSoup SFU简单的架构说明

MediaSoup库中Lib目录下的JS作用

MediaSoup-JS类的关系图

MediaSoup js部分起到的作用

MediaSoup C++ 库类关系图

核心类图

C++类图

小结


前言
     

      上篇文章对MediaSoup源码的调试方法  以及运行时分析、调试、查看核心信息   【流媒体服务器Mediasoup】调试源码以及运行时分析、调试、查看核心信息(三),本章节主要对MediaSoup的源码中重要类基本概念 、上层代码作用详解、底层C++类关系详解

      在下一篇文章中将继续对MediaSoup的源码进行分析和架构的讲解。

MediaSoup的特性 

特性一

  •       支持IPV6
  •       ICE/DTLS/RTP/RTCP    既可以在TCP协议上运行也可以在UDP协议上运行
  •       支持Simulcast(多流发送) 和 SVC(分层接收) 

特性二

  •        支持拥塞控制
  •        带宽评估  (Remb前几个章节有提到)
  •        支持STCP协议(非音视频数据 如文件,文本数据)

特性三

  •         多留使用同一个 ICE + DTLS 传输通道 (减少端口的占用)
  •         拥有强大的性能(底层是C++ 使用进程+LIBUV  异步I/O实践处理机制)

 

MediaSoup SFU简单的架构说明

              å¨è¿éæå¥å¾çæè¿°

Worker

  •       一个Worker代表着一个运行在单核CPU上并处理Router实例的mediasoup C++子进程;

Router

  •        Router用于注入、选择和转发通过Transport实例创建的媒体流;

Transport

  •        Transport将终端与MediaSoup Router连接起来,并通过在其上创建的Producer和Consumer实例实现双向媒体传输,实         现了下面3种Transport:WebRtcTransport,PlainRtpTransport,PipeTransport.
  1.       每个Client创建两个Peerconnection分别用于发送和接受媒体流,发送端用于发送承载本地videoTrack和audioTrack的      localStream,接收端接受来自其他Client的remoteStream;
  2.       同时Room会为每个Client创建一个Peer,Peer管理两个Transport用于接受Client的媒体流和向Client发送媒体流;
  3.      Peer为对应的Client发送的videoTrack和audioTrack分别创建一个Producer(共2个);
  4.      Peer为其他两个Client发送的videoTrack和audioTrack分别创建2个Consumer(共2个);
  5.      Producer将媒体数据发送给每一个订阅者Consumer
  6.     Consumer代表着一个被MediaSoup Router转发到终端的音频或视频源。它是在定义媒体数据包传送方式的Transport之上创建的。

 

MediaSoup库中Lib目录下的JS作用

               

        lib库需要先npm install   编译过后才会出现详细请参阅

                  【流媒体服务器Mediasoup】环境部署与demo搭建(二)

        npm install后 lib 库的路径为

                    server\node_modules\mediasoup\lib

                                                                  

AudioLevelObserver.js  

          用于检测声音的大小, 通过C++检测音频声音返回应用层,通过Observer接收并展示音频大小

Channel.js

          主要用于与C++部分信令通讯

Consume.js

      消费媒体数据,音频或视频

EnhancedEventEmitter.js

      EventEmitter的封装,C++底层向上层发送事件

Logger.js

      用于写日志

PipeTransport.js

      Router之间的转发

PlainRtpTransport.js

      普通的rtp传输通道,如FFmpeg等不经过浏览器rtp协议的数据传输

Producer.js

     生产媒体数据,音频或视频

Routers.js

     代表一个房间或者一个路由器

RtpObserver.js

     Rtp数据的观察者 回调用的

Transport.js

     所有传输的的基类(父类)

WebRtcRtpTransport.js

  浏览器使用的传输

Worker.js

    一个节点或者一个进程,实际应该是进程,代码中根据CPU核数启动相对   应的Worker数量;一个房间只能在一个Worker里。

Errors.js

     错误信息的定义

Index.js

     Mediasoup的库,上层引入Mediasoup最先导入的库,也为库的索引。

Ortc.js

     其与SDP相对应,以对象的形式标识SDP,如编解码参数,编解码器,帧   率等,以对象方式去存储。

ScalabilityModes.js

  一般不关心,略过

SupportedRtpCapabilities.js

  对通讯能力的支持,实际上是媒体协商相关的东西,如你支持的帧率, 码率,编解码器是什么等

Utils.js

       一些常见的工具函数

 

MediaSoup-JS类的关系图

 

                            

  • 每个Worker里有多个Router
  • 每个Worker里都有一个Channel(管道) 通过其与C++进行通讯
  • 每个用户的Transport可能会有多个Produces或者 Consume
  • ransoprt为WebRtcTransport(浏览器加密数据使用的传输)、PlainRtpTransport(自定义Rtp数据,如FFmpeg推流使用的传输)、PipeTransport(不同Router之间的通信传输)的基类

MediaSoup js部分起到的作用

  • 起到管理作用,通过上图可以看出各个模块之间的关系
  • 生成JSON字符串,传给C++; 作为承上启下的作用,即是应用层调用的接口层,又是C++层的适配层或者桥梁层,上层应用与C++的一个桥梁。

例如

 createRouter({ mediaCodecs, appData = {} } = {}) {
           ....            
            yield this._channel.request('worker.createRouter', internal);
            const data = { rtpCapabilities };
            const router = new Router_1.Router({
                internal,
                data,
                channel: this._channel,
                appData
            });
          .....
    }

 ..channel.request()最后会构造json字符串通过channel 传给C++层,C++层则做它自己相对应的逻辑操作.

 

MediaSoup C++ 库类关系图

   对于C++库来说是整个MediaSoup库中最核心的部分,包括了基本的一些管理,这些管理或者关系相对于JS来说要少一些,但最主要的是流的传输,首先对于WebRtc 要先进行数据加密再传到服务端之后要对这些数据进行解密操作。另外包括整个数据的安全,它的验证机制是由C++部分进行验证的,包括流的流转,数据的流转,带宽的评估,发生丢包之后的通知客户端进行重传等操作都是有C++部分完成这些工作。

核心类图

                 

SimpleConsumer

        普通RTP数据的消费者,比如有音频流和视频流每个都是SimpleConsumer,没有按类型区分,音视频流都是一样的,最简单的consumer

PipeConsumer

        不同Worker之间Router之间的数据流转,则其为接收或者消费从另外一个Worker中的Router传过来的数据

SvcConsumer

        传输时一般分为3层(核心层、拓展层、边缘层)进行传输,则其处理消费多层数据

SimulcastConsumer

        当共享者使用的是多路流时,则使用其来接收

Consumer

        为上述模块的基类(父类)

WebRtcTransport

        主要用于浏览器之间的或者浏览器与其他终端进行通讯的,这种传输数据一般是进行加密的,为了保证数据安全,它有很多安全机制,安全机制较为复杂。

PlainRtpTransport

用于普通或者自定义的rtp数据传输

PipeTransport

不同Worker之间Router之间的数据传输

TransportTuple

包括了本地的Socket,远端的Soucket ,使用的是TCP还是UDP , 传输协议等信息存储地方

Transport

        各种传输的基类(父类)

 

C++类图

                 

RtpPack的起作用为对rtp数据包的一个分析,如Rtp包中有包头,拓展头,数据,对于数据协议或者解析都是它的工作

SeqManager对传输的数据重新进行排序和处理,相当于WebRtc客户端与服务端之间进行传输数据的时候 服务端要新产生一个流推送给客户端,整个顺序都是重新排的,某个SSRC所对应的起始位置是多少,后面的包都是以这个起始包基础上进行传输和排序递增

所有Consumer都包含了RtpStreamSend对象, 从服务端角度来说,消费数据等于把数据发送给其他客户端

Producer对于服务端来说,他要生产流数据则就是接受客户端传输来的数据,因此每个Producer会对应多个RtpStreamRecv,为什么会有多个接收流?有可能是丢包了,丢包重传的数据也是单独的一路流。RtpStreamRecv使用了NackGenerator(丢包的一个产生器),对于接受者来说,发送者发了100个包,那么接受者是知道丢了哪些包(通过SeqManager知道丢的哪些包), 如果短时间内可以通过NackGenerator对客户端通知 进行补包。

WebRtcTransport

可以使用UDP或者TCP来传输数据,这两种传输都用PortManager进行端口管理,Mediasoup的默认端口为4000~4999(不同woker[进程]可复用),管理如关口是否被占用等一些策略。具体的传输工作还是 handle目录下的::UdpSocket和 ::TcpServer来完成。UdpSocket和TcpServer只是做了一层封装。

使用了上述的数据连接之后,对于上层传输来说,DtlsTransport 使用了dtls协议对rtp数据包进行加密的传输,在DtlsTransport 会用到SrtpSession的 收与发。RembClient和RembServer主要用于带宽的评估,对于共享者来说MediaSoup它的WebRtcTransport就是一个Clinet端,对于消费者来说,它就是Server端。Remb只是其中一种带宽评估方法,还有其他,这里不做重点讲解。

TransportTuple很多可选项存储在IceServer里,一对多的关系,TransportTuple如果是Tcp连接那么里面还包含了::TcpConnection,  其与 ::TcpServer又有关系,它包含了多个::TcpConnection

 

小结

有很多人对 Nodejs 比较诟病,认为 Nodejs 提拱不了高性能的流媒体服务器。实际上,如果按照传输的 Nodejs 应用开发出的流媒体服务器肯定是不能胜任这项工作的。但对于 Mediasoup 来讲,它只不过使用 Nodejs 做 信令处理 及 业务的管理 工作,所以它的负担并不重。对性能要求高的是媒体数据流的转发工作,而这部分工作是由 Mediasoup(C++)部分实现的。Nodejs 与 Mediasoup之间通过管道进行通信。

严格意义上来说,Mediasoup是单进程的。但这不影响了它的性能。实际上,它是使用单进程的方式将服务器上CPU某个 充分利用好,然后在业务层控制进程的个数。比如说你的服务器是个 8 核的CPU,那么在业务层你就该启动 8 个Mediasoup进程。通过这种方式来达到对 CPU 的充分利用。

 

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/gjy_it/article/details/104474095

智能推荐

mediasoup-client-android-moudle.rar

https://blog.csdn.net/gjy_it/article/details/104414037 Android中编译mediasoupclient/webrtc.a 纯源码编译,直接module导入即可

Mediasoup学习笔记01-开发环境的搭建和部署

为什么学习Mediasoup轻量级,入门简单,拓展性强,支持点对点,支持服务器转发。 环境搭建 1.虚拟机的安装 若有能力请支持正版 虚拟机使用 VMware Workstation 15x 下载地址:...

mediasoup安装使用

基于mediasoup的多方通话研究(一) https://blog.csdn.net/gupar/article/details/83788934 npm install mediasoup npm install mediasoup-client

Visio 2016专业版 激活方式

Visio 2016专业版 激活方式 最新visio2016激活密钥,visio2016是一个独立组件,如果安装了正版visio2016专业版,需要visio专业版2016密钥激活。激活visio2016有两种秘钥:一种是visio2016永久激活码,一种是visio...

win7旗舰版/专业版黑屏后怎样再次永久激活?

windows7大家在使用过程中遇到最严重的问题就是经常出现黑屏。今天小编教你永久解决这个问题。 win7专业版/旗舰版出现黑屏的原因主要有两个: 一:之前在激活的时候采用了破解或者其他官方不认可的方法,ID被拉黑...

selenium中的expected_conditions模块详解

这两个条件类验证title,验证传入的参数title是否等于或包含于driver.title title_is title_contains   这两个人条件验证元素是否出现,传入的参数都是元组类型的locator,如(By.ID, 'kw') 顾名思义,一个只要一个...

Java for Selenium | 理解类与对象

类与对象是面向对象编程语言中最重要的一个基本概念,Java也不例外。理解了类与对象的概念,学习起Java来就会容易很多。 本篇为大家介绍java类与对象的概念。在我们开始讨论类与对象之前,让我们先进入到生活中的一...

win7激活提示错误代码0x80072EE2的最可行解决办法

很多同学在激活win7旗舰版,专业版和家庭版的时候遇到过提示错误代码0x80072EE2的困难,小编经过几次周折,终于完美解决问题,下面小编就把相关经验为大家分享一下。一,首先保证你的密钥是可用的,如果密钥失效或者...

win7旗舰版激活提示错误代码0x80072EE2的最简单解决办法

很多同学在激活win7旗舰版,专业版和家庭版的时候遇到过提示错误代码0x80072EE2的困难,小编经过几次周折,终于完美解决问题,下面小编就把相关经验为大家分享一下。一,首先保证你的密钥是可用的,如果密钥失效或者...

详解socket通信 之 TCP连接与断开详解

TCP(Transmission Control Protocol,传输控制协议)是一种面向连接的、可靠的、基于字节流的通信协议,数据在传输前要建立连接,传输完毕后还要断开连接。 客户端在收发数据前要使用 connect() 函数和服务器建立...

Python程序中自定义异常类

通过创建一个新的异常类,程序可以命名它们自己的异常。异常应该是典型的继承自Exception类,通过直接或间接的方式。 以下为与RuntimeError相关的实例,实例中创建了一个类,基类为RuntimeError,用于在异常触发时...

语义分割+视频分割 开源代码文献集合

基于单张训练样本的视频运动物体分割 Video Object Segmentation Without Temporal Information One-Shot Video Object Segmentation http://www.vision.ee.ethz.ch/~cvlsegmentation/osvos/图像语义匹配 SC...

quartus_ii 驱动

下载驱动程序,(win7 32/64位均可(亲测),win8请自行...win8:http://wenku.baidu.com/link?url=d-ARP0GuBZoh7Gjy89-vxhGXMyndURCUVC2pD7BgGmtJ7VVNtQtif_w5CaO6bDBB-cVB0B2T7fQdj3nCJxnjTAJ7OAC6wRqnqyE0jpEGCRO

关于pyinstaller出现No such file or directory: 'C:\\Users\\qhcsu\\AppData\\Local\\Temp\\_MExx\\xx\xx...

最近在给小老板做项目,编码阶段一直很顺利,直到最后打包出现了让人头疼的问题。 目前将py打包成exe有cxfreeze、py2exe以及我们要说的pyinstaller的方式。废话不多说,直接上问题 问题一:no module found name’ ...

gjy c#

1 using System; 2 public class MyDate{ 3 private int month,day,year; 4 public MyDate(int _month=1,int _day=1,int _year=1900){ 5 bool ok=true; 6 if(_month>1...

人群计数最全代码、数据、论文合集

amp;mid=2247487704&idx=1&sn=e0ea4c28c51cd153aaf388edaadb4d86&chksm=ec1ffd21db687437251a48a0047f991a0c5cae1700322591c69a0da2ee9f01f0bead2fd...

TensorBoard可视化详解

本文参考博客...有助于对tensorboard的理解# coding=utf-8 import tensorflow as tf """ 首先载入Tensorflow,并设置训练的最大步数为1000,学习率为0.001,dropout的保留比率为0.9。 同时,设置MNIST

每日毒鸡汤励志加油PHP网站源码

介绍: ...源码非常的小,直接上传支持PHP的空间即可使用 如果需要删除或添加修改心灵鸡汤语句的 打开dutang.txt文本里面操作即可 网盘下载地址: http://kekewl.net/rsU9vPk6gJY0 图片: ...

Burnside引理和Polya定理详解(适合零基础)

声明:本知识点为帮助大家更好地理解置换群论这一抽象的内容,一些定义中掺杂了撰写者自身的理解,和严格的数学定义有些出入,基本为数学定义的缩小解释和限制解释。 另外,统一一些符号的使用。 对集合A,|A|表示A...

cookies详解

cookies简介 cookie是什么? ...定义于 RFC2109 和 2965 中的都已废弃,最新取代的规范是 RFC6265[1]。Cookie其实就是浏览器缓存。 cookie的生命周期 会话cookie:没有设置expires(是个时间...

Python异步编程详解

我们都知道对于I/O相关的程序来说,异步编程可以大幅度的提高系统的吞吐量,因为在某个I/O操作的读写过程中,系统可以先去处理其它的操作(通常是其它的I/O操作),那么Python中是如何实现异步编程的呢? 简单的...

Pytorch手写数字集基于Tensorboard的可视化损失函数(loss)、准确率(...梯度(grad)、权值(data)的源码

Tensorboard的可视化损失函数(loss)、准确率(Accuracy)、梯度(grad)、权值(data)的源码,以Pytorch手写数字集为例讲解 一、源码 import torch import torch.nn as nn import torch.utils.data as Data from ...

python正则表达式详解

正则表达式是一个很强大的字符串处理工具,几乎任何关于字符串的操作都可以使用正则表达式来完成,作为一个爬虫工作者,每天和字符串打交道,正则表达式更是不可或缺的技能,正则表达式的在不同的语言中使用方式可能...

Python使用Pycrypto库进行RSA加密的方法详解

密码技术的用途主要源于两个方面,加密/解密和签名/验签在信息传播中,通常有发送者,接受者和窃听者三个角色。假设发送者Master想要写信给接受者Ghost,可是又不想信的内容被别人看到,因此Master需要先...

定时任务 Crontab命令 详解

前言crontab是Unix和Linux用于设置周期性被执行的...一个是 要求你的调度程序比较可靠,实际工作中,90%的程序都没有必要花这么多时间和精力去解决上面的两个问题的,只需要写好自己的业务逻辑,通过crond这 个工...

npm install Saving to file: /root/.jenkins/workspace/ems-web/node_modules/chromedriver/2

问题: ➜ npm install npm WARN deprecated [email protected]: this package has been reintegrated into npm and is now out of date with respect to npm > [email protected] install /Users/user/wisedu/...

Python的namedtuple使用详解

Python的namedtuple使用详解 namedtuple是继承自tuple的子类。namedtuple创建一个和tuple类似的对象,而且对象拥有可访问的属性。 下面看个列子 from collections import namedtuple # 定义一个namedtuple类型...

概率论问题_生日问题

问题描述: 在一个教室中最少应有多少学生才使得至少有两个学生的生日在同一天的概率不小于1/2?直觉回答这应该是个三位数的答案,对吧! 然而答案是23!!!!第一次遇到这个问题是高中看一个不知道什么知识点...

Date,日期类,日历类

一、Date 日期 创建对象后,代表当前时间 1.导包,快捷键自动导入 java.util.Date; 2.... 数据类型 变量名 = new 数据类型();... Date date = new Date();... 3.... getYear() 获取年份:计算机界从1900...

随便推点

在Windows下使用Navicat连接虚拟机Linux Centos下的MySql_张吵吵的博客-程序员宅基地

今天想用navicat远程连接虚拟机中的MySQL数据库,一直连不上,在网上搜索了一下,发现原因是MySQL对远程用户登陆的授权问题。这里记录一下我在网上参考了几个文件后的解决方法:一、先使用root权限进入MySqlmysql -uroot(这里是你的MySQL用户名) -p123456(这里是你的MySQL密码)二、然后将权限授予其他电脑GRANT ALL PRIVILEGES ON *.* TO 'root'@'%' IDENTIFIED BY '123456' WITH GRANT OP

iOS 模拟器运行报错原因之一_iOS开发程序媛-程序员宅基地

Unable to boot device due to insufficient system resources.Please see Simulator Help for information on adjusting system settings to allow more simulated devices to boot at once.maxUserProcs: 709,...

uni-app项目 发布为安卓 app_pauline_的博客-程序员宅基地

1. 点击 HBuilderX 状态栏左侧的未登录按钮 , 弹出登录的对话框2. 在弹出的登录对话框中 , 填写帐号和密码之后 , 点击登录即可3. 打开项目根目录中的 manifest.json 配置文件 , 在基础配置面板中 , 获取uni-app 应用标识 , 并填写应用名称:4. 切换到 App 图标配置面板 , 点击浏览按钮 , 选择合适的图片之后 , 再点击自动生成所有图标并替换即可:5. 点击菜单栏上的 发行 => 原生app-云打包6. 勾选打包配置如下

Google 强迫微软弃用 Edge 内核?_CSDN资讯-程序员宅基地

一场巨头之间的合作触发的“战争”......去年 10 月,微软低调地上线了基于 Chromium 的 Android 版 Edge。而一周前,微软 Windows 副总裁Joe Belfiore 在官方博客对外宣布微软放弃基于 EdgeHTML 的 Web 渲染引擎的开发,转而让自家的桌面版 Edge 浏览器也将采用 Chromium 开源项目。整体而言,微软动身去拥抱起...

swap自动释放内存_十色花的博客-程序员宅基地

#free -mh如上图,一般情况下不会用到swap的,一般物理内存使用在90%以上(默认是这个数,可以自行在/etc/sysctl.conf里设置vm.swappiness参数),但有的时候,内存会被缓存占用,导致系统开始使用swap空间,此时就需要清理下swap了这里先说下vm.swappiness参数,设置成vm.swappiness=10:就是说当内存使用90%以上才会使用swap空间...

MongoDB 组合多个条件查询($and、$in、$gte、$lte)_weixin_33701617的博客-程序员宅基地

一,问题描述数据格式: id, timeStamp,count条件1:查询 某个时间段 内的数据: timeStamp BETWEEN startTime AND endTime。比如 timeStamp BETWEEN 1499875200  AND 1499875600条件2:记录 的 id 字段 属于某集合: id IN (1001,1002,1003)条件3:记录 的count字段...

Python 预测孩子身高_奔跑的树懒先生-程序员宅基地_python身高测算

Python 孩子身高预测:源代码:# 创建死循环,直至 用户自行 选择 退出while True : # 分割线 print('*'*60) print('*'*10,'欢迎来到 孩子身高 预测系统','*'*10) # 功能选择 print('\t1、预测查询') print('\t2、退出系统') menus_select ...

推荐文章

热门文章

相关标签