WebRTC源码研究(9)webrtc获取音视频设备

WebRTC源码研究(9)webrtc获取音视频设备

1. 音频设备简介

2. IOS开发中原生的获取音视频设备api

3. Android开发中原生的获取音视频设备api

4. WebRTC中获取音视频的api

4.1 enumerateDevices

在 WebRTC 的规范中,给我们提供一个重要的API,叫enumerateDevices。通过这个API 我们就可以获取到电脑中的音频和视频设备。

接下来我们看看它的基本格式,和怎么调用:

/**
* 基本格式 通过navigator.mediaDevices下的enumerateDevices方法获取所有的音频和视频设备
* 最后它返回的值是一个Promise,这是JavaScript中特有的一个对象
*/
var ePromise = navigator.mediaDevices.enumerateDevices();

通过上面这行代码就可以获取所有的音视频设备

Promise里面有个重要的结构体:MediaDevicesInfo

在这个结构体里面存放几个非常重要的信息:

结构体属性说明
MediaDevicesInfodeviceID设备ID
label设备名称
kind设备类型
groupID设备所在组,如果两个设备groupID相同,则说明是同一个物理设备
  1. deviceID就是这个设备的唯一标识符
  2. label就是设备的名字,就是我们人可读的,比如说内置音频设备,内置音频输入设备、内置音频输出设备或者是耳机等等一些人 可读的设备名字。
  3. kind表示设备的种类,比如音频输入设备、视频输出设备、还有视频输入设备
  4. groupID表示组ID,就是两个设备GroupID相同的组ID,说明是同一个物理设备,以音频 为例,同一个设备里面包含两种类型,一种是输入一种是输出

4.2 Promise

下面我们简单介绍一些JavaScript中的PromisePromise执行流程
上图很好的解释了JavaScript中的Promise是什么东西。

我们需要知道一个背景:JavaScript是使用单线程去处理整个逻辑的,为了防止它被阻塞,大量使用了这个异步调用。
这个Promise就是异步调用其中的一种方式。也是现在比较流行,也是大家比较认可的一种方式。

下面介绍一下它的基本思想:

  1. 首先你在创建Promise的时候要传给它一个handle的处理函数,这个handle处理函数是用来处理你的主要逻辑。在它处理之后,如果成功了会调用这个处理函数中的resolve函数;同理,如果失败了它就会调用reject这个函数,这样就创建好了一个Promise.
  2. Promise可以通过注册两个方法:
    一个是then, 一个是catch
    then就是当我整个逻辑处理成功之后会收到这个on_resolve事件,收到这个事件之后就处理一些逻辑,这就是它这个then
    catch就是失败了,当失败的时候处理一些失败的逻辑,then这个 如果 成功之后,它是一个链式的,可以继续写一个then
  3. 它的核心是,Promise存放有几个状态,第一个是未执行的一个状态,第二个当你执行handle的逻辑的时候赋予这个运行状态,当这个处理成功之后进入这个resolve改为成功状态,如果失败了进入 reject里面设置为出错状态。当你注册这个函数之后你 就可以根据Promise里面这个状态机如果成功了就调用这个then方法 ,如果失败了就 调用这个catch方法 ,
    以上就是Promise的基本逻辑 。

回到上面enumerateDevices的函数,实际上在这个 函数里面它就new 了一个Promise,并且给它注册了一个handle,所以当它这个 函数执行的时候它 就返回一个Promise,在我们用的时候拿到这个Promise之后,我们就给他注册两个函数,一个是then的方法一个是catch的方法,如果成功了他就会调用then我们成功的一些逻辑,如果失败了就会调用失败那些处理逻辑,这就是javaScript中的Promise的基本思想。

接下来我们就通过一个实际的例子,如何通过WebRTCAPI来获取到我们的音视频设备:

  • 我们先在终端命令行创建一个自己的目录,并敲入:vi index.html 新建一个html文件

创建一个文件

  • 编辑网页的内容如下:
<html>
	<head>
		<title> WebRTC get audio and video devices - kongyulu </title>
	</head>
	<body>
		<div>
			<label>audio input device:</label>
			<select id="audioSource"></select>
		</div>
		<div>
			<label>audio output device:</label>
			<select id="audioOutput"></select>
		</div>
		<div>
			<label>video input device:</label>
			<select id="videoSource"></select>
		</div>
 
		<script src="./js/client.js"></script>
	</body>
</html>
	

编辑网页内容

按下“esc” 键, 然后输入:wq,保存退出。

  • 接下来我们需要创建一个简单的js文件,先在index同级目录下,执行mkdir js 创建一个js目录,然后执行vi client.js 创建一个js文件:

创建js 文件

  • 然后,我在里面引入我们编写的脚本client.js,这样当我们打开页面的时候,这个JavaScript代码就会执行 ,就是chrome浏览器会给他交到底层的V8引擎去解析然后去渲染,这样我们的Html就算写完了。
  • 下面来看看clent.js的内容:
// 1、使用严格语法 
'use strict'
var audioSource  = document.querySelector("select#audioSource");
var audioOutput  = document.querySelector("select#audioOutput");
var videoSource  = document.querySelector("select#videoSource");
 
//  2、首先判断浏览器是否支持此方法,在浏览器支持的情况下才调用
if(!navigator.mediaDevices ||
	!navigator.mediaDevices.enumerateDevices){
	console.log('enumerateDevices is not supported!');
}else {
	navigator.mediaDevices.enumerateDevices()
		.then(gotDevices)
		.catch(handleError);
}
 
// 3、实现gotDevices,在gotDevices就可以得到我们刚说的 deviceInfos 了
function gotDevices(deviceInfos){
    // 5、当我们拿到deviceInfos这个数组之后我们就开始遍历这个数组
    // 在这个每一项里面实际上我们可以注册一个匿名函数去处理每一项的内容,它的参数就是每一项的值
	deviceInfos.forEach( function(deviceInfo){
		console.log(deviceInfo.kind + ": label = " 
				+ deviceInfo.label + ": id = "
				+ deviceInfo.deviceId + ": groupId = "
				+ deviceInfo.groupId);	
		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);
		}
	});
 
}
// 4、在handleError里面会返回一个错误
function handleError(err){
	console.log(err.name + " : " + err.message);
}

将上面这段代码写入到js文件:

编辑js文件
同样,按下“esc” 键, 然后输入:wq,保存退出。

  • 我们先直接用Google浏览器打开,看看:

用Google浏览器打开
如上图是我的mac电脑上的信息,获取到了两个音频设备,一个视频设备,但是没有获取到id,只有GroupId打印了

  • 我们思考一下,为啥没有获取到id等信息呢?

原因是,我使用的是http的方式访问的,是不安全,默认不会返回这些信息给浏览器。

  • 我们看一下其他获取到了id的情况如下:

运行结果

我们可以看到有输入设备,label没有显示,id是default,我们看到前两个groupId是一样的,第三个是视频的输入设备,groupId不一样了,第四个 是音频的输入设备,这个输入和输出设备物理设备是一样的,所以他们有同一个groupId

接下来我们在url前面输入https,这样设备名称 就显示出来了,如下图所示:

输出结果

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值