一文带你了解webrtc基本原理(动手实现1v1视频通话)_webrtc的原理-程序员宅基地

技术标签: webrtc  互联网协议与标准  音视频  服务器  

webrtc (Web Real-Time Communications) 是一个实时通讯技术,也是实时音视频技术的标准和框架。
大白话讲,webrtc是一个集大成的实时音视频技术集,包含了各种客户端api、音视频编/解码lib、流媒体传输协议、回声消除、安全传输等。
对于开发者来说可以借助webrtc非常方便的实现低延时视频通话能力。
现在主流的直播系统、会议系统基本都是基于webrtc来实现。

一、webrtc 三种架构

我们先大概了解下webrtc的几种架构及各自适用场景。

webrtc_arch.png

【Mesh】

Mesh架构,需要所有参与连接的peer建立与所有其他peer的媒体连接。
该架构需要n-1个上下行,以此带来的带宽消耗(流量)、编/解码消耗(手机性能)成线性增长。
该架构只能适用3-4个人的小型会议场景。

【MCU】

所有本房间的peer将本地媒体流推到远程媒体服务器,由媒体服务器进行混流,然后再推到所有连接的peer端。
该架构的优点就是只需要1路上下行,随着peer人数不断增加,依然不会对用户造成带宽、手机性能影响。
该架构将压力转嫁到服务端,由专用媒体服务器来完成混流,转推等功能。

【SFU】

相对于MCU来说SFU只做转发,媒体服务器压力有限。与mesh架构相比,只需要n-1个下行,1个上行。
在大规模的场合该架构具有伸缩性。

二、实现 1v1 视频通话

废话不多说,动手实践下。
(麻雀虽小,五脏俱全。通过实现1v1的功能,来整体了解下webrtc协议的原理。)
github:https://github.com/Plen-wang/webrtc-demo-1v1

mesh_p2p.png

由于是私有证书问题,chrome会有安全提示。(demo地址暂时还能用 -_- )

有两个方法可以试下。

第一个方法,手动设置一个类似不安全白名单列表,然后重启浏览器。

chrome://flags/#unsafely-treat-insecure-origin-as-secure

如果不行,我们试下第二个方法肯定可以。

点击空白页输入 thisisunsafe字符。

动手之前,我们先简单了解下webrtc的连接的大致流程和涉及的相关技术点。

【WebRTC P2P】

【NAT穿透】
peer基本都在内网,需要通过nat穿透技术来与peer建立连接。
根据nat的拓扑情况大致分为如下几种:完全锥形、IP锥形、端口锥形、对称形。
stun\turn协议:stun协议用来拿到peer公网ip,turn用来做relay数据转发。

5Figure41.png

【SDP】
sdp是会话描述协议。
是媒体协商时使用,用于将本地支持的媒体(编解码等)信息、candidate(连接候选者)信息打包发送到信令服务器。
sdp的交换是通过中间服务器(信令服务器)来完成的。

【ICE】
ICE是一个不断尝试连接的协议,不同的网络情况下ICE大概会尝试如下几种方式来建立通讯通道。
host(peers都在内网)、 srflx(nat穿透)、prflx(nat穿透-Full Cone)、relay(中继)

【服务端】
在整个连接生命周期中都是需要服务端参与。参与webrtc协作的服务端大概分为这几种类型。
stun/turn服务器(p2p穿透)、信令服务器、媒体服务器(媒体信息处理)、业务服务器(可选)

整体流程大致如下。

webrtc_connection.png

(上述技术点较多,感兴趣可以自行查询相关资料)

【部署STUN\TURN服务器】

为了支持1v1公网访问,我们需要搭建一个stun/turn服务器。
这里我们使用 Coturn 开源组件,coturn的镜像有很多,可自行选择。
(注意准备coturn配置文件时,记得设置用户名和密码。)

    docker run -d  --rm --name turn-server --network=host   \
               -v ${pwd}/turnserver.conf:/etc/coturn/turnserver.conf \
           instrumentisto/coturn

部署好之后可以通过ICE测试工具测试下
https://webrtc.github.io/samples/src/content/peerconnection/trickle-ice

    stun:1.15.11.173:3478?transport=tcp
    turn:1.15.11.173:3478?transport=tcp:user:pwd

如果正常返回了ICE尝试的连接类型,说明部署没有问题。

【实现信令服务器与客户端代码】

我们采用golang来实现一个简单的信令服务器,使用开源组件go-socket。
同时还需要实现一个web客户端。
demo代码就不贴到文章里了,放在github上。整体代码比较简单,感兴趣可以看下。
[email protected]:Plen-wang/webrtc-demo-1v1.git

【部署信令服务器】
当在本地debug的差不多了,我们把信令服务器打个镜像发到云主机上。
(如果部署本demo,可以直接使用此镜像。)

    docker push wangqingpei/rtc-signal-server:latest
    docker run --name signal-server -d -p:8080:8080 wangqingpei/rtc-signal-server
    

