前言
WebRTC是一个开源项目,旨在使得浏览器能为实时通信(RTC)提供简单的JavaScript接口。说的简单明了一点就是让浏览器提供JS的即时通信接口。这个接口所创立的信道并不是像WebSocket一样,打通一个浏览器与WebSocket服务器之间的通信,而是通过一系列的信令,建立一个浏览器与浏览器之间(peer-to-peer)的信道,这个信道可以发送任何数据,而不需要经过服务器。并且WebRTC通过实现MediaStream,通过浏览器调用设备的摄像头、话筒,使得浏览器之间可以传递音频和视频
WebRTC使得实时通信变成一种标准功能,任何Web应用都无需借助第三方插件和专有软件,而是通过简单地JavaScript API即可完成。
在WebRTC中,有三个主要的知识点,理解了这三个知识点,也就理解了WebRTC的底层实现原理。这三个知识点分别是:
MediaStream:获取音频和视频流
RTCPeerConnection:音频和视频数据通信
RTCDataChannel:任意应用数据通信
MediaStream
html
<!DOCTYPE html>
<html>
<head>
<title>Realtime communication with WebRTC</title>
</head>
<body>
<h1>Realtime communication with WebRTC</h1>
<video autoplay playsinline></video>
<script src="js/main.js"></script>
</body>
</html>
main.js
const mediaStreamConstraints = {
video: true,
};
// Video element where stream will be placed.
const localVideo = document.querySelector('video');
// Local stream that will be reproduced on the video.
let localStream;
// Handles success by adding the MediaStream to the video element.
function gotLocalMediaStream(mediaStream) {
localStream = mediaStream;
localVideo.srcObject = mediaStream;
}
// Handles error by logging a message to the console with the error message.
function handleLocalMediaStreamError(error) {
console.log('navigator.getUserMedia error: ', error);
}
// Initializes media stream.
navigator.mediaDevices.getUserMedia(mediaStreamConstraints)
.then(gotLocalMediaStream).catch(handleLocalMediaStreamError);
上面这段代码,就是获取了本地的摄像头,拿到权限后把他添加到video中。
localStream放在了全局,为了可以在命令行中调试方便,可方便的查看输出,生产环境的代码不要这样写。
在JS中,我们通过getUserMedia函数来处理音频和视频,该函数接收三个参数,分别是音视频的约束,成功的回调以及失败的回调。
其中第一个参数约束,默认是关掉音频audio的,所以指定视频就将只打开视频。
也可像下面一样指定详细信息
const mediaStreamConstraints = {
video: {
width: {
min: 1280
},
height: {
min: 720
}
}
}
MediaTrackConstraints specification 列举出了所有的约束,虽然不是每个浏览器都支持全部这些选项。
在底层,浏览器通过音频和视频引擎对捕获的原始音频和视频流加以处理,除了对画质和音质增强之外,还得保证音频和视频的同步。
由于音频和视频是用来传输的,因此,发送方还要适应不断变化的带宽和客户端之间的网络延迟调整输出的比特率。
对于接收方来说,则必须实时解码音频和视频流,并适应网络抖动和时延。其工作原理如下图所示:

如上成功回调的stream对象中携带者一个或多个同步的Track,如果你同时在约束中设置了音频和视频为true,则在stream中会携带有音频Track和视频Track,每个Track在时间上是同步的。
stream的输出可以被发送到一或多个目的地:本地的音频或视频元素、后期处理的JavaScript代理,或者远程另一端。如下图所示:

网友评论