龙空技术网

WebRTC成为HTML5标准!是时候学习了!

高级前端进阶 1975

前言:

目前大家对“audiocontexthtml5”大体比较看重,同学们都需要学习一些“audiocontexthtml5”的相关资讯。那么小编同时在网络上搜集了一些对于“audiocontexthtml5””的相关文章,希望小伙伴们能喜欢,各位老铁们一起来了解一下吧!

家好,很高兴又见面了,我是"高级前端‬进阶‬",由我带着大家一起关注前端前沿、深入前端底层技术,大家一起进步,也欢迎大家关注、点赞、收藏、转发!

高级前端‬进阶

今天带着大家一起了解下WebRTC,话不多说,直接进入正题。

1.什么是 WebRTC?

WebRTC 是一组 JavaScript API,可以在两个浏览器之间建立点对点连接, 实现音频和视频等数据的传输,可以用它创建有语音/视频通话功能的应用程序。

WebRTC 的特别之处是,一旦建立了连接,就可以直接在浏览器之间实时传输数据,不需要借助服务器,因此降低了延迟,所以用户都喜欢用 webRTC 直接传输音视频。

在WebRTC诞生之前,开发实时音视频应用的成本是非常高,需要考虑的技术问题很多,如音视频的编解码,数据传输延时、丢包、网络抖动、回音处理和消除等,如果要兼容浏览器端的实时音视频通信,还需要额外安装插件。可喜的是,本文的主角WebRTC在2021年1月被W3C和IETF发布为正式标准,而且得到了大多数主流浏览器的支持。

2.WebRTC 与 WebSockets的区别

在讨论 WebRTC 的工作原理之前,先看看 WebRTC 和 WebSockets 的对比,因为很多人都会觉得“听着跟 WebSockets 一样,用 WebSockets 就好了,为什么需要 WebRTC ”?

使用 websockets 也可以建立点对点连接,实时传输数据,但这种连接是在客户端和服务器之间。因此,如果我向某一对等点发送消息,这个消息会先传送到服务器,然后服务器再把这个消息发送给另一个对等点。通常来说,这种传输非常快,如果大家发送的是聊天信息或某些通知,即使有一些延迟也注意不到。

但如果我们用 websockets 传输音视频情况就不一样了。用 websockets 传输音视频时,即使有非常轻微的延迟也会非常明显,还会导致很多其他问题。当视频数据到达服务器并返回对等点时,用户会感觉到明显的延迟。

而这就是 webRTC 的优势所在,在两个浏览器之间建立连接并直接交换数据,消除了服务器可能导致的延迟,WebRTC 还使用了用户数据报协议(UDP),这些都有利于数据的快速传输。

通常WebRTC会与WebSocket配合使用,WebSocket的作用主要是用来交换客户端的SDP与网络信息,Websocket传输的内容与真正通信数据无关,只是协助WebRTC建立连接。

3.用 webRTC 传输数据这么快,为什么还需要 websockets?

webRTC 有一定的局限性,所以通常会同时使用 webRTC 和 websockets。

首先,webRTC 使用 UDP,但是用 UDP 传输重要数据会有点不太可靠。UDP 的优势在于传输数据非常快,劣势在于它不检查数据是否被成功接收。所以,可以用 UDP 来传输视频,就算传输过程中丢失了几帧,也没啥大问题;但如果是发送文件,丢失几个字节的数据就会导致整个文件的损坏。

另外,WebRTC 没有内置信令,所以只用 WebRTC 没法建立点对点的连接,但一旦建立了连接,WebRTC 就可以处理所有问题,至于如何传输初始数据来连接两个对等点则由我们决定。

4.两个客户端之间传送什么,如何发送?

首先,信息的发送通常是通过一个叫做信令的过程。由于两个对等点不了解对方的情况,我们通常会使用 WebSockets 或其他第三方信令服务将两个对等点引入同一个频道。

当把两个对等点引入同一个频道或房间时,他们就可以通过连接细节发出信号。这些连接细节以会话描述协议(SDP)和 ICE (Interactive Connectivity Establishment,交互式连接创建)候选人的形式出现。

SDP ——会话描述协议(SDP),是一个包含会话连接(如编解码器、地址、媒体类型、音频和视频等)信息的对象。两个对等点会交换 SDP 来了解如何实现连接。一个是 SDP Offer 形式,另一个是 SDP Answer 形式。

ICE 候选人——ICE 候选人是公共 IP 地址和端口,可以做接收数据的地址。通常来说,每个用户会有多个 ICE 候选人,这些 ICE 候选人是向 STUN 服务器发出一系列请求来收集的。

5.事件发生顺序

首先,两个对等点会使用某种信令方法来传输 SDP。一旦两个 SDP 传输完成,对等点就连接成功,但这时还不能传输数据。

