webrtc笔记(2): 1对1实时视频/语音通讯原理概述
开始正文之前,先思考1个问题:2个处于不同网络环境的(具备摄像头/麦克风多媒体设备的)浏览器,要实现点对点的实时视频/语音通讯,难点在哪?
至少得先搞定下面2个问题:
1、彼此要了解对方支持的媒体格式、支持的最大分辨率等媒体信息

比如:peerA端可支持MPEG-1/2、H264多种编码格式,而peerB端支持MPEG-4、H264,要保证二端都正确的编解码,最简单的办法就是取它们的交集H264
就象2个不同国家的人交流,1个只会讲英文、中文,另1个只会讲德语、英文,他俩肯定要能相互正常沟通,肯定会用双方都懂的英文来交流一样。
注:有一个专门的协议 ,称为Session Description Protocol (SDP),可用于描述上述这类信息,在webrtc中,参与视频通讯的双方必须先交换SDP信息,这样双方才能知根知底,而交换SDP的过程,也称为"媒体协商"。
2、彼此要了解对方的网络情况,这样才有可能找到一条相互通讯的链路
类似的道理,在复杂的网络环境中,要建立二个端的连接,得有一条双方都能访问的链路。

如上图,peerA端具体有公网ip以及网段的内网环境,而peerB没有公网,只有、198二个内网地址,从图中可知,它俩可以使用公用的192网段来通讯。webrtc通讯过程中,这些网络相关的信息,也得相互交换,找出共同的交集,这个过程也称为“网络协商”。
顺着这个思路再琢磨一下,刚开始前,这2个端还没建立连接,既然连都没连上,又如何交换“媒体信息”、“网络信息”?
这时候就该所谓的信令服务器signal server出场了:

如上图,2个浏览器端的上层,可以抽象出一层信令服务器(可以是1台或多台,看实际应用的情况,如果2端的浏览器都能访问某个公共的网络环境,比如公网,可以让它们都连到这台公用的信令服务器上;如果没有公共的网络环境,可以在2端各搭一组服务器,即signal serverA、signal serverB,但是这二组信令服务器之间要能互通),借助信令服务器,就可以实现上面提到的SDP信息及网络信息交换。

交换SDP的过程,大致如上图:
1、Amy(1个假想的人名),把自身的SDP信息,通过setLocalDescription方法保存起来,然后通过offer方法,发给信令服务器。
2、信息服务器把Amy的SDP向前传递到另1端的Bob(另1个假想的人名),Bob会先调用setRemoteDescripition把Amy的SDP保存下来。
3、然后Bob调用setLocalDescription方法保存自己的SDP,然后再通过answer方法,把自己的SDP通过信令服务器发给Amy
4、Amy收到Bob的SDP后,调用setRemoteDescription保存起来,这样双方就完成了SDP交换,然后找出其中的交集,如果能达成一致,就可以建立p2p连接,开始通讯了。
但是现实往往是残酷的,在中国的网络环境中,据一些统计数据显示,至少1半的网络是无法直接穿透打通的(我个人认为根本原因是:IP4地址资源在互联网发展早期绝大多数都被国外占用了,轮到中国这些发展中国家使用时IP地址严重不足,所以大多数电脑都不具备公网ip,只能通过路由器、交换机做NAT转换,而相当一部分NAT是对称型的,基本上没法空透),这种情况下只能借助上一节讲到的turn服务器中转。
另外,在视频对话框中,通常会有房间(或群)的概念,用于做一些业务上的隔离,这部分逻辑也是在signal server中实现的,综合考虑peer端、信令服务器、stun/turn服务器后,整个1对1实时视频通讯的时序图如下:

主要过程如下:
1、双方先调用getUserMedia打开本机摄像头
2、向信令服务器发送加入房间apply_join请求
3、信令服务器通知本人加入成功(joined),同时向其它人广播加入消息(other_joined)
4、二端开始创建peerConnection连接
5、peerB端创建offer,同时将SDP保存到本机(setLocalDescription),并通过信令服务器传递到peerA
6、peerB在setLocalDescription后,会异步触发“候选网络链路”收集,大致是通过Stun确定自己所有的NAT映射出口,如果Stun返回NAT是“对称型”的,基本上就没法穿透了,会再通过Turn拿到中继reply地址,并通过信令服务器,将网络候选链路信息发到peerA(即:开始网络协商)
7、peerA收到的peerB的SDP后,开始回应(createAnswer),仍然通过信令服务器,将SDP发送到peerB
8、同时peerA也会开始网络候选链路的收集,并将自己的网络信息,通过信令服务器,发到peerB(即:网络协商)
这样peerA,peerB就相互交换了媒体信息及网络信息,如果能达到一致(即:找到交集),就可以开始通讯了
基于以上原理,做了一个demo示例程序,见:https://github.com/yjmyzz/webrtc-samples

