最近开始学习如何用WebRTC实现私有化会议直播系统,从一些最常用的WebRTC API 基础知识学起,下面开始记录一些知识点,以免遗忘。
什么是getUserMedia?
getUserMedia意如其名,那就是获取用户层面的媒体,当你的计算机通过 USB
或者其他网络形式接入了 N 多个摄像头或虚拟设备时,都是可以通过这个 API
获取到的。 当然不仅仅是视频设备,还包括音频设备和虚拟音频设备。 获取媒体设备是最简单的操作,它还可以控制获取到媒体的分辨率,以及其他的以一些可选项。
如何使用 getUserMedia?
有简单的用法,有复杂的用法。一般简易场景下,大多数 API 用默认参数就可以实现对应功能,getUserMedia
也一样,直接调用不使用任何参数,则获取的就是 PC 的默认摄像头和麦克风。
但是,当我们遇到复杂一点的应用场景,比如你的电脑上自带麦克风,同时你连接了蓝牙耳机和有线耳机,那么在视频通话过程中,你如何主动选择使用哪个呢?也就是说, 在用摄像头或者麦克风之前,我们先要解决如何从 N 个摄像头或者麦克风中选择我们想要的。
要解决这个问题,我们必须先有个大体的思路(当然这个思路并不是凭空想象出来的,而是在一定的技术储备下才有的。如果你开始前没有任何思路也没关系,可以参考他人的经验),如下:
- 获取当前设备所有的摄像头和麦克风信息;
- 从所有的设备信息中遍历筛选出我们想要使用的设备;
- 将我们想要使用的设备以某种参数的形式传递给浏览器
API
; - 浏览器
API
去执行获取的任务。
上面提到的设备以某种参数的形式传递给 API
,那么这个设备必然是以参数存在的,因此这里有几个概念需要提前知道,如下:
- 音频输入:ID、类型、标签
- 视频输入:ID、类型、标签
- 音频输出:ID、类型、标签
设备分成了图中的三个大类型,每个类型都有固定的字段,比如 ID、kind、label ,而其中用于区分它们的就是kind字段
中的固定值,最核心的字段就是 ID,后面我们经常用的就是这个 ID。
那么,在前端如何使用 JavaScript
获取到这些信息?看下面代码:
function handleError(error) {
alert("摄像头无法正常使用,请检查是否占用或缺失")
console.error('navigator.MediaDevices.getUserMedia error: ', error.message, error.name);
}
/**
* @author suke
* device list init
*/
function initInnerLocalDevice(){
const that = this
var localDevice = {
audioIn:[],
videoIn: [],
audioOut: []
}
let constraints = {video:true, audio: true}
if (!navigator.mediaDevices || !navigator.mediaDevices.enumerateDevices) {
console.log("浏览器不支持获取媒体设备");
return;
}
navigator.mediaDevices.getUserMedia(constraints)
.then(function(stream) {
stream.getTracks().forEach(trick => {
trick.stop()
})
// List cameras and microphones.
navigator.mediaDevices.enumerateDevices()
.then(function(devices) {
devices.forEach(function(device) {
let obj = {id:device.deviceId, kind:device.kind, label:device.label}
if(device.kind === 'audioinput'){
if(localDevice.audioIn.filter(e=>e.id === device.deviceId).length === 0){
localDevice.audioIn.push(obj)
}
}if(device.kind === 'audiooutput'){
if(localDevice.audioOut.filter(e=>e.id === device.deviceId).length === 0){
localDevice.audioOut.push(obj)
}
}else if(device.kind === 'videoinput' ){
if(localDevice.videoIn.filter(e=>e.id === device.deviceId).length === 0){
localDevice.videoIn.push(obj)
}
}
});
})
.catch(handleError);
})
.catch(handleError);
}
这个代码片段的主要作用就是获取用户设备上所有的摄像头和麦克风信息,起关键作用的是enumerateDevices
函数,但是在调用这个关键函数之前,getUserMedia
函数出现在了这里,它的出现是用户在访问服务时直接调用用户摄像头,此时如果用户授权且同意使用设备摄像头、麦克风,那么enumerateDevices
函数就能获取设备信息了,在这里getUserMedia
函数可以理解为获取摄像头或者麦克风权限集合的探路函数。
看下图,我将我电脑上使用enumerateDevices
函数加载到的信息,根据前面提到的字段kind
,将其分三类并打印到控制台。
千万不要小看现在获取到的这些信息哦,在后面视频通话或会议过程中,我们需要抉择摄像头用前置还是后置,麦克风是用蓝牙还是有线,都是离不开这些信息的。
在拿到所有的摄像头麦克风信息之后,我们需选出最终要参与视频通话的那个信息体,看上图中 VideoIn
数组里面label:"eseSoft Vcam"
, 这个摄像头就是我想要参会的摄像头,那么我怎样指定让代码去选择这个摄像头呢?这里就涉及到了getUserMedia
的约束参数constraints
。
……关于constraints的使用我们后期在分享,如果您等不及了,也可以跟我一起学习哦,链接:https://s.juejin.cn/ds/hPgB1bL/
本文来自作者投稿,版权归原作者所有。如需转载,请注明出处:https://www.nxrte.com/jishu/webrtc/7202.html