在之前我们已经学会了利用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);
}