参考资料:
https://rtcdeveloper.com/t/topic/13742
https://www.html5rocks.com/en/tutorials/webrtc/basics/
https://hpbn.co/webrtc/#standards-and-development-of-webrtc
https://blog.csdn.net/momo0853/article/details/85157775
https://developer.mozilla.org/en-US/docs/Web/API/WebRTC_API/Connectivity
https://developer.mozilla.org/en-US/docs/Web/API/RTCPeerConnection/setLocalDescription
https://www.cnblogs.com/lingyunhu/category/626157.html
webrtc笔记(2): 1对1实时视频/语音通讯原理概述的更多相关文章
- webrtc笔记(3): 多人视频通讯常用架构Mesh/MCU/SFU
问题:为什么要搞这么多架构? webrtc虽然是一项主要使用p2p的实时通讯技术,本应该是无中心化节点的,但是在一些大型多人通讯场景,如果都使用端对端直连,端上会遇到很带宽和性能的问题,所以就有了下图 ...
- 并发编程学习笔记(6)----公平锁和ReentrantReadWriteLock使用及原理
(一)公平锁 1.什么是公平锁? 公平锁指的是在某个线程释放锁之后,等待的线程获取锁的策略是以请求获取锁的时间为标准的,即使先请求获取锁的线程先拿到锁. 2.在java中的实现? 在java的并发包中 ...
- 【React Native】集成声网Agora语音通讯
前言: 公司的产品是一款基于社交的内容聊天软件,需要集成语音通讯功能,在写iOS原生项目时,用到的就是Agora SDK,现在写React Native也直接采用了Agora的库. 集成iOS.And ...
- 【第1篇】人工智能(AI)语音测试原理和实践---宣传
前言 本文主要介绍作者关于人工智能(AI)语音测试的各方面知识点和实战技术. 本书共分为9章,第1.2章详细介绍人工智能(AI)语音测试各种知识点和人工智能(AI)语音交互原理:第3.4章介绍人工智 ...
- webrtc笔记(1): 基于coturn项目的stun/turn服务器搭建
webrtc是google推出的基于浏览器的实时语音-视频通讯架构.其典型的应用场景为:浏览器之间端到端(p2p)实时视频对话,但由于网络环境的复杂性(比如:路由器/交换机/防火墙等),浏览器与浏览器 ...
- WebRTC笔记(一)
来源<WebRTC权威指南> 1 WebRTC特点 对等连接(Peer Connection):浏览器与浏览器(万维网上的任意两个通信终端)之间的连接(P2P) 信令服务器:在浏览器和对等 ...
- webrtc笔记(4): kurento 部署
kurento是一个开源的webrtc mcu服务器,按官方的文档,建议在ubtntu上安装,过程如下: 注:建议先切换到root身份,如果不是root身份登录的,下列命令,请自行加上sudo . 另 ...
- webrtc笔记(5): 基于kurento media server的多人视频聊天示例
这是kurento tutorial中的一个例子(groupCall),用于多人音视频通话,效果如下: 登录界面: 聊天界面: 运行方法: 1.本地用docker把kurento server跑起来 ...
- Android IOS WebRTC 音视频开发总结(十三)-- ice原理
以前在做一个视频监控项目的时候,刚开始客户没提到要支持P2P,因为服务端是我们自己写的,为了便于处理一些逻辑,全部采用转发的方式,后来客户要求支持P2P,没办法了,后来自己部署了一个STUN服务器(不 ...
随机推荐
- Python程序中的进程操作-进程同步(multiprocess.Lock)
目录 一.多进程抢占输出资源 二.使用锁维护执行顺序 三.多进程同时抢购余票 四.使用锁来保证数据安全 通过刚刚的学习,我们千方百计实现了程序的异步,让多个任务可以同时在几个进程中并发处理,他们之间的 ...
- Batchnorm原理详解
Batchnorm原理详解 前言:Batchnorm是深度网络中经常用到的加速神经网络训练,加速收敛速度及稳定性的算法,可以说是目前深度网络必不可少的一部分. 本文旨在用通俗易懂的语言,对深度学习的常 ...
- 用keras构建自己的网络层 TensorFlow2.0教程
1.构建一个简单的网络层 from __future__ import absolute_import, division, print_function import tensorflow as t ...
- 雅礼集训2019 D7T2 Subsequence
雅礼集训2019 D7T2 Subsequence 直接贴题解: 平衡树代码: #include<bits/stdc++.h> #define ll long long #define N ...
- H5混合应用之X5内核
一.X5内核介绍 X5内核是腾讯公司基于优秀开源 webkit 深度优化的浏览器渲染引擎,并且在2014年正式宣布开放给app开发者,所以现在可以在很多app上看到都是使用的X5内核实现Hybrid混 ...
- Web前端基础(6):CSS(三)
1. 定位 定位有三种:相对定位.绝对定位.固定定位 1.1 相对定位 现象和使用: 1.如果对当前元素仅仅设置了相对定位,那么与标准流的盒子什么区别. 2.设置相对定位之后,我们才可以使用四个方向的 ...
- vi 上下左右变ABCD乱码解决方法
CentOS echo "set nocompatible" >> ~/.vimrc source ~/.vimrc debian sudo apt-get remov ...
- 图片在DIV里边水平垂直居中
图片在一个DIV中要垂直水平居中,首先定义一个DIV .wrap{ width: 600px; height: 400px; border: 1px #000 solid; } 插入图片 <di ...
- Linux下设置root密码
如下面的代码所示: sudo passwd [sudo] geeksong 的密码: 输入新的 UNIX 密码: 重新输入新的 UNIX 密码: passwd:已成功更新密码 更性的unix密码就是r ...
- 【微信小程序】App.js生命周期
1.小程序的生命周期-App.js App() 必须在 app.js 中注册,且不能注册多个.所以App()方法在一个小程序中有且仅有一个. App({ onLaunch: function () { ...