WebRTC是什么?运用他能做什么?怎么完成一个 webRTC 的运用?

WebRTC 是一个开源项目,可在 Web 和本机运用程序中完成音频、视频和数据的实时通讯。

WebRTC 代表网络实时通讯。它是一个开源免费项目,用于凭借 API(运用程序编程接口)为移动运用程序和 Web 浏览器供给实时通讯。JavaScript APIHTML5 标签、底层通讯协议等由 W3C(万维网联盟)和 IETF(互联网工程使命组)共同界说,以便在未来的 Web 浏览器之间树立一个值得信赖的通讯通道。基本上,首要思维是界说 WebRTC API,它答应安全拜访设备上的输入外围设备(例如麦克风和网络摄像头),以对等办法与长途设备同享或沟通媒体数据、实时数据。

运用场景不仅仅是下面的这些:视频会议、实时视频谈天、与一切朋友同享咱们最喜欢的时刻都是 WebRTC 内部存在的一些示例。 你日常运用的一切小工具,如手机、笔记本电脑、智能电视和人工智能等,都衔接到互联网。凭借 WebRTC,一切这些设备都能够在一个通用平台上平稳、安全地彼此同享语音、视频和实时数据,这也就是 WebRTC 的愿景。WebRTC 是实时通讯的未来。

为什么选择 WebRTC?

WebRTC 受欢迎的原因有许多。其间一些原因如下:

  • WebRTC 是一种无插件的现代实时通讯技能。它不需求任何额定的插件或运用程序来进行音频、视频流和数据同享。它运用 Javascript、运用程序编程接口 (API) 和 HTML5 将通讯技能嵌入到浏览器中。Google HangoutsWhatsappFacebook MessengerZOOMZendesk 客户支撑、Skype for Web 等产品均与 WebRTC 集成。
  • 浏览器能够以点对点的办法直接与其他浏览器沟通实时媒体。
  • 比其他各种流媒体体系供给更高级别的安全性,且无需第三方软件。
  • 无需插件即可进行实时通讯。

WebRTC 在浏览器中怎么作业?

WebRTC 基本上是经过浏览器进行网络实时通讯。它答应浏览器之间进行通讯。WebRTC Web 运用程序被编程为 HTMLJavaScript 的混合体。用户还能够运用 CSS 来自界说通讯的外观。它经过标准化的 WebRTC APIWeb 浏览器作业并通讯。因而,WebRTC API 有必要供给一系列实用程序。其间一些像衔接管理(以点对点办法)、编码/解码功能洽谈、选择和操控、媒体操控、防火墙等。

WebRTC 的完成规模十分广,由于它是高度可定制的。WebRTC 的功能能够分为三个部分:

  1. MediaStream:第一步是取得用户想要同享的数据。在这种情况下,捕获用户想要的流(音频/视频)、树立的通讯模式。本地媒体流答应浏览器拜访流设备,例如摄像头、网络麦克风。它还答应浏览器捕获媒体。用户能够运用getUserMedia() 浏览器的功能来获取拜访权限。
  2. RTCPeerConnection:一旦用户决定了通讯流,下一步就是将其与长途服务的体系衔接。它答应咱们的浏览器直接与长途服务浏览器(对等点)沟通数据以进行语音和视频通话。它答应经过STUNTURN服务器在发送方和接纳方之间进行关联。
  3. RTCDataChannel:它答应浏览器双向点对点沟通数据。

WebRTC 三角形:

WebRTC是什么?运用他能做什么?怎么完成一个 webRTC 的运用?

  • WebRTC 包括供 Web 开发人员运用的三个不同的 API 层。
    • 第一层包括 Web 开发人员所需的一切 API,包括 RTCPeerConnectionRTCDataChannel 和媒体流目标及其功能。
    • 第二层是浏览器制造商的 API,比方 safiachromefirefoxedge 等等。
    • 第三个是 Overridable API。
  • 假如咱们从客户端-服务器端查看 WebRTC 架构,那么咱们会发现最常用的模型之一是受到 SIP(​​会话启动协议)梯形的启示。
  • 幻想一下咱们和咱们的朋友正在运转 WebRTC 运用程序。我想与咱们的朋友沟通。然后运用信令音讯,其作业是树立和结束通讯。
  • 这些音讯经过 HTTP 或 WebSocket 协议传输到 Web 服务器,Web 服务器能够根据需求修改、翻译或管理它们。
  • 至于数据途径,PeerConnection 答应媒体直接在浏览器之间活动,无需任何中间服务器。两个网络服务器能够运用标准信令协议进行通讯,而且在咱们和咱们的朋友之间树立通讯。

