|
《WebRTC 探索:前端视角下的实时通信解析》(上)
苏璇
大转转FE
大转转FE 定期分享一些团队对前端的想法与沉淀 430篇内容
2024年08月30日 09:00
北京
引言实时通信技术正在迅速改变我们的沟通方式,WebRTC(Web Real-Time Communications)作为这场变革的核心,为开发者和用户带来了无限可能。《WebRTC探索之旅》系列将分三篇文章带你了解 WebRTC:第一篇《WebRTC探索:前端视角下的实时通信解析(上)》将介绍 WebRTC 的基础概念和核心功能。第二篇《WebRTC探索:前端视角下的实时通信解析(中)》将探讨会话流程和信令服务器的搭建。第三篇《WebRTC探索:前端视角下的实时通信解析(下)》通过实战Demo,展示如何构建音视频通话和即时通讯应用。让我们一起踏上这场探索之旅,从前端视角深入 WebRTC,开启实时通信的新篇章!1、什么是WebRTC?1.1 WebRTC介绍WebRTC(Web 实时通信)是一个可以用在视频聊天、音频聊天或 P2P 文件分享等 Web 应用中的 API。——摘自:MDN - WebRTCMDN 对 WebRTC 的定义我们可以拆分为以下三点:WebRTC 是网页即时通信(Web Real-Time Communication)的缩写;它提供了支持网页浏览器进行实时语音和视频对话的 API;允许浏览器之间直接建立连接,实现点对点的通信。乍一看,我们所熟悉的 WebSocket 好像和 WebRTC 是同一种技术,然而它们之间的差别就像短信和视频通话——虽然都是通信工具,但一个让你“见字如面”,另一个则是“身临其境”。WebRTC vs WebSocket为了更好地理解 WebRTC 的独特性,我们先来回顾一下 WebSocket 的主要特点:WebSocket 是一种基于单个 TCP 连接的全双工通信协议;它允许服务器主动向客户端推送数据;在 WebSocket API 中,浏览器和服务器只需完成一次握手,之后就能建立持久性的连接,并进行双向的数据传输。关键区别:通信类型:WebSocket 主要用于文本和二进制数据的实时交换,非常适合聊天应用、实时游戏等需要低延迟的数据传输场景。WebRTC 则专注于媒体流的实时传输,如视频和音频通话,具有更复杂的媒体处理能力。建立连接:WebSocket 连接是建立在 TCP 上的,全双工的、持久的连接。WebRTC 则是点对点的,利用 NAT 穿透 技术(NAT 指的是网络地址转换,Network Address Translation)直接在浏览器之间建立连接,支持多种实时通信场景。功能支持:WebSocket 不直接支持媒体流的传输和编解码功能,而 WebRTC 内置了对视频、音频流的编解码和传输功能,提供更高层次的实时通信能力。通过下图,我们可以更直观地比较 WebRTC 和 WebSocket 的区别:以上对比可以帮助我们更清晰地理解这两种技术的特点。WebRTC 和 WebSocket 各自有不同的优势,可以说WebRTC 目前是将前端技术和音视频嫁接起来最佳的媒介。1.2 WebRTC的浏览器兼容性WebRTC 在主流浏览器中的支持情况如下图所示,这些信息来自 caniuse.com 网站,提供了各个浏览器对 WebRTC 的兼容性概况:兼容性注意事项:移动端支持:大多数移动浏览器也支持 WebRTC。需要注意的是,在 iOS 设备上,Safari 浏览器的版本需大于 10.1。旧版浏览器:一些老旧的浏览器或 WebView 组件可能不支持 WebRTC,建议在发布应用前进行全面的兼容性测试。网络环境与隐私权限:不同浏览器对摄像头、麦克风等隐私权限的处理方式有所不同,用户授权和连接稳定性可能受此影响。通过查看上图中的兼容性数据,我们可以更好地评估 WebRTC 在不同平台上的表现,优化应用以适配各种浏览器环境。1.3 WebRTC适用场景在线教育:如新东方云教室、智慧树、猿辅导、网易云课堂,通过WebRTC实现实时互动教学。社交媒体:增强用户互动体验,如 Soul 和 陌陌 的视频聊天功能等。视频会议:如腾讯会议、钉钉,提供高质量的实时视频会议体验。直播平台:如抖音、快手,利用WebRTC技术进行低延迟的实时直播。物联网(IoT):提供了低延迟的音视频通信能力,可以用于物联网设备之间的实时视频监控,如小米智能家居、小天才等。1.4 WebRTC 的优缺点WebRTC 的出现标志着实时通信技术的一次重要革新。作为一种开源标准,WebRTC 使得浏览器能够直接进行音视频通信,无需额外插件或第三方软件。它结合了前端技术与实时多媒体通信,为开发者和用户提供了新的可能性。然而,尽管 WebRTC 拥有众多优点,它也面临一些挑战。下面我们来详细探讨 WebRTC 的主要优缺点:优点描述实时通信WebRTC 支持浏览器之间的实时音频、视频和数据通信,无需任何插件或第三方软件。高质量的音视频通信WebRTC 使用最先进的音频和视频编解码器,如 Opus 和 VP8/VP9/H.264,可以提供高质量的通信体验。端到端加密WebRTC 的所有通信都是端到端加密的,保护了用户的隐私和数据安全。P2P 连接WebRTC 支持直接的 P2P 连接,可以减少延迟和带宽消耗,提高通信效率。跨平台和跨浏览器WebRTC 是一个开源的标准,被大多数现代浏览器和平台支持。缺点描述复杂的信令过程WebRTC 本身并不包含信令协议,开发者需要自己实现信令过程,增加了开发的复杂性。(信令是指在WebRTC会话建立过程中,用于在通信双方之间交换必要的控制信息的机制)防火墙和 NAT 问题在某些网络环境下,建立 P2P 连接可能会受到防火墙和 NAT 的限制。隐私问题虽然 WebRTC 的通信是加密的,但仍有可能泄露用户的 IP 地址,可能会引发一些隐私问题。资源消耗实时音视频通信需要消耗大量的 CPU 和带宽资源,可能会影响设备的性能。2、web端基础常用相关APIWebRTC 提供了一些 API,用于实现 Web 端的音视频通信。作为 W3C 标准,它涉及到用户的隐私设备如摄像头和麦克风。接下来,我们将简要介绍这些常用的 WebRTC API。这些 API 为实现实时通信提供了强大的支持,每个 API 都各有其独特的用途。首先,我们来看看如何通过 WebRTC 访问用户的音视频设备。2.1 getUserMediagetUserMedia是什么?getUserMedia 是 WebRTC API 中用于访问用户音视频设备的接口,包括摄像头和麦克风。无论是通过 USB 连接的设备还是虚拟设备,都可以通过这个 API 进行访问。如何使用 getUserMedia?在简单场景下,直接调用 getUserMedia 的默认参数即可获取 PC 的默认摄像头和麦克风。然而,在处理复杂场景时,例如选择特定的设备,可以按以下步骤操作:列出所有可用的媒体设备:获取设备列表以便选择。选择所需的设备:从设备列表中选择适合的摄像头和麦克风。配置并传递设备信息:将所选设备的信息传递给浏览器 API 以进行设置。//1.列出所有可用的媒体设备navigator.mediaDevices.enumerateDevices().then(devices=>{devices.forEach(device=>{console.log(device.kind,device.label,device.deviceId);});//2.根据用户选择的deviceId请求媒体流constconstraints={audio:{deviceId:{exact:selectedAudioDeviceId}},video:{deviceId:{exact:selectedVideoDeviceId}}};//3.请求用户媒体流returnnavigator.mediaDevices.getUserMedia(constraints);}).then(stream=>{//将媒体流绑定到视频或音频元素上constvideoElement.srcObject=stream;}).catch(error=>{console.error('媒体设备访问失败:',error);});媒体约束 constraints在上述代码片段中,constraints 参数用于指定音视频设备和其属性。以下是几种常见配置及其应用场景:同时获取视频和音频输入constconstraints={audio:true,video:true}如果没有视频设备,调用时会报错。可以先使用 enumerateDevices 判断是否有视频输入源,再决定是否设置 video 为 false。指定设备constconstraints={audio:{deviceId:audioId},video:{deviceId:videoId}}指定分辨率根据网络带宽和设备能力设置分辨率。例如://高分辨率constconstraints={audio:true,video:{width:{min:320,ideal:1280,max:1920},height:{min:240,ideal:720,max:1080}}}//低分辨率constconstraints={audio:true,video:{width:720,height:480}}指定摄像头方向使用 facingMode 属性来选择前置或后置摄像头://前置constconstraints={audio:true,video:{facingMode:"user"}}//后置constconstraints={audio:true,video:{facingMode:{exact:"environment"}}}指定帧速率 frameRate帧速率影响视频的流畅度。可以根据网络条件调整帧速率:constconstraints={audio:true,video:{width:1920,height:1080,frameRate:{ideal:10,max:15}}}2.2 getDisplayMediagetDisplayMedia 是什么?getDisplayMedia API 用于在浏览器中实现屏幕分享功能。它允许用户选择并分享整个屏幕或特定应用窗口,适用于远程会议和在线演示等场景。如何使用 getDisplayMedia?调用 getDisplayMedia 获取屏幕分享的媒体流。此 API 返回一个 Promise,解析值为包含屏幕视频流的 MediaStream 对象。asyncfunctiongetShareMedia(){constconstraints={video:{width:1920,height:1080},audio:false};//停止之前的媒体流if(window.stream){window.stream.getTracks().forEach(track=>track.stop());}try{returnawaitnavigator.mediaDevices.getDisplayMedia(constraints);}catch(error){console.error('屏幕分享失败:',error);}}媒体约束 Constraints基本配置在屏幕分享中video属性不能设置为false。constconstraints={video:true};指定分辨率constconstraints={video:{width:1920,height:1080}};音频设置如果需要分享系统音频,可以将 audio 设置为 true。注意,并非所有浏览器都支持音频分享功能。constconstraints={audio:true,video:{width:1920,height:1080}};示例对比:有音频:无音频:当audio设置为false后,底部就少了开启系统音频的按钮。小提示:在获取新的媒体流之前,建议停止之前的媒体流,以避免设备使用提示,并确保应用逻辑清晰。if(window.stream){window.stream.getTracks().forEach(track=>track.stop());}2.3 RTCPeerConnectionRTCPeerConnection 是什么?RTCPeerConnection用于管理音视频连接。它帮助你建立和维护与其他用户的实时通信,处理媒体流、网络连接等问题。如何使用 RTCPeerConnection?创建 RTCPeerConnection 需要提供一个配置对象,通常包含用于网络穿透的服务器信息(如 STUN 服务器)。constconfiguration={iceServers:[{urls:'stun:stun.l.google.com:19302'}]};constpeerConnection=newRTCPeerConnection(configuration);主要功能:1. 创建连接请求createOffer(): 发起连接请求。createAnswer(): 响应连接请求。peerConnection.createOffer().then(offer=>peerConnection.setLocalDescription(offer)).then(()=>{//发送offer给对端});2. 设置描述信息setLocalDescription(description): 设置本地的连接信息。setRemoteDescription(description): 设置对端的连接信息。peerConnection.setRemoteDescription(newRTCSessionDescription(remoteOffer)).then(()=>peerConnection.createAnswer()).then(answer=>peerConnection.setLocalDescription(answer));3. 处理媒体流addTrack(track, stream): 添加音视频轨道到连接中。addIceCandidate(candidate): 添加网络候选地址。navigator.mediaDevices.getUserMedia({video:true,audio:true}).then(stream=>{stream.getTracks().forEach(track=>peerConnection.addTrack(track,stream));});peerConnection.addIceCandidate(newRTCIceCandidate(candidate));4. 事件处理onicecandidate: 当新的网络候选地址出现时触发。ontrack: 当接收到对端的媒体流时触发。oniceconnectionstatechange: 当连接状态变化时触发。peerConnection.onicecandidate=(event)=>{if(event.candidate){//发送候选地址到信令服务器}};peerConnection.ontrack=(event)=>{constremoteStream=event.streams[0];//显示远程媒体流videoElement.srcObject=remoteStream;};2.4 RTCDataChannelRTCDataChannel 是什么?RTCDataChannel 是 WebRTC 提供的一个 API,用于在对等端之间传输任意数据。它支持低延迟、可靠性可选的数据传输方式,使得在音视频通信之外,还可以传输文本、文件等数据。如何使用 RTCDataChannel?通过 RTCPeerConnection 创建一个数据通道,并定义其配置。constdataChannel=peerConnection.createDataChannel("myDataChannel");主要功能:1. 发送和接收数据send(data): 通过数据通道发送数据,可以是字符串、二进制数据等。onmessage: 当接收到数据时触发。dataChannel.send("Hello,WebRTC!");dataChannel.onmessage=(event)=>{console.log("Receivedmessage:",event.data);};2. 事件处理onopen: 当数据通道打开时触发。onclose: 当数据通道关闭时触发。dataChannel.onopen=()=>{console.log("Datachannelisopen");};dataChannel.onclose=()=>{console.log("Datachannelisclosed");};2.5 API 协同工作通过 getUserMedia 获取用户的摄像头和麦克风流,结合 getDisplayMedia 进行屏幕分享,再利用 RTCPeerConnection 管理音视频连接,最终通过 RTCDataChannel 实现数据传输。通过这些 API 的协同工作,我们可以轻松实现一个功能齐全的视频通话应用。3、小结在《WebRTC探索之旅:前端视角下的实时通信解析(上)》中,我们迈出了了解 WebRTC 的第一步。我们探讨了 WebRTC 的核心定义及其在开放网络中实现实时音视频交流的能力,同时掌握了基础 API,为构建实时通信应用奠定了基础。接下来,我们将深入挖掘 WebRTC 的核心技术,包括:链接方式的多样性:研究 WebRTC 支持的各种连接方式及其影响。PeerConnection 的核心作用:解析 PeerConnection 对象的功能和重要性。会话流程的梳理:系统化了解 WebRTC 会话的生命周期,包括信令处理和媒体协商。信令服务器的实践:探讨如何搭建和配置信令服务器以支持 WebRTC 通信。随着我们进一步探索 WebRTC 的技术细节,你将掌握构建复杂实时通信应用的关键知识。期待在下一篇文章中继续发掘其技术精髓,并学习如何将这些理论应用于实际开发中,实现高效的实时通信解决方案。想了解更多转转公司的业务实践,点击关注下方的公众号吧!
|
|