今天我们介绍的是音频相关的约束,以及手机web端切换前后摄像头
第一个是与音量相关的,这个数值是从0到1.0,0就是静音 ,1.0就是最大音量。
第二个是采样率,在音频里面有很多采样率,四万八,三万二,一万六,八千等,根据自己的需要设置就好了。
第三个是采样大小,每一个采样大小是由多少位表示,一般情况下我们都是用16位,也就是两个字节。
第四个是回音,就是我们在开启采集 数据之后,是否要开启回音消除,在我们实时直播的过程中,回音消除是 一个非常重要的功能,当双方通信的时候 ,如果有回音传过来,对这个通话质量会造成极大的影响,设置可以通过true或false来开启或关闭回音消除。
第五个是自动增益,在我原有的录制的声音的基础上是否给他增加这个音量,它增加的范围也是有一定范围的,这也是一个用 true或false设置的,也就是开始或者关闭。
第六个是降噪,就是我们在采集数据的时候是否要开启降噪功能 。
第七个表示 延迟大小,当我直播过程中,我们音视频,这里latency设置小的话,就表示它的 视频传输试试通信的时候它的延迟就会小,延迟小的后果就是当你网络状况不好的时候,它就会出现卡顿甚至花屏等质量问题。但是它的好处是我们双方可以实时通信,一般是低于500毫秒,这是非常好的一个质量了。当然最好的是200毫秒以内,从采集到编码到传输到对方接受且解码再到渲染整个过程中是200毫秒以内是最好的 。我们正常通话应该是这样一个延迟。我们感受500毫秒还可以,再往上800毫秒 就比较大了。
如果你的latency设置的大,它的好处是你的画面比你声音更平滑,但是它这种及时性,就是说如果做实时通信的话 ,就会很麻烦,你说了一句话,你过了一秒多,对方才听到,在回答你又过了一秒。这种交互的话就没法忍受了。
第八个表示单声道还是双声道,一般情况下我们会使用单声道,如果是对于一些乐器,都是双声道,这样的话音质才更好。
第九个是devideID就是当我有多个输入输出设备的时候,我可以进行设备的切换 ,比如在手机上当我改变了devideID之后,我从前置摄像头就可以切换到后置摄像头。
第十个是groupID,它代表 是同一个物理设备,我们之前 说过,对于 音频来说,音频的输入输出是同一个物理设备,不同浏览器其实它的实现是不一样的,那么对于chrome来说它分成了音频的输入输出,对于FireFOX和safari就没有音频的输出,音频视频设备就是一个音频设备。
当然约束也可以写成最大最小的范围限制,这些 都可以设置,这样它就是一个动态的,它会在这个范围内选择一个最好的,不是说摄像的时候实时变化 ,是说它选择的时候会在这个范围内选择一个最好的。帧率他是可以根据网络的情况去调整的。
我们看constraints参数约束
切换摄像头,每次改变选择 的时候就会触发start方法
'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);
}
function start() {
// 判断浏览器是否支持
if(!navigator.mediaDevices ||
!navigator.mediaDevices.getUserMedia){
console.log('getUserMedia is not supported!');
}else{
// 获取到deviceId
var deviceId = videoSource.value;
// 这里是约束参数,正常情况下我们只需要是否使用视频是否使用音频
// 对于视频就可以按我们刚才所说的做一些限制
var constraints = { // 表示同时采集视频金和音频
video : {
width: 640, // 宽带
height: 480, // 高度
frameRate:15, // 帧率
facingMode: 'enviroment', // 设置为后置摄像头
deviceId : deviceId ? deviceId : undefined // 如果deviceId不为空直接设置值,如果为空就是undefined
},
audio : {
noiseSuppression: true, // 降噪
echoCancellation: true // 回音消除
},
}
// 从指定的设备中去采集数据
navigator.mediaDevices.getUserMedia(constraints)
.then(gotMediaStream) // 使用Promise串联的方式,获取流成功了
.then(gotDevices)
.catch(handleError);
}
}
start();
// 当我选择摄像头的时候,他可以触发一个事件,
// 当我调用start之后我要改变constraints
videoSource.onchange = start;