一文带你了解webrtc基本原理(动手实现1v1视频通话)
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上。整体代码比较简单,感兴趣可以看下。
git@github.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 音视频开发基础与实战》
一文带你了解webrtc基本原理(动手实现1v1视频通话)的更多相关文章
- 一文带你了解elasticsearch
一文带你了解elasticsearch cxf2102100人评论160人阅读2019-07-02 21:31:36 elasticsearch es基本概念 es术语介绍 文档Document ...
- Istio是啥?一文带你彻底了解!
原标题:Istio是啥?一文带你彻底了解! " 如果你比较关注新兴技术的话,那么很可能在不同的地方听说过 Istio,并且知道它和 Service Mesh 有着牵扯. 这篇文章可以作为了解 ...
- 一文带您了解5G的价值与应用
一文带您了解5G的价值与应用 5G最有趣的一点是:大多数产品都是先有明确应用场景而后千呼万唤始出来.而5G则不同,即将到来的5G不仅再一次印证了科学技术是第一生产力还给不少用户带来了迷茫——我们为什么 ...
- 【转帖】Istio是啥?一文带你彻底了解!
Istio是啥?一文带你彻底了解! http://www.sohu.com/a/270131876_463994 原始位置来源: https://cizixs.com 如果你比较关注新兴技术的话,那么 ...
- 一文带你了解 C# DLR 的世界
一文带你了解 C# DLR 的世界 在很久之前,我写了一片文章dynamic结合匿名类型 匿名对象传参,里面我以为DLR内部是用反射实现的.因为那时候是心中想当然的认为只有反射能够在运行时解析对象的成 ...
- 一文带你看清HTTP所有概念(转)
一文带你看清HTTP所有概念 上一篇文章我们大致讲解了一下 HTTP 的基本特征和使用,大家反响很不错,那么本篇文章我们就来深究一下 HTTP 的特性.我们接着上篇文章没有说完的 HTTP 标头继 ...
- 一文带你了解js数据储存及深复制(深拷贝)与浅复制(浅拷贝)
背景 在日常开发中,偶尔会遇到需要复制对象的情况,需要进行对象的复制. 由于现在流行标题党,所以,一文带你了解js数据储存及深复制(深拷贝)与浅复制(浅拷贝) 理解 首先就需要理解 js 中的数据类型 ...
- 【项目实践】一文带你搞定Spring Security + JWT
以项目驱动学习,以实践检验真知 前言 关于认证和授权,R之前已经写了两篇文章: [项目实践]在用安全框架前,我想先让你手撸一个登陆认证 [项目实践]一文带你搞定页面权限.按钮权限以及数据权限 在这两篇 ...
- 一文带你看遍 JDK9~14 的重要新特性!
Java9 发布于 2017 年 9 月 21 日 .作为 Java8 之后 3 年半才发布的新版本,Java 9 带 来了很多重大的变化其中最重要的改动是 Java 平台模块系统的引入,其他还有诸如 ...
随机推荐
- 第6组 Alpha冲刺 (5/6)
目录 1.1 基本情况 1.2 冲刺概况汇报 1.郝雷明 2. 方梓涵 3.董翔云 4.杜筱 5.詹鑫冰 6.黄少丹 7.曹兰英 8.鲍凌函 9.曾丽莉 10.吴沅静 1.3 冲刺成果展示 1.1 基 ...
- JS - 使用 html2canvas 将页面转PDF
JS - 使用 html2canvas 将页面转PDF 本方法可以将页面元素块转为pdf. 网站地址 jspdf.js 官网地址:http://jspdf.com GitHub 主页:https:// ...
- VTK 截图
vtk的vtkRenderWindowInteractor中的Initialize函数初始化了可交互的窗口,但是实际工程中,往往需要把窗口拿出来在别的页面上显示,如存为png图片等等.本文主要介绍如何 ...
- 认识一下什么是JSP
摘要:JSP,全称是Java Server Pages,即Java服务器页面,是由Sun Microsystems公司主导创建的一种动态网页技术标准. 本文分享自华为云社区<Java服务器页面- ...
- 在.NET中计算文件的MD5值
更新记录 本文迁移自Panda666原博客,原发布时间:2021年7月2日. 直接上代码吧: using System; using System.IO; using System.Security. ...
- JS:条件语句1
条件语句: 1.if...else if (condition1) { 当条件 1 为 true 时执行 } else { 当条件 1 不为 true 时执行 } if (condition1) { ...
- 数据库系列:MySQL索引优化总结(综合版)
1 背景 作为一个常年在一线带组的Owner以及老面试官,我们面试的目标基本都是一线的开发人员.从服务端这个技术栈出发,问题的范围主要还是围绕开发语言(Java.Go)等核心知识点.数据库技术.缓存技 ...
- React技巧之检查元素是否可见
原文链接:https://bobbyhadz.com/blog/react-check-if-element-in-viewport 作者:Borislav Hadzhiev 正文从这开始~ 总览 在 ...
- java中JVM和JMM之间的区别
一 jvm结构 jvm的内部结构如下图所示,这张图很清楚形象的描绘了整个JVM的内部结构,以及各个部分之间的交互和作用. 1 Class Loader(类加载器)就是将Class文件加载到内存,再说的 ...
- 华为HMS Core携手超图为三维GIS注入新动能
6月30日,在2022(第五届)GIS软件技术大会GIS基础软件新技术板块论坛上,华为联合超图推出了基于HMS Core 3D Engine开发的高保真三维GIS插件,通过3D渲染技术助力三维GIS实 ...