【部署web服务器】
部署好信令服务器之后,我们把静态文件放到web服务器里,直接使用nginx镜像部署非常简单。

    docker run -d -p 80:80 -p 443:443  --rm --name webrtc-nginx   \
    -v /data/rtc-nginx.conf:/etc/nginx/nginx.conf  \
    -v /data/pem/server.key:/etc/nginx/server.key  \
    -v /data/pem/server.pem:/etc/nginx/server.pem  \
    -v /data/rtc-static-file:/usr/share/nginx/html  nginx

部署前,记得修改js里的stun服务器地址。

//创建RTCPeerConnection对象
function createRTCPeerConnection() {
    try {
	    
	    const configuration = {'iceServers': [{'urls': 'stun:1.15.11.173:3478?transport=tcp'}]}
	    
        rtcConnObject = new RTCPeerConnection(configuration);
        rtcConnObject.onicecandidate = handleRtcICECandidate;//ice 交互
        rtcConnObject.onaddstream = handleRtcAddStream;//远程stream加入
        rtcConnObject.onremovestream = handleRtcRemoveStream;//远程stream移除
        rtcConnObject.addStream(localStreamObject);//添加本地stream
        console.log("create local RTCPeerConnection object ok.");
    } catch (e) {
        console.error("create RTCPeerConnection err.", e);
    }
}

两边peer就可以借助stun服务器拿到公网ip实现nat穿透。

三、实现MCU/SFU 多人通话

MCU/SFU架构需要 专用媒体服务器 参与。

【媒体服务器选择】

专用媒体服务器有 OWT(open webrtc toolkit)、TWS(Kurento Media Server)等重量级的开源产品。

这两款开源框架都支持MCU、SFU架构功能。

我们选择OWT捣鼓下。

先看下部署起来的效果,默认MCU模式。

owt_ok.png

红框部分是服务端混流之后的效果。

【部署OWT】

注意,owt-server-4.3镜像与最新版chrome有兼容性问题,会报错 Empty candidate 错误。

owt_empty_candidate.png

我们直接使用5.0的镜像部署。

docker run -d --name owt-demo --network host lmshao/owt-server

由于该镜像是使用默认配置打的,启动后手动进入容器修改下相关配置,换成你云主机的公网ip,然后重启服务。

配置文件路径

vi dist/webrtc_agent/agent.toml

配置项,这里修改成你的公网ip

network_interfaces = [{name = "eth0", replaced_ip_address = "1.116.175.232"}]  # default: []

stun服务器可选

stunport = 3478 #default: 0
stunserver = "1.15.11.173" #default: ""

然后修改下portal.toml文件,文件路径。

vi dist/portal/portal.toml

修改成公网ip

ip_address = "1.116.175.232" #default: ""

重启下相关服务

./bin.restart-all.sh 

注意启动日志里有一个id、key,这是用来进入管理页面用的。(没错,owt提供了后台管理页面 -_-)

superServiceId: xxx
superServiceKey: xxx

sampleServiceId: xxx
sampleServiceKey: xxx

默认3004端口下是mcu模式,连线的人多了就会明显卡顿(看服务器配置)。

我们切到SFU模式试下流畅度和服务器负载情况。

通过 ?forward=true 参数控制

https://1.116.175.232:3004/?forward=true

demo_sfu.png

OWT还配有管理后台用于控制媒体服务器的相关参数。
owt_room.png
owt_room_detail.png

OWT还是比较强大的,有兴趣可以研究研究。

参考资料:
github.com/googollee/go-socket.io
《WebRTC技术详解:从0到1构建多人视频会议系统》
《WebRTC音视频实时互动技术:原理、实战与源码分析》
《FFmpeg 音视频开发基础与实战》

关注微信公众号|收获更多干货

在这里插入图片描述

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

智能推荐

python 人脸提取_Python 自动提取电影中所有人脸-程序员宅基地

文章浏览阅读1.1k次。最近由于论文写作需要涉及到人脸的提取操作,结合以前做过的人脸识别项目:Python自动识别人脸开机和 ffmpeg 的影片逐帧提取功能,实现了自动提取电影中所有人脸的操作。我们知道,机器学习、深度学习的算法需要数据量到达一定量级之后效果才比较好。所以我们今天的这个功能主要可以用于一些人脸识别算法的训练集、测试集提取。1.准备我们使用ffmpeg提取视频中的图片,它的安装方法如下:1.1(1)w..._视频中提取人脸

jenkins java版本_jenkins 多版本 jdk-程序员宅基地

文章浏览阅读3.4k次。最近又开始使用jenkins了,遇到一个问题,开发本地使用的jdk是1.7,而我们jenkins由于需要对docker的插件的支持必须使用1.8。这样就导致了有的开发的代码在jenkins去代码库checkout代码的时候,有的代码能被jenkins打包,但是有的代码拉取下来登录到jenkins宿主机能够使用mvn install打包,但是不能被jenkins打包,出现这个问题主要是mvn使用的是...

Cocos2d-x 3.2:通过ClippingNode实现一个功能完善的跑马灯公告(2)-程序员宅基地

