关于浏览器中获取设备和屏幕共享的基本接口在上一篇中已经介绍过浏览器获取摄像头、麦克风和屏幕共享(一),可以通过浏览器API来获取麦克风和摄像头,可是在业务场景中,我们可能不仅仅是需要获取设备,如果用户有多个摄像头和麦克风设备,我们可能需要获取指定的设备,还可能是指定的分辨率或者帧率。
获取设备列表
通过浏览器API来获取设备列表
navigator.mediaDevices.enumerateDevices().then((list) => {
console.log("list:", list);
}).catch((err) => {
console.log("enumerateDevices error:", err);
})
在使用https或者127.0.0.1打开网页后运行上面的代码,看到输出的list是个空的数组。没有获取到设备列表的原因大概率是因为页面还没有获取到使用音视频设备的权限(当然,也有可能是你确实是没有任何的设备,比如台式机)。目前主流浏览器都限制了获取音视频设备的权限,需要先询问用户是否允许使用音视频设备,允许之后才能获取设备列表。所以上面的代码还需要稍作修改
if (navigator && navigator.mediaDevices && navigator.mediaDevices.getUserMedia) {
navigator.mediaDevices.getUserMedia({audio: true, video: true}).then((mediastream) => {
navigator.mediaDevices.enumerateDevices().then((list) => {
console.log("list:", list);
}).catch((err) => {
console.log("enum error");
})
}).catch((err) => {
})
} else {
// 浏览器不支持获取设备权限,有可能是当前页面不是https,也可能是当前浏览器不支持获取设备权限
}
然后在控制台中能看到
返回的数据中包含了几种不同类型的数据,可以通过kind字段来判断设备信息的类型。
• deviceId
设备的唯一id,可以通过设置devicdId来获取指定的设备。
• label
设备的名称
• kind
设备的类型,主要有三种类型
"audioinput":音频输入设备,比如麦克风
"audiooutput":音频输出设备,比如扬声器
"videoinput":视频输入设备,比如摄像头
浏览器获取摄像头
相比上一篇浏览器获取摄像头、麦克风和屏幕共享(一)中我们只能获取默认摄像头,我们现在可以在获取设备列表之后,获取指定的摄像头。
<video id="localVideo" controls ></video>
if (navigator && navigator.mediaDevices && navigator.mediaDevices.getUserMedia) {
navigator.mediaDevices.getUserMedia({
diveceId: "", // 设置成设备列表中kind是videoinput的deviceId
width: 640, // 视频宽度
height: 480, // 视频高度
frameRate: 30, // 视频帧率
}).then((mediastream) => {
// 如果需要播放,则可以直接使用auido播放
let videoElement = document.getElementById("localVideo");
videoElement.srcObject = mediastream;
videoElement.play();
// 通过设置不同的分辨率,我们也能从最终的显示效果中发现效果略有不同,当然也可以通过代码来验证我们设置的参数是否生效了
let videoTrack = mediastream.getVideoTracks()[0];
let settings = videoTrack.getSettings();
console.log("video frameRate:", settings.frameRate);
console.log("video width:", videoElement.videoWidth;
console.log("video height:", videoElement.videoHeight);
}).catch((err) => {
// 获取摄像头失败,可以通过 err.name 或者 err.message 来判断错误原因,err并没有返回错误错误码
})
} else {
// 浏览器不支持获取设备权限,有可能是当前页面不是https,也可能是当前浏览器不支持获取设备权限
}
移动端浏览器获取摄像头
在移动端,同样可以通过以上的方法来获取摄像头,但是还有个更方便的方法,不需要获取设备列表,因为移动端是默认有前置和后置两个摄像头的。可以直接通过参数获取。
注意移动端获取摄像头的分辨率同样认为是横置摄像头,据个例子,比如我们想要获取前置摄像头,分辨率设置应该是640360或者640480(这样的分辨率看起来和pc端是一样的,但是获取过来的摄像头效果放在手机上的视觉效果是360640或者480640.效果是正确的,如果分辨率设置反了,比如设置480*640,看起来的效果就是画面被裁减的效果,可以自己试试看).
if (navigator && navigator.mediaDevices && navigator.mediaDevices.getUserMedia) {
navigator.mediaDevices.getUserMedia({
facingMode: "user", // 在移动端默认是有两个摄像头的,user表示前置摄像头,environment表示后置摄像头
width: 640, // 视频宽度
height: 480, // 视频高度
frameRate: 30, // 视频帧率
}).then((mediastream) => {
// 如果需要播放,则可以直接使用auido播放
let videoElement = document.getElementById("localVideo");
videoElement.srcObject = mediastream;
videoElement.play();
// 通过设置不同的分辨率,我们也能从最终的显示效果中发现效果略有不同,当然也可以通过代码来验证我们设置的参数是否生效了
let videoTrack = mediastream.getVideoTracks()[0];
let settings = videoTrack.getSettings();
console.log("video frameRate:", settings.frameRate);
console.log("video width:", videoElement.videoWidth;
console.log("video height:", videoElement.videoHeight);
}).catch((err) => {
// 获取摄像头失败,可以通过 err.name 或者 err.message 来判断错误原因,err并没有返回错误错误码
})
} else {
// 浏览器不支持获取设备权限,有可能是当前页面不是https,也可能是当前浏览器不支持获取设备权限
}
释放设备
在windows平台,视频设备是独占的,一个程序获取了设备之后,在它释放设备之前,其他应用都无法获取该设备。当我们获取设备之后,摄像头的灯就会被点亮,所以设备应该在需要用的时候才获取,使用结束就释放,否则就有侵犯隐私的嫌疑。
if (navigator && navigator.mediaDevices && navigator.mediaDevices.getUserMedia) {
navigator.mediaDevices.getUserMedia({video: true}).then((mediastream) => {
// 代码运行到此处的时候,我们可以看到,摄像头的灯已经被点亮了。即使我们不显示视频内容,灯也是点亮的
// 在我们刷新页面之前,摄像头会一直被这个页面占用着。接下来我们来释放设备
// 首先从mediastream中获取所有的audiotrack和videotrack
let arr = mediastream.getTracks();
// 释放所与的audiotrack和videotrack
arr.forEach((track) => {
track.stop();
})
//代码运行到此处,可以看到摄像头的灯熄灭了。设备已经释放完成
}).catch((err) => {
// 获取摄像头失败,可以通过 err.name 或者 err.message 来判断错误原因,err并没有返回错误错误码
})
} else {
// 浏览器不支持获取设备权限,有可能是当前页面不是https,也可能是当前浏览器不支持获取设备权限
}
其他
如果你也是专注前端多媒体或者对前端多媒体感兴趣,可以搜索微信公众号"前端多媒体"