mediasoup 源码分析(六)consumer和producer

consumer和producer

    • 一、consumer 类型介绍
    • 二、创建过程
    • 三、创建Producer时传进来rtpParameter
    • tips

一、consumer 类型介绍

mediasoup总共有四种消费者类型,SimpleConsumer、PipeConsumer、SvcConsumer、SimucastConsumer。
consumer的类型是基于producer的类型来创建的。
SimpleConsumer: 普通RTP数据的消费者,对应PlainTransport。
PipeConsumer:不同Worker之间Router之间的数据流转,则其为接收或者消费从另外一个Worker中的Router传过来的数据。
SvcConsumer:传输时一般分为3层(核心层、拓展层、边缘层)进行传输,则其处理消费多层数据。
SimulcastConsumer :Simulcast 多播模式,即当共享者使用的是多路流时,则使用其来接收。

二、创建过程

见Transport.ts 的consume函数

async consume(
{producerId,rtpCapabilities,paused = false,preferredLayers,appData = {}
}: ConsumerOptions
): Promise<Consumer>
{
....
....//创建Consumerconst reqData ={kind : producer.kind,rtpParameters,//创建consumer时,type类型来自producer的类型  //对应 Producer中的_data.type ,在Producer构造函数中创建type  : producer.type,  consumableRtpEncodings : producer.consumableRtpParameters.encodings,paused,preferredLayers};const status =await this._channel.request('transport.consume', internal, reqData);
}

producer.type来自于创建producer时c++层的返回结果,代码如下:
创建producer时指定了rtpParameters,c++层会基于该参数中的编码器信息确定producer的类型。
代码见Transport.cpp

