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视频通话)的更多相关文章

  1. 一文带你了解elasticsearch

    一文带你了解elasticsearch cxf2102100人评论160人阅读2019-07-02 21:31:36   elasticsearch es基本概念 es术语介绍 文档Document ...

  2. Istio是啥?一文带你彻底了解!

    原标题:Istio是啥?一文带你彻底了解! " 如果你比较关注新兴技术的话,那么很可能在不同的地方听说过 Istio,并且知道它和 Service Mesh 有着牵扯. 这篇文章可以作为了解 ...

  3. 一文带您了解5G的价值与应用

    一文带您了解5G的价值与应用 5G最有趣的一点是:大多数产品都是先有明确应用场景而后千呼万唤始出来.而5G则不同,即将到来的5G不仅再一次印证了科学技术是第一生产力还给不少用户带来了迷茫——我们为什么 ...

  4. 【转帖】Istio是啥?一文带你彻底了解!

    Istio是啥?一文带你彻底了解! http://www.sohu.com/a/270131876_463994 原始位置来源: https://cizixs.com 如果你比较关注新兴技术的话,那么 ...

  5. 一文带你了解 C# DLR 的世界

    一文带你了解 C# DLR 的世界 在很久之前,我写了一片文章dynamic结合匿名类型 匿名对象传参,里面我以为DLR内部是用反射实现的.因为那时候是心中想当然的认为只有反射能够在运行时解析对象的成 ...

  6. 一文带你看清HTTP所有概念(转)

    一文带你看清HTTP所有概念   上一篇文章我们大致讲解了一下 HTTP 的基本特征和使用,大家反响很不错,那么本篇文章我们就来深究一下 HTTP 的特性.我们接着上篇文章没有说完的 HTTP 标头继 ...

  7. 一文带你了解js数据储存及深复制(深拷贝)与浅复制(浅拷贝)

    背景 在日常开发中,偶尔会遇到需要复制对象的情况,需要进行对象的复制. 由于现在流行标题党,所以,一文带你了解js数据储存及深复制(深拷贝)与浅复制(浅拷贝) 理解 首先就需要理解 js 中的数据类型 ...

  8. 【项目实践】一文带你搞定Spring Security + JWT

    以项目驱动学习,以实践检验真知 前言 关于认证和授权,R之前已经写了两篇文章: [项目实践]在用安全框架前,我想先让你手撸一个登陆认证 [项目实践]一文带你搞定页面权限.按钮权限以及数据权限 在这两篇 ...

  9. 一文带你看遍 JDK9~14 的重要新特性!

    Java9 发布于 2017 年 9 月 21 日 .作为 Java8 之后 3 年半才发布的新版本,Java 9 带 来了很多重大的变化其中最重要的改动是 Java 平台模块系统的引入,其他还有诸如 ...

随机推荐

  1. 万字长文,带你轻松学习 Spark

    大家好,我是大D. 今天给大家分享一篇 Spark 核心知识点的梳理,对知识点的讲解秉承着能用图解的就不照本宣科地陈述,力求精简.通俗易懂.希望能为新手的入门学习扫清障碍,从基础概念入手.再到原理深入 ...

  2. SQL中常用的字符串LEFT函数和RIGHT函数详解!

    今天继续整理日常可能经常遇到的一些处理字符串的函数,记得点赞收藏!以备不时之需!看到最后有惊喜! LEFT(expression, length)函数 解析:从提供的字符串的左侧开始提取给定长度的字符 ...

  3. pandas:数据迭代、函数应用

    1.数据迭代 1.1 迭代行 (1)df.iterrows() for index, row in df[0:5].iterrows(): #需要两个变量承接数据 print(row) print(& ...

  4. Java虚拟机启动过程解析

    一.序言 当我们在编写Java应用的时候,很少会注意Java程序是如何被运行的,如何被操作系统管理和调度的.带着好奇心,探索一下Java虚拟机启动过程. 1.素材准备 从Java源代码.Java字节码 ...

  5. conda创建/移除虚拟环境

    conda创建python虚拟环境 前言 conda常用的命令: conda list 查看安装了哪些包. conda env list 或 conda info -e 查看当前存在哪些虚拟环境 co ...

  6. python基础知识-day9(数据驱动)

    1.数据驱动的概念 在自动化测试中,需要把测试的数据分离到JSON,YAML等文件中. 2.YAML 的相关知识 YAML 入门教程 分类 编程技术 YAML 是 "YAML Ain't a ...

  7. 11.2 Android Studio如何切换主题和更改字体

    如何进入设置? 全平台启动界面 Configure-Preferences 主界面 Windows版本:File-Settings Mac版本:Android Studio-Preferences 外 ...

  8. RapidEye快鸟、SPOT卫星遥感影像数据

    ​目前地理遥感生态网平台已发布高分辨率卫星遥感影像数据. 数据样例:百度云下载链接:https://pan.baidu.com/s/17ofPwpDM3OCHnE-LuhvUp 提取码:i0m4   ...

  9. Tapdata 在线研讨会:DaaS vs 大数据平台,是竞争还是共处?

    从20年前的传统数仓,到10年前大数据平台,5年前开始火热的数据中台以及最近出现的湖仓一体新数据平台,今天被数据孤岛困扰的企业,面临着太多的选择.这些数据产品及架构有一个共性:他们本质上解决的大部分都 ...

  10. labview从入门到出家5(进阶篇)--程序调试以及labview函数库的运用

    跟了前面几章的操作流程,相信大家对labview有了一定的认识.其实只要了解了labview的编程思路,再熟悉地运用各个变量,函数以及属性,那么我们就可以打开labview的大门了.跟其他编程语言一样 ...