【zlm】 webrtc源码讲解

目录

前端WEB

服务器收到请求

服务端的处理

 播放

拉流

参考文章


前端WEB

服务器收到请求

POST /index/api/webrtc?app=live&stream=test&type=play HTTP/1.1
 

HttpSession::onRecvHeaderHttpSession::Handle_Req_POSTHttpSession::Handle_Req_POSTif (totalContentLen > 0 && (size_t)totalContentLen < maxReqSize )_contentCallBack = [this,parserCopy](const char *data,size_t len) {//恢复http头_parser = parserCopy;//设置content_parser.setContent(string(data,len));//触发http事件,emitHttpEvent内部会选择是否关闭连接emitHttpEvent(true);//清空数据,节省内存_parser.Clear();//content已经接收完毕return false;};HttpSession::onRecvContent(const char *data,size_t len)if (_contentCallBack)_contentCallBack(data,len);        HttpSession::emitHttpEvent// 广播HTTP事件NoticeCenter::Instance().emitEvent(Broadcast::kBroadcastHttpRequest,_parser,invoker,consumed,static_cast<SockInfo &>(*this));

服务端的处理

// 主函数中调用web接口安装函数
installWebApiaddHttpListener();api_regist("/index/api/webrtc",[](API_ARGS_STRING_ASYNC){auto type = allArgs["type"];auto offer = allArgs.getArgs();WebRtcPluginManager::Instance().getAnswerSdp(*(static_cast<Session *>(&sender)), type,WebRtcArgsImp(allArgs, sender.getIdentifier()),[invoker, val, offer, headerOut](const WebRtcInterface &exchanger) mutable {headerOut["Content-Type"] = HttpFileManager::getContentType(".json");headerOut["Access-Control-Allow-Origin"] = "*";val["sdp"] = const_cast<WebRtcInterface &>(exchanger).getAnswerSdp(offer);val["id"] = exchanger.getIdentifier();val["type"] = "answer";invoker(200, headerOut, val.toStyledString());});});addHttpListener//注册监听kBroadcastHttpRequest事件NoticeCenter::Instance().addListener(&web_api_tag, Broadcast::kBroadcastHttpRequest,[](BroadcastHttpRequestArgs) {auto it = s_map_api.find(parser.Url());it->second(parser, invoker, sender);}                  

根据url找到对应的事件回调,最终会调用WebRtcPluginManager::Instance().getAnswerSdp。

WebRtcPluginManager::getAnswerSdpauto it = _map_creator.find(type);it->second(sender, args, cb);// 静态注册插件
WebRtcPluginManager::Instance().registerPlugin("play", play_plugin);void play_plugin(Session &sender, const WebRtcArgs &args, const WebRtcPluginManager::onCreateRtc &cb)// 使用rtsp媒体源,两者均是传输的rtp流info._schema = RTSP_SCHEMA;MediaSource::findAsync(info, session_ptr, [=](const MediaSource::Ptr &src_in) mutable {auto src = dynamic_pointer_cast<RtspMediaSource>(src_in);// 还原成rtc,目的是为了hook时识别哪种播放协议info._schema = RTC_SCHEMA;auto rtc = WebRtcPlayer::create(EventPollerPool::Instance().getPoller(), src, info, preferred_tcp);cb(*rtc); // 发送answer SDP给web端});    

 播放

拉流


Web端首先根据协商的IP和端口,服务端webrtc的端口是8000,发送STUN命令再次获取STUN地址。
首次连接,服务端会创建对应的session。

WebRtcSession::WebRtcSession(const Socket::Ptr &sock) : Session(sock)
  socklen_t addr_len = sizeof(_peer_addr);
  getpeername(sock->rawFD(), (struct sockaddr *)&_peer_addr, &addr_len);
  

WebRtcSession::onRecv_l(const char *data, size_t len)
  // 首次进入,根据username获取之前创建的transport.
  auto user_name = getUserName(data, len); // 此处的username就是之前设置的transport标识
  auto transport = WebRtcTransportManager::Instance().getItem(user_name);
  transport->setSession(shared_from_this());
  _transport = std::move(transport);
  _transport->inputSockData((char *)data, len, (struct sockaddr *)&_peer_addr);
  
  
WebRtcTransport::inputSockData
  // 处理STUN消息
  if (RTC::StunPacket::IsStun((const uint8_t *)buf, len))
    std::unique_ptr<RTC::StunPacket> packet(RTC::StunPacket::Parse((const uint8_t *)buf, len));
    _ice_server->ProcessStunPacket(packet.get(), tuple);
    return;
    
  // 处理    
  if (is_dtls(buf))
    _dtls_transport->ProcessDtlsData((uint8_t *)buf, len);
    return;
    
  // 由于是拉流,不存在rtp数据,但是有rtcp数据
  if (is_rtcp(buf))
    if (_srtp_session_recv->DecryptSrtcp((uint8_t *)buf, &len))
      onRtcp(buf, len);


DTLS交互完成后,接下来启动媒体传输

WebRtcTransport::OnDtlsTransportConnected
  onStartWebRTC();


WebRtcPlayer::onStartWebRTC
  WebRtcTransportImp::onStartWebRTC();
  _reader = _play_src->getRing()->attach(getPoller(), true);
  weak_ptr<WebRtcPlayer> weak_self = static_pointer_cast<WebRtcPlayer>(shared_from_this());
  weak_ptr<Session> weak_session = getSession();
  _reader->setReadCB([weak_self](const RtspMediaSource::RingDataType &pkt) {
    size_t i = 0;
    pkt->for_each([&](const RtpPacket::Ptr &rtp) {
      strong_self->onSendRtp(rtp, ++i == pkt->size());
    });
  });
 

参考文章

zlm源码研究 - webrtc播放-CSDN博客

WebRTC: Real-Time Communication in Browsers (w3.org) 

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

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

相关文章

科技评估分类

声明 本文是学习GB-T 42776-2023 科技评估分类. 而整理的学习笔记,分享出来希望更多人受益,如果存在侵权请及时联系我们 1 范围 本文件确立了科技评估的分类原则&#xff0c;描述了分类方法&#xff0c;规定了编码方法、分类与代码。 本文件适用于科技评估的规划、设计、委…

Ganache本地测试网+cpolar内网穿透实现公网访问内网

文章目录 前言1. 本地环境服务搭建2. 局域网测试访问3. 内网穿透3.1 ubuntu本地安装cpolar内网穿透3.2 创建隧道3.3 测试公网访问 4. 配置固定二级子域名4.1 保留一个二级子域名4.2 配置二级子域名4.3 测试访问公网固定二级子域名 前言 网&#xff1a;我们通常说的是互联网&am…

计算机毕设 大数据上海租房数据爬取与分析可视化 -python 数据分析 可视化

# 1 前言 &#x1f525; 这两年开始毕业设计和毕业答辩的要求和难度不断提升&#xff0c;传统的毕设题目缺少创新和亮点&#xff0c;往往达不到毕业答辩的要求&#xff0c;这两年不断有学弟学妹告诉学长自己做的项目系统达不到老师的要求。 为了大家能够顺利以及最少的精力通…

error:03000086:digital envelope routines::initialization error问题解决

目录 问题描述&#xff1a;error:03000086:digital envelope routines::initialization error 问题原因&#xff1a;nodejs V17 版本发布了 OpenSSL3.0 对算法和秘钥大小增加了更为严格的限制&#xff0c;nodeJs v17 之前版本没影响&#xff0c;但 V17 和之后版本会出现这个错…

短视频矩阵系统源代码开发搭建分享--代码开源SaaS

一、什么是短视频矩阵系统&#xff1f; 短视频矩阵系统是专门为企业号商家、普通号商家提供帐号运营从流量 到转化成交的一站式服务方案&#xff0c;具体包含&#xff1a;点赞关注评论主动私信 &#xff0c;评论区回复&#xff0c;自动潜客户挖掘&#xff0c;矩阵号营销&#x…

Codeforces Round 896 (Div. 1) C. Travel Plan(树形dp+组合数学)

题目 有一棵n(1<n<1e18)个点的树&#xff0c; 点i连着2*i和2*i1两个点&#xff0c;构成一棵完全二叉树 对于每个点i&#xff0c;记其值为a[i]&#xff0c;a[i]可以取[1,m](1<m<1e5)的整数 记i到j的简单路径上的最大值为s[i][j]&#xff0c; 则一棵权值确定的树…

邮件数据安全案例 | 有一种遇见,叫相见恨晚

Mr.赵回忆和联通相遇的时刻&#xff0c;他说&#xff0c;用一句诗来形容恰如其分&#xff0c;“众里寻他千百度&#xff0c;蓦然回首&#xff0c;那人却在&#xff0c;灯火阑珊处” 。 中国联合网络通信集团有限公司在国内31个省&#xff08;自治区、直辖市&#xff09;和境外…

排序算法:归并排序(递归和非递归)

朋友们、伙计们&#xff0c;我们又见面了&#xff0c;本期来给大家解读一下有关排序算法的相关知识点&#xff0c;如果看完之后对你有一定的启发&#xff0c;那么请留下你的三连&#xff0c;祝大家心想事成&#xff01; C 语 言 专 栏&#xff1a;C语言&#xff1a;从入门到精通…

【多目标跟踪】 TrackFormer 耗时三天 单句翻译!!!

【多目标跟踪】 TrackFormer 耗时三天 单句翻译&#xff01;&#xff01;&#xff01; TrackFormer: Multi-Object Tracking with Transformers Abstract The challenging task of multi-object tracking (MOT) re-quires simultaneous reasoning about track initiali…

uniappAndroid平台签名证书(.keystore)生成

一、安装JRE环境 https://www.oracle.com/java/technologies/downloads/#java8 记住下载默认安装地址。ps&#xff1a;我都默认安装地址C:\Program Files\Java\jdk-1.8 二、安装成功后配置环境变量 系统变量配置 AVA_HOME 放到环境变量去 %JAVA_HOME%\bin 三、生成签名证书…

本地电脑搭建SFTP服务器,并实现公网访问

本地电脑搭建SFTP服务器&#xff0c;并实现公网访问 文章目录 本地电脑搭建SFTP服务器&#xff0c;并实现公网访问1. 搭建SFTP服务器1.1 下载 freesshd 服务器软件1.3 启动SFTP服务1.4 添加用户1.5 保存所有配置 2. 安装SFTP客户端FileZilla测试2.1 配置一个本地SFTP站点2.2 内…

苹果手机无法正常使用小程序和APP

小程序、APP 已使用了几年&#xff0c;突然大量反馈&#xff1a;苹果手机无法正常使用。但不是全部&#xff0c;只是部分手机。 因为同事苹果手机都能用&#xff0c;所以无法准确判断具体原因。 后来同事苹果手机也无法使用了&#xff0c;显示&#xff1a; 网上搜索结果&…

全国职业技能大赛云计算--高职组赛题卷④(私有云)

全国职业技能大赛云计算--高职组赛题卷④&#xff08;私有云&#xff09; 第一场次题目&#xff1a;OpenStack平台部署与运维任务1 基础运维任务&#xff08;5分&#xff09;任务3 OpenStack云平台运维&#xff08;15分&#xff09;任务4 OpenStack云平台运维开发&#xff08;1…

【xshell7】设置语法高亮(突出显示集)方式

设置高亮方式 增加文件路径 将下面内容起名 以.hls结尾&#xff0c;放入截图位置&#xff0c;然后按照步骤一选择即可 [Keyword_0] TermBackColor1 Underline1 Bold0 Strikeout0 Keyword[_a-z0-9-](.[_a-z0-9-])*[a-z0-9-](.[a-z0-9-])* DescriptionEmail address BackColorIn…

解决jupyter找不到虚拟环境的问题

解决jupyter找不到虚拟环境的问题 使用jupyter只能使用base环境&#xff0c;不能找到自己创建的虚拟环境。如下图&#xff0c;显示的默认的虚拟环境base的地址。 如何解决这个问题&#xff1f;需要两个步骤即可 1 . 在base环境中安装nb_conda_kernels这个库 activate base c…

第9章 【MySQL】InnoDB的表空间

表空间 是一个抽象的概念&#xff0c;对于系统表空间来说&#xff0c;对应着文件系统中一个或多个实际文件&#xff1b;对于每个独立表空间来说&#xff0c;对应着文件系统中一个名为 表名.ibd 的实际文件。大家可以把表空间想象成被切分为许许多多个 页 的池子&#xff0c;当我…

Brother CNC联网数采集和远程控制

兄弟CNC IP地址设定参考&#xff1a;https://www.sohu.com/a/544461221_121353733没有能力写代码的兄弟可以提前下载好网络调试助手NetAssist&#xff0c;这样就不用写代码来测试连接CNC了。 以上是网络调试助手抓取CNC的产出命令&#xff0c;结果有多个行string需要自行解析&…

汽车电子系统总线LIN通信协议精要

汽车电子系统总线LIN通信协议精要 文章目录 汽车电子系统总线LIN通信协议精要简介LIN信号的物理层LIN总线收发器 LIN通信协议LIN的主机和从机LIN报文帧结构同步间隔段&#xff08;Break field&#xff09;同步段&#xff08;Sync field&#xff09;受保护的帧ID&#xff08;Pro…

uview组件库的安装

更多的请查看官方文档uView 2.0 - 全面兼容 nvue 的 uni-app 生态框架 - uni-app UI 框架 (uviewui.com) // 如果您的根目录没有package.json文件的话&#xff0c;请先执行如下命令&#xff1a; // npm init -y 安装 npm install uview-ui2.0.36 // 更新 // npm update uvie…

【案例教学】华为云API图引擎服务 GES的便捷性—AI帮助快速处理图片小助手

云服务、API、SDK&#xff0c;调试&#xff0c;查看&#xff0c;我都行 阅读短文您可以学习到&#xff1a;人工智能AI快速处理图片 1 IntelliJ IDEA 之API插件介绍 API插件支持 VS Code IDE、IntelliJ IDEA等平台、以及华为云自研 CodeArts IDE&#xff0c;基于华为云服务提供…