什么是信号传递?

WebRTC 运用 RTCPeerConnection 在浏览器之间传输流数据,但还需求一种机制来协调通讯和发送操控音讯,该进程称为信令。WebRTC 未指定信令办法和协议。

什么是 STUN 和 TURN?

WebRTC 规划为点对点作业,因而用户能够经过最直接的路由进行衔接。然而,WebRTC 的构建是为了应对实践世界的网络:客户端运用程序需求穿越NAT 网关和防火墙,而且点对点网络需求在直接衔接失利时进行回退。在此进程中,WebRTC API 运用 STUN 服务器获取计算机的 IP 地址,并运用 TURN 服务器作为中继服务器,以防点对点通讯失利。

WebRTC 安全吗?

一切 WebRTC 组件都有必要加密,而且其 JavaScript API 只能从安全来历(HTTPS 或本地主机)运用。信令机制不是由 WebRTC 标准界说的,因而您需求确保运用安全协议。

WebRTC 的局限性:

  • 有必要能够拜访快速的互联网衔接才能与 WebRTC 进行通讯。
  • 它不供给任何离线服务。
  • 它并非在一切浏览器中都可用。
  • 没有固定的服务为每个浏览器供给基础。它不断更新,一些软件可能比其他软件供给更复杂的服务,而且具有易于拜访和其他设施。

快速入门

WebRTC 有多个 JavaScript API。

  • getUserMedia():捕获音频和视频。
  • MediaRecorder:录制音频和视频。
  • RTCPeerConnection:在用户之间传输音频和视频。
  • RTCDataChannel:用户之间的流数据。

第一步:终端创建一个项目


❯ mkdir webrtc-web && cd webrtc-web/
❯ pwd
❯ /Users/oo7/Developer/webrtc-web
❯ ~/Developer/webrtc-web 

第二步:从网络摄像头流式传输视频

  • 从网络摄像头获取视频流。
  • 操作流播映。
  • 运用 CSS 和 SVG 来操作视频。

在作业目录中向 index.html 增加一个video 元素和一个script元素:

<!DOCTYPE html>
<html>
<head>
	<title>与WebRTC的实时通讯</title>
	<link rel="stylesheet" href="css/main.css" />
</head>
<body>
	<h1>与WebRTC的实时通讯</h1>
	<video src="" autoplay playsinline></video>
	<script src="./js/main.js"></script>
</body>
</html>

在 js 文件夹中的 main.js编写一下内容:

'use strict';
const mediaStreamConstraints = {
	video: true,
};
//将放置流的视频元素
const localVideo = document.querySelector("video");
//将在视频中播映本地流。
let localStream;
//经过将MediaStream增加到视频元素来处理
function gotLocalMediaStream(mediaStream) {
	localStream = mediaStream;
	localVideo.srcObject = mediaStream;
}
//经过将带有过错音讯的记录输出到操控台
function handleLocalMediaStreamError(error) {
	console.log("navigator.getUserMedia过错: ", error);
}
// 初始化媒体流
navigator.mediaDevices
	.getUserMedia(mediaStreamConstraints)
	.then(gotLocalMediaStream)
	.catch(handleLocalMediaStreamError);

打开浏览器输入服务地址:http://127.0.0.1:5500/work/ 虽然是静态文件但是也需求以服务的形式启动

WebRTC是什么?运用他能做什么?怎么完成一个 webRTC 的运用?

运作办法

调用getUserMedia()后,浏览器会恳求用户拜访其相机的权限(假如这是第一次恳求对当时源的相机拜访)。假如成功,则返回 mediaStream,媒体元素能够经过以下srcObject特点运用该流:


// 初始化媒体流
navigator.mediaDevices
	.getUserMedia(mediaStreamConstraints)
	.then(gotLocalMediaStream)
	.catch(handleLocalMediaStreamError);
function gotLocalMediaStream(mediaStream) { 
	localVideo.srcObject = mediaStream;
}

