WebRTC源码研究(11)获取音视频设备的访问权限

2,273 阅读4分钟

WebRTC系列文章

  1. WebRTC源码研究(1)WebRTC架构

  2. WebRTC源码研究(2)webrtc源码目录结构

  3. WebRTC源码研究(3)webrtc运行机制

4.WebRTC源码研究(4)web服务器工作原理和常用协议基础

  1. [WebRTC源码研究(5)Nodejs搭建环境

  2. [WebRTC源码研究(6)创建简单的HTTP服务

  3. [WebRTC源码研究(7)

  4. [WebRTC源码研究(8)

  5. [WebRTC源码研究(9)

  6. [WebRTC源码研究(10)

  7. [WebRTC源码研究(11)获取音视频设备的访问权限

  8. [WebRTC源码研究(12)视频约束

  9. [WebRTC源码研究(13)音频约束

  10. [WebRTC源码研究(14)视频特效

  11. [WebRTC源码研究(15)从视频中获取图

  12. [WebRTC源码研究(16)只采集音频数据

  13. [WebRTC源码研究(17)MediaStreamAPI 获取视频约束

  14. [WebRTC源码研究(18)WebRTC录制视频原理

  15. [WebRTC源码研究(19)WebRTC录采集平面数据

  16. [WebRTC源码研究(20)WebRTC信令服务器原理

  17. WebRTC源码研究(21)WebRTC信令服务器实现

WebRTC源码研究(11)获取音视频设备的访问权限

本篇博客的源码下载地址: 点击这里下载源码

1. 获取音视频设备的访问权限Api

2. WebRTC在网页中实现获取访问权限

在上一篇博客中,我们已经学会了利用enumerateDevices这个API来获取到音视频设备,但是现在我们遇到了一个问题,如何在chrome浏览器中是可以看到音视频设备的名字的,但是在safari浏览器中却都是空白的。

chrome下可以正常获取设备信息 chrome下的获取设备信息 在safari下获取不到信息,如下图:

在safari下获取不到信息

上面在Safari下获取不到,就是因为没有获取到相应的权限,由于各个浏览器它的实现是完全不一样的,所以它对这个权限的控制也是不同的,那对于safari和FireFOX来说对权限的控制更严格一些,在chrome下也和不同的版本有关。

那么如何去解决这个问题呢?

  1. 做过IOS相关开发都知道,苹果很多权限访问都是需要弹框让用户授权的,只有授权了才能使用。
  2. 这就要求我们在采集音视频数据的时候,这个时候浏览器就会弹出一个窗口问你是否允许访问音视频设备,我们允许采集音视频设备了,这样我们就获得了相应的访问设备的权利,
  3. 拿到这个权限之后,我们再去调用enumerateDevices,这个时候我们就可以拿到所有的设备名称了。

下面我们来实践一下,看看在网页端是怎么调用api获取设备权限的,废话不多说,直接上代码:

先来看看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>

再来看看脚本文件clent.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);
}

运行效果如下:

运行效果如下