背景
用户摄像头、麦克风损害,或者是用户禁止使用麦克风、摄像头,会出现本地流创建失败的情况,原因是因为创建本地流的时候,声音和视频都设置的true,在初始化的时候,就会找不到可用设备而走error回调,导致只走了catch方法
分析
创建本地流方法,默认设置的都是true,导致腾讯云去取摄像头和麦克风的时候没取到,走了error回调
this.localStream = TRTC.createStream({
audio: true, // 采集麦克风
video: true, // 采集摄像头
userId: this.localUserID
});
解决
需要知道本地的麦克风或者摄像头是否可以使用,如果可以的话,设置成true,如果不能使用,则设置成false
navigator.mediaDevices.enumerateDevices() 获取媒体设备 |
---|
MediaDevices 的方法 enumerateDevices() 请求一个可用的媒体输入和输出设备的列表,例如麦克风,摄像机,耳机设备等。 返回的 Promise 完成时,会带有一个描述设备的 MediaDeviceInfo 的数组
所以根据返回的数据数组是否大于0,就知道是否有可用的设备
let list = await navigator.mediaDevices.enumerateDevices();
if (list.length > 0) {}
如果小于0,则不用继续,提醒用户没有可用设备即可,如果有可用设备,则需要判断一下,可用的是哪些设备,如果可用设备中有摄像头,则初始化video:true,如果有麦克风可用,则audio:true,反之则为false,这样就能确保初始化是正常的
// 检查音频设备方法
checkAudio() {
let p = new Promise((resolve, reject) => {
navigator.mediaDevices.getUserMedia({
audio: true
}).then(() => {
resolve(true);
}).catch(error => {
console.log(error);
reject(new Error('audio'));
});
});
return p;
}
// 调用检查可用设备方法的另外一个方法中
try {
let audioPromise = await this.checkAudio();
audioFlag = 'canUse';
} catch (error) {
console.log(error);
audioFlag = 'noUse';
}
摄像头设备检查如上相同
具体代码如下:
async createLocalStream() {
// 检查设备
let audioFlag = '-1';
let videoFlag = '-1';
let list = await navigator.mediaDevices.enumerateDevices();
if (list.length > 0) {
try {
let audioPromise = await this.checkAudio();
audioFlag = 'canUse';
} catch (error) {
console.log(error);
audioFlag = 'noUse';
}
try {
let videoPromise = await this.checkVideo();
videoFlag = 'canUse';
} catch (error) {
console.log(error);
videoFlag = 'noUse';
}
console.warn(audioFlag, videoFlag)
if (audioFlag === '-1' && videoFlag === '-1') {
// 一直pending
this.$message.error("请授权摄像头/麦克风访问权限,否则无法进行音视频通话");
} else if (videoFlag === 'canUse' || audioFlag === 'canUse') {
let auFlag = (audioFlag === 'canUse');
let viFlag = (videoFlag === 'canUse');
this.createLocalStreamMethod(auFlag, viFlag);
} else {
this.$message.error("没有找到可用摄像头/麦克风");
}
} else {
this.$message.error("没有找到可用摄像头/麦克风");
}
},