1.什么是 WebRTC?WebRTC 是一组 JavaScript API,可以在两个浏览器之间建立点对点连接, 实现音频和视频等数据的传输,可以用它创建有语音/视频通话功能的应用程序。 WebRTC 的特别之处是,一旦建立了连接,就可以直接在浏览器之间实时传输数据,不需要借助服务器,因此降低了延迟,所以用户都喜欢用 webRTC 直接传输音视频。 在WebRTC诞生之前,开发实时音视频应用的成本是非常高,需要考虑的技术问题很多,如音视频的编解码,数据传输延时、丢包、网络抖动、回音处理和消除等,如果要兼容浏览器端的实时音视频通信,还需要额外安装插件。可喜的是,本文的主角WebRTC在2021年1月被W3C和IETF发布为正式标准,而且得到了大多数主流浏览器的支持。 ![]() CanIUse中WebRTC的浏览器支持情况 2.WebRTC 与 WebSockets的区别在讨论 WebRTC 的工作原理之前,先看看 WebRTC 和 WebSockets 的对比,因为很多人都会觉得“听着跟 WebSockets 一样,用 WebSockets 就好了,为什么需要 WebRTC ”? ![]() 使用 websockets 也可以建立点对点连接,实时传输数据,但这种连接是在客户端和服务器之间。因此,如果我向某一对等点发送消息,这个消息会先传送到服务器,然后服务器再把这个消息发送给另一个对等点。通常来说,这种传输非常快,如果大家发送的是聊天信息或某些通知,即使有一些延迟也注意不到。 但如果我们用 websockets 传输音视频情况就不一样了。用 websockets 传输音视频时,即使有非常轻微的延迟也会非常明显,还会导致很多其他问题。当视频数据到达服务器并返回对等点时,用户会感觉到明显的延迟。 而这就是 webRTC 的优势所在,在两个浏览器之间建立连接并直接交换数据,消除了服务器可能导致的延迟,WebRTC 还使用了用户数据报协议(UDP),这些都有利于数据的快速传输。
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 RTCPeerConnectionRTCPeerConnection用于点对点之间建立连接以传输音视频数据流,这是RTCPeerConnection的任务,为此需要借助一个信令服务器(signaling server)来进行,信令包括3种类型的信息:
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 RTCDataChannelRTCDataChannel 接口代表在两者之间建立了一个双向数据通道的连接,可以用
5.3 访问用户摄像头及麦克风getUserMediaWebRTC支持直接传输音频流和视频流(https:///): 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相结合,用来处理音频效果:
其实,WebRTC并不只是用来做视频、音频,它还可以用来传输任意数据,包括文件,文本等。上面代码示例可以看到,WebRTC规定了dataChannel这个双工数据通道,而https:///这个网站就是通过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 => { }) 参考资料https:///agora-io/how-does-webrtc-work-996748603141 https://www./cn/community/blog/24640 https://www./guiqulaixi-2ciw1/ltzgfd/xqgx3h9zdwxxszd9 https://developer.mozilla.org/en-US/docs/Web/API/RTCDataChannel https:///?search=WebRTC https://www.jianshu.com/p/1022f559a805 https://zhuanlan.zhihu.com/p/421503695 https://github.com/nashaofu/webrtc-demo https://blog.csdn.net/xyphf/article/details/107297616 |
|