constraints参数答应您指定要获取的媒体。在此示例中,仅视频,由于默认情况下音频处于禁用状态:

const mediaStreamConstraints = {
	video: true,
};

假如咱们对视频如分辨率有要求,运用以下参数来做微调:

const hdConstraints = {
	video: {  
		width: {   
			min: 1280  
		},  
		height: {
		  min: 720  
		}
	}
}

MediaTrackConstraints标准列出了一切的约束类型,但并不是一切浏览器都支撑这些选项。 假如当时选择的相机不支撑所恳求的分辨率,getUserMedia()则会被回绝,OverconstrainedError而且不会提示用户授予拜访其相机的权限。

假如getUserMedia()履行成功,来自网络摄像头的视频流将被设置为视频元素的源:

function gotLocalMediaStream(mediaStream) {
	localVideo.srcObject = mediaStream;
}

ps:

  • video 元素需求增加 autoplay上的特点,假如没有它,咱们将只能看到一个边框,或者什么都看不到!

运用 RTCPeerConnection 流式传输视频

什么是 RTCPeerConnection?

RTCPeerConnection 是一个 API,用于进行 WebRTC 调用以流式传输视频和音频以及沟通数据。

咱们在同一页面上的两个 RTCPeerConnection 目标(称为对等体)之间树立衔接。

增加视频元素和操控按钮

index.html中,将单个视频元素替换为两个视频元素和三个

<video id="localVideo" autoplay playsinline></video>
<video id="remoteVideo" autoplay playsinline></video>
<div> 
	<button id="startButton">开端</button> 
	<button id="callButton">拨号</button> 
	<button id="hangupButton">挂断</button>
</div>

一个视频元素将显现来自 RTCPeerconnection 的流,getUserMedia()另一个视频元素将显现经过 RTCPeerconnection 流式传输的相同视频。(在实践场景的运用程序中,一个视频元素将显现本地流,另一个视频元素将显现长途流。不然自己跟自己视频那叫一个没意思)

增加适配器 adapter.js

咱们直接引用网络的就好了

<script src="https://webrtc.github.io/adapter/adapter-latest.js"></script>

dapter.js 用于使运用程序免受标准更改和前缀差异的影响。(实践情况中用于WebRTC完成的标准和协议十分稳定,而且只要几个前缀称号。)

改造 index.html, 现在应该如下所示:

<!DOCTYPE html>
<html>
<head>
	<title>与WebRTC的实时通讯</title>
	<link rel="stylesheet" href="css/main.css" />
</head>
<body>
	<h1>与WebRTC的实时通讯</h1>
<!-- <video src="" autoplay playsinline></video> -->
	<video id="localVideo" autoplay playsinline></video>
	<video id="remoteVideo" autoplay playsinline></video>
	<div>
		<button id="startButton">开端</button>
		<button id="callButton">拨号</button>
		<button id="hangupButton">挂断</button>
	</div>
<script src="./js/main.js"></script>
<script src="https://webrtc.github.io/adapter/adapter-latest.js"></script>
</body>
</html>

编写 RTCPeerConnection 代码

WebRTC是什么?运用他能做什么?怎么完成一个 webRTC 的运用?

WebRTC 运用 RTCPeerConnection API 树立衔接以在 WebRTC 客户端(称为对**等点)**之间传输视频。

在此示例中,两个 RTCPeerConnection 目标坐落同一页面上:pc1pc2。没有太多实践用途,但有助于演示 API 的作业原理。

在 WebRTC 对等点之间树立呼叫触及三个使命:

  • 为呼叫的每一端创建一个 RTCPeerConnection,并在每一端增加来自 的本地流getUserMedia()
  • 获取和同享网络信息:潜在的衔接端点称为 ICE 候选端点。
  • 获取并同享本地和长途描述:有关 SDP 格局的本地媒体的元数据

摄影并经过数据通道同享

  • 拍摄相片并运用 canvas 元素从中获取数据。
  • 与长途用户沟通图画数据。

咱们经过 RTCDataChannel API 使得同享整个文件成为可能:在此示例中,经过getUserMedia().

该过程的中心部分如下:

  1. 树立数据通道。请注意,在此过程中,您不会向对等衔接增加任何媒体流。
  2. 运用以下命令捕获用户的网络摄像头视频流getUserMedia()