//c++层创建producer,并把类型返回给node.js层的Transport.ts
Transport::HandleRequest(Channel::Request* request)
{case Channel::Request::MethodId::TRANSPORT_PRODUCE:{auto* producer = new RTC::Producer(producerId, this, request->data); // Create status response.json data = json::object();data["type"] = RTC::RtpParameters::GetTypeString(producer->GetType());request->Accept(data);//返回producer的类型,这个返回值在Channel.ts的this._consumerSocket读取到//然后传给_processMessage中的sent.resolve(msg.data),这个最终返回到request()的resolve//最后返回给Transport.ts中创建producer的地方const status = await this._channel.request('transport.produce', internal, reqData);//此处的status就是上面的c++层的data。//又新定义一个data结构把参数传给了Producer的构造函数内部。const data ={kind,rtpParameters,type : status.type,//这个类型就是创建consumer是的producer.typeconsumableRtpParameters};}
}
//c++层Producer的构造函数
Producer::Producer(const std::string& id, RTC::Producer::Listener* listener, json& data): id(id), listener(listener){ auto jsonRtpParametersIt = data.find("rtpParameters");if (jsonRtpParametersIt == data.end() || !jsonRtpParametersIt->is_object())MS_THROW_TYPE_ERROR("missing rtpParameters");// This may throw.this->rtpParameters = RTC::RtpParameters(*jsonRtpParametersIt);// Evaluate type. 基于rtpParameters获得Producer的类型this->type = RTC::RtpParameters::GetType(this->rtpParameters);
}
//基于rtpParameters获取producer类型的逻辑RtpParameters::Type RtpParameters::GetType(const RtpParameters& rtpParameters){MS_TRACE();if (rtpParameters.encodings.size() == 1){auto& encoding = rtpParameters.encodings[0];if (encoding.spatialLayers > 1 || encoding.temporalLayers > 1)return RtpParameters::Type::SVC;elsereturn RtpParameters::Type::SIMPLE;}else if (rtpParameters.encodings.size() > 1){return RtpParameters::Type::SIMULCAST;}return RtpParameters::Type::NONE;}

三、创建Producer时传进来rtpParameter

见:mediasoup-demo/server/lib/Room.js

//server.js接收到创建producer时,参数中包含rtpParametersasync createBroadcasterProducer({broadcasterId,transportId,kind,rtpParameters}){const broadcaster = this._broadcasters.get(broadcasterId);if (!broadcaster)throw new Error(`broadcaster with id "${broadcasterId}" does not exist`);const transport = broadcaster.data.transports.get(transportId);if (!transport)throw new Error(`transport with id "${transportId}" does not exist`);const producer =await transport.produce({ kind, rtpParameters });}  
//如ffmpeg.sh,是创建的PlainTranport,其创建rtpParameter参数如下:
rtpParameters:="{ \"codecs\": [{ \"mimeType\":\"audio/opus\", \"payloadType\":${AUDIO_PT}, \"clockRate\":48000, \"channels\":2, \"parameters\":{ \"sprop-stereo\":1 } }], \"encodings\": [{ \"ssrc\":${AUDIO_SSRC} }] }" \
对照上面c++的判断producer类型的地方,此处encoding.size=1,但是没有配置spatialLayers,
所以是simple类型,和PlainTranport对应。

tips

更多关于mediasoup的文章可以进入我的专栏查看
http://t.csdnimg.cn/3UQeL

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/859749.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

[Linux]缓冲区

一、概念 缓冲区&#xff0c;也称为缓存&#xff0c;是内存空间的一部分。也就是说&#xff0c;在内存空间中预留了一定的存储空间&#xff0c;用来缓冲输入或输出的数据。这个保留的空间称为缓冲区。 缓冲区的主要作用就是提高效率&#xff1a; 提高使用者的效率&#xff0…

【杂记-浅谈IS-IS路由协议】

这里写目录标题 一、IS-IS路由协议概述二、IS-IS协议特点三、IS-IS路由器分类四、IS-IS协议应用场景五、IS-IS与OSPF协议的比较 一、IS-IS路由协议概述 IS-IS&#xff0c;Intermediate System-to-Intermediate System&#xff0c;中间系统到中间系统&#xff0c;是一种内部网关…

大家都爱用!不可错过的 AI API 接口

AI API&#xff08;人工智能应用程序接口&#xff09;是一种软件中间件&#xff0c;它允许开发者和企业通过编程方式访问和集成人工智能服务到他们自己的应用程序、网站或系统中。AI API通常由专业的AI服务提供商开发和维护&#xff0c;使得用户无需深入了解复杂的AI算法和模型…

操作系统入门 -- 死锁

操作系统入门 – 死锁 1.什么是死锁、死锁产生的条件 1.1 死锁 在两个或多个并发进程中&#xff0c;如果每个进程都持有某种资源&#xff0c;并且正在等待其他进程释放它或进程都保持资源&#xff0c;在当前状态下无法推进。通俗来说就是两个或多个进程进入无限期阻塞、互相…

AI视频改字系统+五端兼容+卡密兑换+内置素材,系统搭建部署

目录 前言&#xff1a; 一、AI视频改字系统是什么 二、AI视频改字系统的功能 三、总结 前言&#xff1a; AI视频改字是利用套模板的原理&#xff0c;对短视频的模板进行更改&#xff0c;从而生成新的短视频。当然这个AI短视频改字系统都是有素材的&#xff0c;不用自己上传…

vim跳转到文件末尾

在 Vim 编辑器中&#xff0c;有几种方法可以跳转到文件的末尾&#xff1a; 使用 G 命令&#xff1a; 在 Vim 的正常模式下&#xff08;即不是插入模式或可视模式&#xff09;&#xff0c;只需按下大写字母 G。这将立即将光标移动到文件的末尾。 使用 : 命令模式&#xff1a; 在…

在小程序wxml中截取字符串

在微信小程序的WXML中直接进行字符串截取是不被支持的&#xff0c;因为WXML主要负责布局和渲染&#xff0c;不包含数据处理逻辑。 但你可以通过使用微信小程序提供的wxs&#xff08;WeiXin Script&#xff09;来实现字符串的截取。 wxs是一种运行在客户端的脚本语言&#xff…

tensorflow2实现多智能体强化学习算法MADDPG

目录 1.MADDPG算法简介2.实验环境搭建3.实验代码3.1 maddpg.py1.导入一些要使用的包以及函数2.MADDPG中单个智能体的结构基类(1)单个智能体的有关参数(2)单个智能体的有关网络的结构actor 的网络结构critic的网络结构 (3)优化器部分(4)MADDPGAgent完整代码 3.MADDPG中单个智能体…

深入解析与解决高并发下的线程池死锁问题

问题背景 在现代互联网应用中&#xff0c;高并发场景是常态&#xff0c;为了高效处理大量用户请求&#xff0c;后端服务通常会采用线程池来管理线程资源。然而&#xff0c;在一个复杂的微服务架构项目中&#xff0c;我们遇到了一个棘手的问题&#xff1a;在业务高峰期&#xf…

WSL安装的Ubuntu与docker desktop集成

WSL安装的Ubuntu与docker desktop集成 最近因为项目需要&#xff0c;要在本地利用WSL搭建一个docker和Ubuntu的部署环境。一开始并不知道docker desktop与Ubuntu可以集成使用&#xff0c;所以在Ubuntu上独立安装了docker引擎&#xff0c;但在安装docker-compose的时候出现以下…

MN316 AT模式丨低功耗实测分析

NB-IoT模组的应用场景一般具备低频次、小数据量、上行为主、工作时间短&#xff08;激活态时间短&#xff09;等特点。因此&#xff0c;休眠态的功耗是NB-IoT模组产品综合耗电的重点考量参数之一。中移物联OneMO超低功耗NB-IoT模组MN316&#xff0c;凭借其紧凑的尺寸、极低的休…

天翼云服务器80、443等特殊端口无法访问原因记录

之前阿里云、腾讯云的服务器上&#xff0c;想要用域名访问项目简单配置就好了&#xff0c;这次甲方直接买的翼云的服务器&#xff0c;配置了半天&#xff0c;防火墙端口80、443端口开放了&#xff0c;控制台安全组也添加了&#xff0c;就是不能用域名或IP直接访问&#xff0c;配…

51串口通讯

介绍 串口是一种应用十分广泛的通讯接口&#xff0c;串口成本低、容易使用、通信线路简单&#xff0c;可实现两个设备的互相通信。单片机的串口可以使单片机与单片机、单片机与电脑、单片机与各式各样的模块互相通信&#xff0c;极大的扩展了单片机的应用范围&#xff0…

Java读取指定 JAR 包路径中的 git.properties 文件

Java读取指定 JAR 包路径中的 git.properties 文件 在上述代码中&#xff0c;首先打开 JAR 文件&#xff0c;获取 git.properties 文件的 JarEntry 对象&#xff0c;如果存在该条目&#xff0c;就获取其输入流进行后续的读取和处理。具体的读取和处理逻辑需要根据您的实际需求在…

淘宝item_password接口技术详解

淘宝item_password接口技术详解 一、引言 在电商领域&#xff0c;淘宝作为中国最大的在线购物平台之一&#xff0c;拥有海量的商品信息和用户数据。为了方便用户快速访问和分享商品&#xff0c;淘宝推出了淘口令功能&#xff0c;这是一种加密的链接形式&#xff0c;用户可以在…

在QLineEdit或QPushButton上检测Enter键按下

前言 在开发一个游戏应用时,玩家需要猜测系统随机选择的数字。当玩家输入一个数字并点击“Play”按钮后,应用会根据玩家的猜测给出反馈。然而,频繁地点击按钮显得有些不便。为了提升用户体验,我们希望在玩家按下Enter键时也能触发相同的操作。本文将介绍如何在QLineEdit和…

一文搞懂Python局部变量与全局变量的12大陷阱

今天我们要来聊聊一个让人又爱又恨的话题——局部变量与全局变量的八大迷雾。在Python的世界里&#xff0c;变量就像是你的小宠物&#xff0c;有时候它们乖乖听话&#xff0c;但一不小心就给你挖了个大坑&#xff01;别担心&#xff0c;今天我们就一起把这些陷阱挖出来&#xf…

基于VTK9.3.0+Visual Studio2017 c++实现DICOM影像MPR多平面重建+V R体绘制4个视图展示功能的实现

开源库&#xff1a;VTK9.3.0 开发工具&#xff1a;Visual Studio2017 开发语言&#xff1a;C 实现过程&#xff1a; class vtkImageInteractionCallback : public vtkCommand { public:static vtkImageInteractionCallback* New(){return new vtkImageInteractionCallback()…

文库小程序搭建部署:实现资源共享正向反馈

文档库相信大家应该不陌生&#xff0c;日常我们的工作模板、会议模板、求职时的简历模板、教育界的教学模板等来源方式都出自于文档库&#xff0c;随着互联网的发展和工作需求&#xff0c;文档模板开启了新型的知识变现新途径&#xff0c;通过文库小程序&#xff0c;我们不仅能…

Web服务器与Apache(LAMP架构+搭建论坛)

一、Web基础 1.HTML概述 HTML&#xff08;Hypertext Markup Language&#xff09;是一种标记语音,用于创建和组织Web页面的结构和内容&#xff0c;HTML是构建Web页面的基础&#xff0c;定义了页面的结构和内容&#xff0c;通过标记和元素来实现 2.HTML文件结构 <html>…