背景
用户摄像头、麦克风损害,或者是用户禁止使用麦克风、摄像头,会出现本地流创建失败的情况,原因是因为创建本地流的时候,声音和视频都设置的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') {// 一直pendingthis.$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("没有找到可用摄像头/麦克风");}},
