当前位置:网站首页>一文带你了解webrtc基本原理(动手实现1v1视频通话)
一文带你了解webrtc基本原理(动手实现1v1视频通话)
2022-08-08 06:27:00 【王清培】
webrtc (Web Real-Time Communications) 是一个实时通讯技术,也是实时音视频技术的标准和框架。
大白话讲,webrtc是一个集大成的实时音视频技术集,包含了各种客户端api、音视频编/解码lib、流媒体传输协议、回声消除、安全传输等。
对于开发者来说可以借助webrtc非常方便的实现低延时视频通话能力。
现在主流的直播系统、会议系统基本都是基于webrtc来实现。
一、webrtc 三种架构
我们先大概了解下webrtc的几种架构及各自适用场景。
【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
由于是私有证书问题,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数据转发。
【SDP】
sdp是会话描述协议。
是媒体协商时使用,用于将本地支持的媒体(编解码等)信息、candidate(连接候选者)信息打包发送到信令服务器。
sdp的交换是通过中间服务器(信令服务器)来完成的。
【ICE】
ICE是一个不断尝试连接的协议,不同的网络情况下ICE大概会尝试如下几种方式来建立通讯通道。
host(peers都在内网)、 srflx(nat穿透)、prflx(nat穿透-Full Cone)、relay(中继)
【服务端】
在整个连接生命周期中都是需要服务端参与。参与webrtc协作的服务端大概分为这几种类型。
stun/turn服务器(p2p穿透)、信令服务器、媒体服务器(媒体信息处理)、业务服务器(可选)
整体流程大致如下。
(上述技术点较多,感兴趣可以自行查询相关资料)
【部署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]b.com: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】
注意,owt-server-4.3镜像与最新版chrome有兼容性问题,会报错 Empty candidate 错误。
我们直接使用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
OWT还配有管理后台用于控制媒体服务器的相关参数。
OWT还是比较强大的,有兴趣可以研究研究。
参考资料:
github.com/googollee/go-socket.io
《WebRTC技术详解:从0到1构建多人视频会议系统》
《WebRTC音视频实时互动技术:原理、实战与源码分析》
《FFmpeg 音视频开发基础与实战》
边栏推荐
猜你喜欢
leetcode第84场双周赛
websocket结合消息队列完成多台服务器下的订单服务主动通知
CSDN21天学习挑战赛之选择排序
Solved the problem that when VRTK transmission under Unity HDRP, the screen fades in and out, and the visual occlusion cannot be displayed correctly when passing through the wall
File IO realizes the encryption operation of pictures
Problem solving about Unity's button event response error triggering UI events
Unity_雷达图(属性图)+ UI动画
【图形学】08 3D坐标系的变换(一)
C语言实现链表的增删查改以及OJ题讲解
[Unity] 状态机事件流程框架 (一)(C#事件系统,Trigger与Action)
随机推荐
类与对象之动静态方法,继承,名字的查找顺序,经典类和新式类,派生方法
leetcode daily question 8.6 (continuously updated)
OSPF动态配置网络环境
rhcsa——第三天
线程P01——进程 并发 并行 线程的使用
P22 美颜相机——引入动态数组,优化重绘
[总结]Unity Console面板的问题汇总
Unity_组件自动绑定
P03 线程安全 synchronized Lock
三元表达式,各种生成式,匿名函数相关知识点
Nine common interfaces for implementing sequence table in C language
Unity_条形图(柱状图)+ UI动画
封装,property伪类属性,多态,反射
《Filter Pruning using Hierarchical Group Sparse》ICPR2020论文详解
多数之和小结
【图形学】12 UnityShader语法入门
Problems when signed and unsigned numbers are involved in operations
websocket结合消息队列完成多台服务器下的订单服务主动通知
Unity 本地 IIS 服务搭建之文件夹权限配置
【图形学】13 UnityShader语义(一)