var video = document.getElementById('video');
function grabWebCamVideo() {
  console.log('正在获取用户媒体 (video) ...');
  navigator.mediaDevices.getUserMedia({
    video: true
  })
  .then(gotStream)
  .catch(function(e) {
    alert('getUserMedia() error: '   e.name);
  });
}
  1. 当用户单击Snap按钮时,从视频流中获取快照(视频帧)并将其显现在元素中canvas
var photo = document.getElementById('photo');
var photoContext = photo.getContext('2d');
function snapPhoto() {
  photoContext.drawImage(video, 0, 0, photo.width, photo.height);
  show(photo, sendBtn);
}
  1. 当用户单击**“发送”**按钮时,将图画转换为字节并经过数据通道发送:
function sendPhoto() {
	//将数据通道音讯拆分为此字节长度的块。
  var CHUNK_LEN = 64000;
  var img = photoContext.getImageData(0, 0, photoContextW, photoContextH),
    len = img.data.byteLength,
    n = len / CHUNK_LEN | 0;
  console.log('共发送 '   len   ' byte(s)');
  dataChannel.send(len);
	//拆分相片并以大约64KB的数据块发送
  for (var i = 0; i < n; i  ) {
    var start = i * CHUNK_LEN,
      end = (i   1) * CHUNK_LEN;
    console.log(start   ' - '   (end - 1));
    dataChannel.send(img.data.subarray(start, end));
  }
	//发送提示(假如有)
  if (len % CHUNK_LEN) {
    console.log('last '   len % CHUNK_LEN   ' byte(s)');
    dataChannel.send(img.data.subarray(n * CHUNK_LEN));
  }
}
  1. 接纳端将数据通道音讯字节转换回图画并将图画显现给用户:
function receiveDataChromeFactory() {
  var buf, count;
  return function onmessage(event) {
    if (typeof event.data === 'string') {
      buf = window.buf = new Uint8ClampedArray(parseInt(event.data));
      count = 0;
      console.log('Expecting a total of '   buf.byteLength   ' bytes');
      return;
    }
    var data = new Uint8ClampedArray(event.data);
    buf.set(data, count);
    count  = data.byteLength;
    console.log('count: '   count);
    if (count === buf.byteLength) {
		//一切数据块都已接纳
      console.log('Done. Rendering photo.');
      renderPhoto(buf);
    }
  };
}
function renderPhoto(data) {
  var canvas = document.createElement('canvas');
  canvas.width = photoContextW;
  canvas.height = photoContextH;
  canvas.classList.add('incomingPhoto');
	// trail是保存传入图画的元素
  trail.insertBefore(canvas, trail.firstChild);
  var context = canvas.getContext('2d');
  var img = context.createImageData(photoContextW, photoContextH);
  img.data.set(data);
  context.putImageData(img, 0, 0);
}

以下是 index.html 文件的代码

<!DOCTYPE html>
<html>
<head>
  <title>与WebRTC的实时通讯</title>
  <link rel="stylesheet" href="/css/main.css" />
</head>
<body>
  <h1>与WebRTC的实时通讯</h1>
  <h2>
    <span>Room URL: </span><span id="url">...</span>
  </h2>
  <div id="videoCanvas">
    <video id="camera" autoplay></video>
    <canvas id="photo"></canvas>
  </div>
  <div id="buttons">
    <button id="snap">Snap</button><span> then </span><button id="send">Send</button>
    <span> or </span>
    <button id="snapAndSend">Snap &amp; Send</button>
  </div>
  <div id="incoming">
    <h2>Incoming photos</h2>
    <div id="trail"></div>
  </div>
  <script src="/socket.io/socket.io.js"></script>
  <script src="https://webrtc.github.io/adapter/adapter-latest.js"></script>
  <script src="js/main.js"></script>
</body>
</html>

总结

WebRTC 是实时通讯的未来。日常运用的一切小工具,如手机、笔记本电脑、智能电视和人工智能等,都衔接到互联网。凭借 WebRTC,一切这些设备都能够在一个通用平台上平稳、安全地彼此同享语音、视频和实时数据,这也就是 WebRTC 的愿景。

WebRTC 相关的 API 许多,假如想要构建好一个 webRTC 的运用程序需求参阅 webRTC 相关的资料.

参阅资料: