背景

webRTC是Google在2010年收购GIP公司之后获得的一项技术。如下图所示,它提供了音视频的采集、处理(降噪,回声消除等)、编解码、传输等技术。

webRTC的目标是实现无需安装任何插件就可以通过浏览器进行P2P的实时音视频通话及文件传输,来看看Google的demo,是不是很酷?本文将带你分析webRTC的原理,并逐步编写一个简单的demo。

原理

如图,浏览器之间媒体流的传输是P2P的,但是这并不意味着webRTC不需要服务器支持。建立P2P视频连接需要的信息,如用来初始化通信的session信息,双方的ip、端口,视频分辨率,编解码格式等等,还是需要通过服务器来传输的。webRTC没有规定这些信息传输的机制,XHR、webSocket、Socket.io等都是可以的,因为Socket.io自带了房间的概念,便于双向视频的撮合,所以我在demo里选择了Socket.io。

当然,连接建立的过程不会这么简单。首先,提到P2P就绕不开NAT(Network Address Translation),webRTC使用ICE(Interactive Connectivity Establishment)框架,ICE是一种综合性的NAT穿越技术,它整合了STUN、TURN。当穿越网络时,ICE会先尝试STUN,查出自己位于哪种类型的NAT之后以及NAT为某一个本地端口所绑定的Internet端端口从而建立UDP连接,如果失败了ICE就会再尝试TCP(先尝试HTTP,再尝试HTTPS),如果仍然失败就使用中继的TURN服务器。

再来看看建立连接过程中的具体步骤:

  1. 调用getUserMedia获取本地的MediaStreams;
  2. 从STUN获取自己的外网IP及端口,通过Signaling Server向对方发送Offer(SDP协议),并收到Answer;
  3. 同时webRTC会生成一些包含自己的内网、外网IP等信息的candidate,同样通过Signaling Server相互传输;
  4. 建立P2P连接,传输媒体信息。

API

  • getUserMedia: 获取本地视频、音频,可以传入constraints调整分辨率、帧率,返回一个promise;
  • RTCPeerConnection: 生成一个RTCPeerConnection实例,传输视频、音频流;
  • createOffer: 会话发起方生成SDP Offer,包含了本地媒体流信息;
  • setLocalDescription:在此方法被调用之前oncandidate事件不会被触发;
  • setRemoteDescription: 接收到offer或者answer之后调用;
  • addIceCandidate: 接收到icecandidate之后调用;

Steps

获取媒体流

var constraints = {audio: false,video: true
};navigator.mediaDevices.getUserMedia(constraints)
.then(gotStream)
.catch(function(e) {alert('getUserMedia() error: ' + e.name);
});function gotStream(stream) {localVideo.srcObeject = stream;localStream = stream;
}
复制代码

getUserMedia存在兼容性问题,需要在项目中引用webRTC官方给出的adapter.js。constraints还可以配置video的分辨率、帧率、对移动端还可以选择前后摄像头: var constraints = { video: { width: { min:640, ideal: 1280, max: 1920 }, height: { min: 480 ideal: 720, max: 1080 }, facingMode: 'user' // 前置摄像头 } };

定义RTCPeerConnection

var serverConfig = {'iceServers': [{'urls': 'stun:stun.l.google.com:19302'}]
};function createPeerConnection() {var pc = new RTCPeerConnection(serverConfig);pc.onicecandidate = function(e) {if (e.candidate) {pc.addIceCandidate(e.candidate);}};// 添加对方的媒体流pc.onaddstream = function(e) {remoteVideo.srcObeject = e.stream;remoteStream = stream;};
}
复制代码

由STUN、TURN配置生成对应的RTCPeerConnection实例,再定义相关的事件处理函数,如onicecandidate、onaddstream、onremovestream等。

创建连接

function start() {pc.addstream(localStream);if (isCaller) {pc.createOffer(function(sessionDescription) {pc.setLocalDescription(sessionDescription);send(sessionDescription);  // 根据不同的Signaling方式实现});if (receiveAnswer) {pc.setRemoteDescription(answer.sessionDescription);}} else {if (receiveOffer) {pc.setRemoteDescription(offer.sessionDescription);}pc.createAnswer(function(sessionDescription) {pc.setLocalDescription(sessionDescription);send(sessionDescription);});}
}
复制代码

必须先getUserMedia后才能生成sessionDescription,并且只有在setLocalDescription后onicecandidate事件才会触发。上面代码中的只是为了说明大致流程,实际项目中结合socket.io的事件更容易实现。

中断会话

function stop() {pc.stop();pc = null;
}
复制代码

关于socket.io有关的代码本文没有贴出,详情可参考socket.io的用法。

可行性

按照上面的步骤可以成功地搭建webRTC的小demo,但是能否将webRTC运用到实际项目中去呢?下面从浏览器兼容性和webRTC本身的性能两个方面去分析。

兼容性

  • IOS: 只有最新的ios11支持webRTC,且仅限safari浏览器,微信内置浏览器尚不支持getUserMedia,不支持DataChannel,视频编解码格式为H.264;

  • Android: 安卓4.4以上(不含4.4),经测试各大手机厂商自带浏览器均不支持getUserMedia,但微信内置浏览器可以正常运行,另外61版本以上的Chrome for Android也都支持;

  • PC: Chrome49以上,Firefox55以上,Edge支持,Safari只有11支持,IE不支持。

性能

诚然webRTC在回声消除,图像编解码等方面已经做得十分出色,但它在性能上的问题还是不可忽视的:

  • 由于需要进行视频编解码,所以CPU占用率非常高,尤其是在移动设备上;
  • 在移动设备上获取的视频分辨率有限,最高只能达到640 * 480;
  • 带宽有限时,音视频质量较差,延时明显;

综上所述,虽然webRTC具有不需安装插件或者客户端,开源免费,强大的网络穿透能力,出色的音视频处理技术等等优点,但由于兼容性及性能上的问题,要投入到生产中还需要时间,主要是IOS11的普及以及CPU占用率和延时的问题。

参考文章

  • WebRTC in the real world: STUN, TURN and signaling

  • How to Select a Signaling Protocol for Your Next WebRTC Project?

  • Getting Started with WebRTC

  • 使用WebRTC搭建前端视频聊天室——入门篇

转载于:https://juejin.im/post/5c866629f265da2d8d6a1466

webRTC——浏览器里的音视频通话 1相关推荐

  1. webRTC——浏览器里的音视频通话

    背景 webRTC是Google在2010年收购GIP公司之后获得的一项技术.如下图所示,它提供了音视频的采集.处理(降噪,回声消除等).编解码.传输等技术. webRTC的目标是实现无需安装任何插件 ...

  2. vue + node + webrtc 实现多人音视频通话

    最近在搞一个内网音视频通话的功能,最终确定前端要用webrtc去实现,网上关于webrtc的文章不是很多,想找一个demo也很难,最终在gitee上找到一个大佬写的,很符合目前需求,前端js后台是no ...

  3. WebRTC:并非解决音视频应用所有问题的银弹

    WebRTC1.0标准虽然已经定稿,但各个浏览器的实现都还不成熟,处于快速迭代中,网易云信CTO赵加雨针在接受LiveVideoStack采访时,针对实时通信技术演进.WebRTC国内外发展与趋势.以 ...

  4. Android之 集成音视频通话

    一,背景 1.1 最近接收一个即时通讯二开项目,即时通讯部分用的XMPP协议,音视频则是集成的国外的开源免费库jitsi-meet-sdk-2.4.0-4.aar,是基于WebRTC的开源框架.但客户 ...

  5. WebRTC:P2P音视频通话基础概述

    前言 本篇文章参考WebRTC基础知识详解_签约计划_IT酷盖_InfoQ写作社区,介绍了P2P音视频通信的场景下的一些基础知识,包括WebRTC的基本架构.协议栈,一对一通话基础,和一对一通话原理三 ...

  6. 如何使用 Javascript/node.js 在 WebRTC 中构建音视频通话APP?

    语音和视频通信的嵌入对于现在的互联网产品发展的重要性已经毋庸置疑,WebRTC 事实上是一种通用的技术框架标准,它可以在浏览器之间不需要中介的情况下,实现任意数据流交换.这使得 web 应用程序和移动 ...

  7. WebRTC 实现P2P音视频通话——搭建信令服务器

    WebRTC 实现P2P音视频通话--搭建信令服务器 文章目录 WebRTC 实现P2P音视频通话--搭建信令服务器 前言 一.安装NodeJS,npm 二.服务器端实现 1.引入库 2.代码实现 3 ...

  8. iOS下WebRTC音视频通话(一)

    在iOS下做IM功能时,难免都会涉及到音频通话和视频通话.QQ中的QQ电话和视频通话效果就非常好,但是如果你没有非常深厚的技术,也没有那么大的团队,很难做到QQ那么快速和稳定的通话效果. 但是利用We ...

  9. 5G时代必学的WebRTC音视频通话技术

    什么是WebRTC ◼ WebRTC(Web Real-Time Communication)是 Google于2010以6829万美 元从 Global IP Solutions 公司购买,并于20 ...

最新文章

  1. nagios监控linux nrpe安装
  2. python太难学了-为何编程那么难?新手该怎么学Python?
  3. 在tomcat中部署mule项目
  4. 如何把微信文章中的语音/音乐下载下来
  5. Oracle数据库,当DML操作时执行触发器记录日志
  6. azure db 设置时区_将数据迁移到Azure Cosmos DB
  7. Asp.net系列--基础篇(二)
  8. 如果软件也玩凡尔赛文学,将如何对话?
  9. 《达拉崩吧》扣哒世界版——在扣哒世界中学习编程
  10. 面试官如何对应聘者的素质与能力做出相对准确的判断
  11. (四)keycloak 自定义用户(SPI)开发
  12. 头条 上传图片大小_无锡抖音巨量运营培训南天值得选择——鹰手营子矿头条...
  13. React制作简易小名片
  14. Be Better:遇见更好的自己-2016年记
  15. 截止2017年5月19日小虎软考粉丝有798人
  16. 宇视科技android面试_浙江宇视科技有限公司面试经验
  17. WIN10下如何更改微信聊天记录的默认存储路径
  18. linux命令之partprobe
  19. ATCA基础入门学习总结
  20. MDK5 Kil5中STM32工程的建立过程

热门文章

  1. 第4章 Python 数字图像处理(DIP) - 频率域滤波7 - 二维DFT和IDFT的一些性质 - 傅里叶频谱和相角
  2. 第3章 Python 数字图像处理(DIP) - 灰度变换与空间滤波9 - 直方图处理 - 直方图匹配(规定化)灰度图像,彩色图像都适用
  3. 7-1 FireTruck 消防车 uva208
  4. Idea 设置Eclipse快捷键(常用)
  5. Linux实战教学笔记37:企业级Nginx Web服务优化实战(上)
  6. 1 uC/OS工程目录
  7. java程序 输入10个数字并求和
  8. android之隐式intent调用
  9. AJAX自学笔记01
  10. osx doc to html,macos – 在OSX上安装Git HTML帮助