在之前我们已经学会了利用enumerateDevices这个API来获取到音视频设备,但是我们遇到了一个问题,如何在chrome浏览器中是可以看到音视频设备的名字的,但是在safari浏览器中却都是空白的。
在chrome下
在safari下名称都是空的
这个原因非常简单,就是因为没有获取到相应的权限,由于各个浏览器它的实现是完全不一样的,所以它对这个权限的控制也是不同的,那对于safari和FireFOX来说对权限的控制更严格一些,在chrome下也和不同的版本有关,那么如何去解决这个问题呢?
这就要求我们在采集音视频数据的时候,这个时候浏览器就会弹出一个窗口问你是否允许访问音视频设备,我们允许采集音视频设备了,这样我们就获得了相应的访问设备的权利,拿到这个权限之后,我们再去调用enumerateDevices,这个时候我们就可以拿到所有的设备名称了。
下面我们来实践一下,看是否能获得设备名称
index.html
<html> <head> <title>捕获音视频数据 WebRTC capture video and audio</title> </head> <body> <div> <label>audio Source:</label> <select id="audioSource"></select> </div> <div> <label>audio Output:</label> <select id="audioOutput"></select> </div> <div> <label>video Source:</label> <select id="videoSource"></select> </div> <!-- 我们创建一个video标签,这个标签就可以显示我们捕获的音视频数据 autoplay 表示当我们拿到视频源的时候直接播放 playsinlin 表示在浏览器页面中播放而不是调用第三方工具 --> <video autoplay playsinlin id="player"></video> <!-- 引入 adapter.js库 来做 不同浏览器的兼容 --> <script src="https://webrtc.github.io/adapter/adapter-latest.js"></script> <script src="./js/client.js"></script> </body> </html>client.js
'use strict' var audioSource = document.querySelector('select#audioSource'); var audioOutput = document.querySelector('select#audioOutput'); var videoSource = document.querySelector('select#videoSource'); // 获取video标签 var videoplay = document.querySelector('video#player'); // deviceInfos是设备信息的数组 function gotDevices(deviceInfos){ // 遍历设备信息数组, 函数里面也有个参数是每一项的deviceinfo, 这样我们就拿到每个设备的信息了 deviceInfos.forEach(function(deviceinfo){ // 创建每一项 var option = document.createElement('option'); option.text = deviceinfo.label; option.value = deviceinfo.deviceId; if(deviceinfo.kind === 'audioinput'){ // 音频输入 audioSource.appendChild(option); }else if(deviceinfo.kind === 'audiooutput'){ // 音频输出 audioOutput.appendChild(option); }else if(deviceinfo.kind === 'videoinput'){ // 视频输入 videoSource.appendChild(option); } }) } // 获取到流做什么, 在gotMediaStream方面里面我们要传人一个参数,也就是流, // 这个流里面实际上包含了音频轨和视频轨,因为我们通过constraints设置了要采集视频和音频 // 我们直接吧这个流赋值给HTML中赋值的video标签 // 当时拿到这个流了,说明用户已经同意去访问音视频设备了 function gotMediaStream(stream){ videoplay.srcObject = stream; // 指定数据源来自stream,这样视频标签采集到这个数据之后就可以将视频和音频播放出来 // 当我们采集到音视频的数据之后,我们返回一个Promise return navigator.mediaDevices.enumerateDevices(); } function handleError(err){ console.log('getUserMedia error:', err); } // 判断浏览器是否支持 if(!navigator.mediaDevices || !navigator.mediaDevices.getUserMedia){ console.log('getUserMedia is not supported!'); }else{ var constraints = { // 表示同时采集视频金和音频 video : true, audio : false } navigator.mediaDevices.getUserMedia(constraints) .then(gotMediaStream) // 使用Promise串联的方式,获取流成功了 .then(gotDevices) .catch(handleError); }