文章浏览阅读54次。Cocos2d-x 3.2:通过ClippingNode实现一个功能完善的跑马灯公告(2)本文转载至深入理解Cocos2d-x 3.x:一步一步通过ClippingNode实现一个功能完善的跑马灯公告(2)本文的主要内容是根据跑马灯解析ClippingNode实现原理。本文涉及到Cocos2d-x 3.x的渲染机制以及部分opengl的知识。首先看看上一篇文章中说到的跑马灯的简单...

【深度学习】RNN-程序员宅基地

文章浏览阅读6.9k次,点赞4次,收藏31次。循环神经网络(Recurrent Neural Network, RNN)是一类以序列(sequence)数据为输入,在序列的演进方向进行递归(recursion)且所有节点(循环单元)按链式连接的递归神经网络(recursive neural network)。_rnn

pert计算公式期望值_练习-三点估算和PERT技术-程序员宅基地

文章浏览阅读873次。三点估算和PERT技术通过考虑估算中的不确定性和风险,可以提高活动持续时间估算的准确性。这个概念起源于计划评审技术(ProjectEvaluationandReviewTechnique,PERT)。PERT经常使用3种估算值来界定活动持续时间的近似区间,其关系如下:·最可能时间(tE)。活动的持续时间估算。项目管理论坛·最可能时间(tM)。基于最可能获得的资源、最可能取得的资源生产率..._beta pert 分布, 三点时间满足 90%概率分布,求期望时间te

MFC链接SQL Server ——学生成绩管理系统-程序员宅基地

文章浏览阅读3.3k次,点赞18次,收藏67次。MFC链接SQL Server连接数据库新建一个udl文件,服务器名称与SQL Server服务器保持一致。选择相应的数据库,测试连接。(先建好数据库)将udl文件改成txt文件。打开该文件,第3行为SQL Server数据库连接字符串。在MFC项目中添加连接代码新建基于对话框的MFC应用程序项目,按学号命名。在电脑查找msado15.dll的路径,例如:C:\Program Files (x86)\Common Files\System\ado\msado15.dll在MFC项目头文

随便推点

64位下无法使用Microsoft.Jet.OLEDB.4.0的解决方法-程序员宅基地

文章浏览阅读9.5w次,点赞4次,收藏9次。OLE DB 访问接口 'Microsoft.Jet.OLEDB.4.0' 配置为在单线程单元模式下运行,所以该访问接口无法用于分布式查询解决办法1.下载ACE2010的驱动,64位的。http://www.microsoft.com/downloads/zh-cn/details.aspx?familyid=c06b8369-60dd-4b64-a44b-84b371ed_microsoft.jet.oledb.4

全球首家!苹果市值达 3 万亿美元,AR 和自动驾驶是下一重点?-程序员宅基地

文章浏览阅读212次。作者 | 苏宓出品 | CSDN(ID:CSDNnews)成立于 1976 年的苹果公司,耗时 44 年,终于在 2018 年首次达到 1 万亿美元的市值。自此之后,苹果的发展仿佛安装了“高速马达”,短短两年后的 2020 年 8 月,苹果市值超越沙特阿美,打开 2 万亿美元的大门,成为彼时全球市值最高的上市公司。这一次,苹果仅用了一年的时间,在 2022 年新年伊始,于...

Java/Python/Go不同开发语言在进程、线程和协程的设计差异_线程和进程 不同的编程语言-程序员宅基地

文章浏览阅读1.5k次,点赞18次,收藏17次。在多线程项目开发时,最常用、最常遇到的问题是1,线程、协程安全2,线程、协程间的通信和控制本文主要探讨不同开发语言go、java、python在进程、线程和协程上的设计和开发方式的异同。_线程和进程 不同的编程语言

Spring Boot @PathVariable出现点号"."时导致路径参数截断获取不全的解决办法_springboot 路径参数 不支持点-程序员宅基地

文章浏览阅读4.9k次。@PathVariable出现点号"."时导致路径参数截断获取不全的解决办法时间:2015-05-28 17:59:54 阅读:756 评论:0 收藏:0[点我收藏+]标签:springmvc pathvaria 小数点 点 参数不全 1、问题 SpringMVC项目中通过下面的URL进行GET请求。当versi_springboot 路径参数 不支持点

Android与H5的交互_window['userinfo']-程序员宅基地

文章浏览阅读289次。如今H5的广泛应用,使得Android与H5交互也变得十分广泛,这篇文章就交互问题浅谈一下。 Android通过内置的控件Webview来加载H5页面。webview的应用十分简单,只有设置一下其属性即可。代码如下: webView.setVerticalScrollBarEnabled(false);webView.setHorizon_window['userinfo']

oracle正则表达式regexp_like的用法详解_oracle regexp_like \n\t\r-程序员宅基地

文章浏览阅读4.8w次,点赞6次,收藏97次。ORACLE中的支持正则表达式的函数主要有下面四个: 1,REGEXP_LIKE :与LIKE的功能相似 2,REGEXP_INSTR :与INSTR的功能相似 3,REGEXP_SUBSTR :与SUBSTR的功能相似 4,REGEXP_REPLACE :与REPLACE的功能相似 它们在用法上与Oracle SQL 函数LIKE、INSTR、SUBSTR 和REPLACE 用法相同,..._oracle regexp_like \n\t\r