要在两个对等点之间交换数据,我们要先传输数据。问题是,现在大多数设备都位于防火墙和 NAT 设备后面,因此,为了协调公共 IP 地址的发现,我们使用 ICE (Interactive Connectivity Establishment,交互式连接创建)方法。

一旦后台传输了 SDP 提议,每个对等点就会向 STUN 服务器发出一系列请求,该服务器会生成一个 ICE 候选人列表。STUN 服务器的成本很低,并且容易维护,有非常多的免费服务,所以大家可以设置一个。

一旦对等点 1 从 STUN 服务器获得这些 ICE 候选人,就会把这些候选人发送给对等点 2,让网络决定要使用的最佳候选人。对等点 2 会进行同样的操作,请求 ICE 候选人,然后将其发送给等点 1。

当这些候选人传输成功并发现一条最佳路径时,数据就可以开始在两个对等点之间流动。

5.WebRTC API调用5.1 RTCPeerConnection

RTCPeerConnection用于点对点之间建立连接以传输音视频数据流,这是RTCPeerConnection的任务,为此需要借助一个信令服务器(signaling server)来进行,信令包括3种类型的信息:

Session control messages: 初始化和关闭通信,及报告错误;Network configuration: 双方的IP地址和端口号(局域网内部IP地址需转换为外部的IP地址);Media capabilities: 双方的浏览器支持使用何种编码以及多高的视频分辨率。

var PeerConnection = window.RTCPeerConnection || window.mozRTCPeerConnection || window.webkitRTCPeerConnection;navigator.getUserMedia = navigator.getUserMedia ? "getUserMedia" :    navigator.mozGetUserMedia ? "mozGetUserMedia" :    navigator.webkitGetUserMedia ? "webkitGetUserMedia" : "getUserMedia";var v = document.createElement("video");// 创建信令(createOffer)var pc = new PeerConnection();pc.addStream(video);pc.createOffer(function(desc) {    pc.setLocalDescription(desc, function() {        // send the offer to a server that can negotiate with a remote client    });})// 创建回复(createAnswer)var pc = new PeerConnection();pc.setRemoteDescription(new RTCSessionDescription(offer), function() {    pc.createAnswer(function(answer) {        pc.setLocalDescription(answer, function() {            // send the answer to the remote connection        });    });})
5.2 RTCDataChannel

RTCDataChannel 接口代表在两者之间建立了一个双向数据通道的连接,可以用

RTCPeerConnection.createDataChannel() 或者在现有的 RTCPeerConnection 上用 RTCDataChannelEvent 类型的 datachannel 事件接收,创建出 RTCDataChannel 类型的对象。

var pc = new RTCPeerConnection();// 获取RTCPeerConnection对象var dc = pc.createDataChannel("my channel");// 创建DataChannel对象dc.onmessage = function (event) {  console.log("received: " + event.data);};dc.onopen = function () {  console.log("datachannel open");};dc.onclose = function () {  console.log("datachannel close");};
5.3 访问用户摄像头及麦克风getUserMedia

WebRTC支持直接传输音频流和视频流():

const pc = new RTCPeerConnection() ;// 获取RTCPeerConnectionnavigator.getUserMedia({ video: true }, stream => {   // 添加视频流到会话中  stream.getTracks().forEach(track => pc.addTrack(track, stream))   // 在网页中预览自己摄像头拍摄到的内容,其中$localVideo表示一个Video对象  $localVideo.srcObject = stream; }) 

navigator.getUserMedia()还可以和web Audio API相结合,用来处理音频效果:

var range = document.querySelector('input');window.AudioContext = window.AudioContext || window.webkitAudioContext;var audioCtx = new AudioContext();navigator.getUserMedia({    audio: true}, function(stream) {    // 创建音频流    var source = audioCtx.createMediaStreamSource(stream);    // 双二阶滤波器    var biquadFilter = audioCtx.createBiquadFilter();    biquadFilter.type = 'lowshelf';    biquadFilter.frequenc.value = 1000;    biquadFilter.gain.value = range.value;    source.connect(biquadFilter);    biquadFilter.connect(audioCtx.destination);}, function(error) {    console.log(error);});

其实,WebRTC并不只是用来做视频、音频,它还可以用来传输任意数据,包括文件,文本等。上面代码示例可以看到,WebRTC规定了dataChannel这个双工数据通道,而这个网站就是通过WebRTC进行文件分享。

const pc = new RTCPeerConnection() const dataChannel = pc.createDataChannel('chat') // 监听datachannel事件pc.addEventListener('datachannel', event => {   // 接收通信方发送过来的数据  event.channel.addEventListener('message', event => {     console.log('message', event.message)   }) }) dataChannel.addEventListener('open', () => {   // 发送数据,可发送任意数据   dataChannel.send('Hi!') }) dataChannel.addEventListener('close', event => { }) 

参考资料

标签: #audiocontexthtml5