赞
踩
WebRTC 是由一家名为 Gobal IP Solutions,简称 GIPS 的瑞典公司开发的。Google 在 2011 年收购了 GIPS,并将其源代码开源。然后又与 IETF 和 W3C 的相关标准机构合作,以确保行业达成共识。其中:
WebRTC(Web Real-Time Communication)是一项开源的技术,旨在实现实时音视频以及数据通信,而无需安装任何插件或扩展。WebRTC 允许用户之间通过 P2P(Peer-to-Peer)模式进行实时通信,减轻服务器的负担并提高通信效率。
所以,我们可以在不需要任何第三方插件的情况下,实现一个浏览器到浏览器的点对点(P2P)连接,从而进行音视频实时通信。当然,WebRTC 提供了一些 API 供我们使用,在实时音视频通信的过程中,我们主要用到以下三个:
不过,虽然浏览器给我们解决了大部分音视频处理问题,但是从浏览器请求音频和视频时,我们还是需要特别注意流的大小和质量。因为即便硬件能够捕获高清质量流,CPU 和带宽也不一定可以跟上,这也是我们在建立多个对等连接时,不得不考虑的问题。
WebRTC P2P 由以下几个主要组件组成:
WebRTC 不包含信令协议,因此需要开发者根据需求自定义信令过程。
信令主要用于协调双方建立 P2P 连接、交换音视频编码信息、网络地址等。
在 WebRTC 中,信令主要负责以下几个方面:
SDP 是一种文本格式的协议,用于描述多媒体会话的属性,例如音视频编码格式、分辨率、帧率等。在 WebRTC 中,SDP 主要用于在通信双方之间协商通信参数。
在实际网络环境中,大多数用户都位于 NAT(网络地址转换)环境之下。NAT 会导致用户之间无法直接建立 P2P 连接。为了解决这个问题,WebRTC 使用了 ICE 协议,结合 STUN(Session Traversal Utilities for NAT)和 TURN(Traversal Using Relays around NAT)服务器进行 NAT 穿透。
ICE 的工作原理如下:
- 首先,通信双方收集本地网络地址(包括私有地址和公共地址)以及通过 STUN 和 TURN 服务器获取的候选地址。
- 接下来,双方通过信令服务器交换这些候选地址。
- 通信双方使用这些候选地址进行连接测试,确定最佳的可用地址。
- 一旦找到可用的地址,通信双方就可以开始实时音视频通话。
信令服务器负责协调客户端之间的通信,主要包括交换 SDP 信息和 ICE 候选(NAT 穿越信息)。信令服务器可以使用 WebSocket、Socket.IO 等技术来实现。
在选择信令服务器时,开发者需要考虑以下几个方面:
由于 WebRTC 可以在不依赖插件或外部应用的情况下实现实时通信,因此在各种需要实时音视频通信和数据传输的场景中都可以发挥重要作用。
getUserMedia 主要就是用来获取设备的媒体流(即 MediaStream)。它可以接受一个约束对象 constraints 作为参数,用来指定需要获取到什么样的媒体流。
navigator.mediaDevices.getUserMedia
是新版的 API,旧版的是 navigator.getUserMedia
。为了避免兼容性问题,我们可以稍微处理一下(其实说到底,现在 WebRTC 的支持率还不算高,有需要的可以选择一些适配器,如 adapter.js
)。
- // 判断是否有 navigator.mediaDevices,没有赋成空对象
- if (navigator.mediaDevices === undefined) {
- navigator.mediaDevices = {};
- }
-
- // 继续判断是否有 navigator.mediaDevices.getUserMedia,没有就采用 navigator.getUserMedia
- if (navigator.mediaDevices.getUserMedia) {
- navigator.mediaDevices.getUserMedia = function(prams) {
- let getUserMedia = navigator.webkitGetUserMedia || navigator.mozGetUserMedia;
- // 兼容获取
- if (!getUserMedia) {
- return Promise.reject(new Error('getUserMedia is not implemented in this browser'));
- }
- return new Promise(function(resolve, reject) {
- getUserMedia.call(navigator, prams, resolve, reject);
- });
- };
- }
- navigator.mediaDevices.getUserMedia(constraints)
- .then(stream => {
- let video = document.querySelector('#Rtc');
- if ('srcObject' in video) { // 判断是否支持 srcObject 属性
- video.srcObject = stream;
- } else {
- video.src = window.URL.createObjectURL(stream);
- }
- video.onloadedmetadata = function(e) {
- video.play();
- };
- })
- .catch((err) => { // 捕获错误
- console.error(err.name + ': ' + err.message);
- });
- navigator.mediaDevices.getUserMedia({ audio: false, video: true });
- // 只需要视频流,不要音频
-
-
- // 获取指定宽高,这里需要注意:在改变视频流的宽高时,
- // 如果宽高比和采集到的不一样,会直接截掉某部分
- {
- audio: false,
- video: { width: 1280, height: 720 }
- }
-
- // 设定理想值、最大值、最小值
- {
- audio: true,
- video: {
- width: { min: 1024, ideal: 1280, max: 1920 },
- height: { min: 776, ideal: 720, max: 1080 }
- }
- }
-
- // 对于移动设备来说,还可以指定获取前摄像头,或者后置摄像头
- { audio: true, video: { facingMode: "user" } } // 前置
- { audio: true, video: { facingMode: { exact: "environment" } } } // 后置
- // 也可以指定设备 id,
- // 通过 navigator.mediaDevices.enumerateDevices() 可以获取到支持的设备
- { video: { deviceId: myCameraDeviceId } }
-
- // 设置视频源为屏幕,但是目前只有火狐支持了这个属性
- { audio: true, video: {mediaSource: 'screen'} }
-
RTCPeerConnection 接口代表一个由本地计算机到远端的 WebRTC 连接。该接口提供了创建,保持,监控,关闭连接的方法的实现。
RTCPeerConnection 作为创建点对点连接的 API,是我们实现音视频实时通信的关键。在点对点通信的过程中,需要交换一系列信息,通常这一过程叫做 — 信令(signaling)。
在信令阶段需要完成的任务:
* 为每个连接端创建一个 RTCPeerConnection,并添加本地媒体流。
* 获取并交换本地和远程描述:SDP 格式的本地媒体元数据。
* 获取并交换网络信息:潜在的连接端点称为 ICE 候选者。
我们虽然把 WebRTC 称之为点对点的连接,但并不代表在实现过程中不需要服务器的参与。相反,在点对点的信道建立起来之前,二者之间是没有办法通信的。这也就意味着,在信令阶段,我们需要一个通信服务来帮助我们建立起这个连接。WebRTC 本身没有指定某一个信令服务,所以,我们可以但不限于使用 XMPP、XHR、Socket 等来做信令交换所需的服务。
为每个连接端创建一个 RTCPeerConnection,并添加本地媒体流。事实上,如果是一般直播模式,则只需要播放端添加本地流进行输出,其他参与者只需要接受流进行观看即可。
- // 因为各浏览器差异,RTCPeerConnection 一样需要加上前缀
- let PeerConnection = window.RTCPeerConnection ||
- window.mozRTCPeerConnection ||
- window.webkitRTCPeerConnection;
- let peer = new PeerConnection(iceServers);
-
-
- // 参数 — iceServers
- // 参数配置了两个 url,分别是 STUN 和 TURN,这便是 WebRTC 实现点对点通信的关键,也是一般 P2P 连接都需要解决的问题:NAT穿越。
- {
- iceServers: [
- {
- url: "stun:stun.l.google.com:19302" // 谷歌的公共服务
- },
- {
- url: "turn:***",
- username: ***, // 用户名
- credential: *** // 密码
- }
- ]
- }
一般情况下会采用 ICE 协议框架进行 NAT 穿越,ICE 的全称为 Interactive Connectivity Establishment,即交互式连接建立。它使用 STUN 协议以及 TURN 协议来进行穿越。
关于 NAT 穿越的更多信息可以参考 ICE协议下NAT穿越的实现(STUN&TURN)、
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。