对于前端开发小伙伴而言,如果用 JavaScript 做音视频处理
在以前是不可想象的,因为首先就要考虑浏览器的性能是否跟得上音视频的采集
但是 Google 作为国际顶尖科技公司,就喜欢做一些常人无法想象的事情
2011 年,Google 创立了 WebRTC 项目,其愿景就是可以在浏览器之间快速地实现音视频通信。
随着时间的发展,在浏览器之间进行实时音视频通信已经已经变很成熟了
从上图结构图可以看出,1对1的视频通话结构大体上可以分为四个部分
两个 WebRTC 终端:这里可以看成是两个浏览器,主要负责音视频采集、编解码、NAT 穿越、音视频数据传输
Signal(信令)服务器:负责信令处理,如点击静音,关闭摄像头,进入房间等指令操作
STUN/TURN 服务器:负责获取 WebRTC 终端在公网的 IP 地址,以及 NAT 穿越失败后的数据中转
浏览器中采集音视频设备非常简单
只需要使用 getUserMedia(constraints)
方法即可
传入的 constraints
是配置参数,可以单独配置是否采集音视频
但是IE8以下的浏览器不兼容该视频采集方法
// 同时采集音视和视频 const mediaStreamContrains = { video: true, audio: true }; var promise = navigator.mediaDevices.getUserMedia(mediaStreamContrains);
frameRate:可以配置视频帧率
width:设置视频宽度,ideal代表理想宽度
height:设置视频高度,ideal代表理想高度
aspectRatio:代表宽高比
对于音频则是开启回音消除、降噪、自动增益等操作
const mediaStreamContrains = { video: { frameRate: {min: 20}, width: {min: 640, ideal: 1280}, height: {min: 360, ideal: 720}, aspectRatio: 16/9 }, audio: { echoCancellation: true, // 开启回音消除 noiseSuppression: true, // 降噪 autoGainControl: true // 自动增益 } }; var promise = navigator.mediaDevices.getUserMedia(mediaStreamContrains);
采集摄像头的内容并在浏览器上播放
需要注意的是,一定要在https协议或者本地localhost域名下才可以调用
我们通过调用 getUserMedia
方法,将视频数据加载到 video
标签中进行播放
如果video标签想要播放流媒体数据,需要将数据挂在到 srcObject
属性上,该属性和普通的 src
属性互斥
如果是第一次请求 Camera,浏览器会向用户弹出提示窗口,让用户决定是否可以访问摄像头
如果用户允许访问,且设备可用,则调用 gotLocalMediaStream
方法
<!DOCTYPE html> <html> <head> <title>Realtime communication with WebRTC</title> </head> <style> video { width: 800px; height: 450px; } </style> <body> <h1>Realtime communication with WebRTC </h1> <video autoplay playsinline></video> <script> 'use strict'; const mediaStreamContrains = { video: true }; const localVideo = document.querySelector('video'); function gotLocalMediaStream(mediaStream) { localVideo.srcObject = mediaStream; } function handleLocalMediaStreamError(error) { console.log('navigator.getUserMedia error: ', error); } navigator.mediaDevices.getUserMedia(mediaStreamContrains).then( gotLocalMediaStream ).catch( handleLocalMediaStreamError ); </script> </body> </html>
以手机为例,它一般会包括前置摄像头和后置摄像头麦克风、相机、耳机等。我们可以根据自己的需要,选择打开不同的设备
WebRTC 是否提供了的 enumerateDevices
接口,可以查询自己机子上都有哪些音视频设备
deviceInfo中有三个比较重要的属性
deviceID:设备的唯一标识
label:设备名称,用户已被授予访问媒体设备的权限(要想授予权限需要使用 HTTPS 请求),否则 label 字段始终为空。
kind:设备种类,可用于识别出是音频设备还是视频设备,是输入设备还是输出设备
// 判断浏览器是否支持这些 API if (!navigator.mediaDevices || !navigator.mediaDevices.enumerateDevices) { console.log("enumerateDevices() not supported."); return; } // 枚举 cameras and microphones. navigator.mediaDevices.enumerateDevices() .then(function (deviceInfos) { // 打印出每一个设备的信息 deviceInfos.forEach(function (deviceInfo) { console.log(deviceInfo.kind + ": " + deviceInfo.label + " id = " + deviceInfo.deviceId); }); }) .catch(function (err) { console.log(err.name + ": " + err.message); });
方法 getUserMedia
的配置参数