Angular网页应用切换麦克风出现NotReadableError错误如何解决
麦克风切换并发限制问题解决方案
解决这个问题的核心逻辑是:申请新设备权限前,主动停止旧媒体轨道的占用,释放硬件资源,同时修正原有代码中的逻辑错误,具体操作如下:
- 第一步:组件层面存储当前正在使用的音频/视频轨道引用,方便切换前销毁
你需要在当前业务组件中新增变量存储在用轨道,示例:
// 组件内新增变量,存储当前正在使用的音频轨道 private currentActiveAudioTrack: MediaStreamTrack | null = null; // 如果需要同时处理摄像头,也可以存储视频轨道或完整的MediaStream实例 private currentLocalStream: MediaStream | null = null;
- 第二步:申请新设备前,先停止旧轨道的运行,释放硬件资源
调用媒体轨道的stop()方法即可停止设备占用,浏览器的权限激活状态也会同步更新。 - 第三步:修正原有代码的逻辑错误:原有代码中从新的媒体流拿了视频轨去替换音频位,完全不符合切换麦克风的需求,需要改为获取音频轨。
- 第四步:切换完成后更新存储的轨道引用,方便下一次切换时销毁。
修正后的完整代码示例
async onMicrophoneSelected(event: any) { const selectedDeviceId = event?.value; if (!selectedDeviceId) return; // 1. 先销毁之前正在使用的音频轨道,释放麦克风占用 if (this.currentActiveAudioTrack) { this.currentActiveAudioTrack.stop(); this.currentActiveAudioTrack = null; } // 如果有旧的完整流,也可以统一停止所有音频轨 if (this.currentLocalStream) { this.currentLocalStream.getAudioTracks().forEach(track => track.stop()); } let newAudioTrackInfo: MediaDeviceInfo | undefined; // 2. 匹配目标麦克风设备 const devices = await navigator.mediaDevices.enumerateDevices(); newAudioTrackInfo = devices.find(device => device.kind === 'audioinput' && device.deviceId === selectedDeviceId ); if (!newAudioTrackInfo) return; // 3. 单独申请音频流即可,不需要重复申请视频流,避免摄像头重启 const audioConstraints = { audio: { deviceId: { exact: newAudioTrackInfo.deviceId } }, video: false // 不需要视频的话这里设为false,要保留视频的话也可以复用原有视频流,不用重新申请 }; const newAudioStream = await navigator.mediaDevices.getUserMedia(audioConstraints); const newAudioTrack = newAudioStream.getAudioTracks()[0]; // 存储新的轨道引用,下次切换时销毁 this.currentActiveAudioTrack = newAudioTrack; // 4. 替换发布流的音频轨道 await this.localUsersService .getWebcamPublisher() .replaceTrack(newAudioTrack); this.publishAudio(true); this.hasAudioDevices = true; }
额外优化说明
如果你不想在切换麦克风的时候影响摄像头的运行,可以不用重新申请视频流,仅单独申请音频流替换即可,完全不需要动原有视频轨道,用户感知会更流畅。
内容的提问来源于stack exchange,提问作者richardrobu
相关产品推荐
相关产品推荐

