2 HTML躬行记——WebRTC基础实践

WebRTC (Web Real-Time Communications) 是一项实时通讯技术,在 2011 年由 Google 提出,经过 10 年的发展,W3C 于 2021 年正式发布 WebRTC 1.0 标准 。

2 HTML躬行记——WebRTC基础实践

文章插图
WebRTC 标准概括介绍了两种不同的技术:媒体捕获设备和点对点连接(P2P,Peer-to-Peer),可让用户无需安装任何插件或第三方软件的情况下,实现共享桌面、文件传输、视频直播等功能 。
下图是官方给出的一张 WebRTC 整体架构设计图:
2 HTML躬行记——WebRTC基础实践

文章插图
  • 紫色部分是前端开发所使用的 API 。
  • 蓝色实线部分是各大浏览器厂商所使用的 API 。
  • 蓝色虚线部分包含可自定义的 3 块:音频引擎、视频引擎和网络传输 。
由于各个浏览器对 WebRTC 的实现有所不同,因此 Google 官方提供了一个适配器脚本库:adapter.js,省去很多兼容工作 。
本文的源码已上传至 Github , 有需要的可以随意下载 。
一、自拍自拍是指通过摄像头拍照生成图片,先看下 HTML 结构 , 其实就 4 个元素 。
<video id="video"></video><button id="btn">拍照</button><canvas id="canvas" width="300" height="300"></canvas><img id="img" alt="照片"/>1)getUserMedia()
然后在脚本中声明各个元素 , 通过 navigator.mediaDevices.getUserMedia() 方法获取媒体流 。
const video = document.getElementById('video');const canvas = document.getElementById('canvas');const btn = document.getElementById('btn');const img = document.getElementById('img');const size = 300;/** * 获取媒体流 */navigator.mediaDevices.getUserMedia({video: {width: size,height: size,},audio: false}).then((stream) => {video.srcObject = stream;video.play();});getUserMedia() 的参数是一个包含了video 和 audio 两个成员的 MediaStreamConstraints 对象,上面代码将摄像头的分辨率限制为 300 x 300 。
then() 中的 stream 参数是一个 MediaStream 媒体流,一个流相当于容器 , 可以包含几条轨道,例如视频和音频轨道,每条轨道都是独立的 。
video 元素中的 src 和 srcObject 是一对互斥的属性,后者可关联媒体源 , 根据规范也可以是 Blob 或者 File 等类型的数据 。
接着为按钮绑定点击事件,并且在点击时从流中捕获帧,画到 Canvas 内,再导出赋给 img 元素 。
/** * 点击拍照 */btn.addEventListener('click', (e) => {const context = canvas.getContext('2d');// 从流中捕获帧context.drawImage(video, 0, 0, size, size);// 将帧导出为图片const data = https://www.huyubaike.com/biancheng/canvas.toDataURL('image/png');img.setAttribute('src', data);}, false);在下图中,左边是 video 元素,打开摄像头后就会有画面,在点击拍照按钮后 , 右边显示捕获的帧 。
2 HTML躬行记——WebRTC基础实践

文章插图
2)enumerateDevices()
MediaDevices 提供了访问媒体输入和输出的设备 , 例如摄像头、麦克风等,得到硬件资源的媒体数据 。
mediaDevices.enumerateDevices() 会得到一个描述设备的 MediaDeviceInfo 的数组 。
其中 groupId 用于标识多个设备属于同一个物理设备,例如一个显示器内置了摄像头和麦克风 。
navigator.mediaDevices.enumerateDevices().then((devices) => {devices.forEach((device) => {console.log(`${device.kind}: ${device.label} id = ${device.deviceId}`);});})3)devicechange
当媒体设备(例如麦克风、摄像头等)连接到系统或从系统中移除时,devicechange 事件就会被发送给设备实例 。
navigator.mediaDevices.ondevicechange = (event) => { };event 参数没有附加任何特殊的属性 。
二、共享桌面Windows 系统采用的共享桌面协议是 RDP(Remote Desktop Protocal),另一种可在不同操作系统共享桌面的协议是 VNC(Virtual Network Console) 。
像 TeamViewer 采用的就是后一种协议 , 而 WebRTC 的远程桌面没有采用传统的 RDP、VNC 等协议,因为不需要远程控制 。
WebRTC 提供了 getDisplayMedia() 方法采集桌面,在使用上与之前的 getUserMedia() 方法类似 。
navigator.mediaDevices.getDisplayMedia({video: {width: 2000,height: 1000}}).then((stream) => {video.srcObject = stream;video.play();});在刷新页面后,会要求选择共享的桌面,包括整个屏幕、窗口或 Chrome 标签页 。
2 HTML躬行记——WebRTC基础实践

文章插图
三、录像WebRTC 的录像包括录制音频和视频两种流,通过 Blob 对象将数据保存成多媒体文件 。

推荐阅读