react-native-webrtc iOS端视频通话结束后麦克风未关闭问题咨询
问题根因分析
- 音频升级视频场景下旧纯音频流未释放:
getVideoStream方法中仅将旧localStream从原对等连接中移除,未主动停止旧流上的音频轨道,这部分被遗弃的音频轨持续持有麦克风硬件资源。后续挂断操作仅停止了state中存储的新音视频流的轨道,旧流的轨道永远不会被触发停止,导致系统麦克风指示器常亮。 - 升级视频时旧对等连接未销毁:每次调用
startStream都会新建RTCPeerConnection实例,旧实例未调用close()方法,仍然持有旧音频流的引用,进一步阻碍资源释放。 - 挂断时资源释放顺序错误:当前逻辑先停止本地流轨道,再操作对等连接,正确顺序应先移除对等连接中的流、关闭对等连接,再停止轨道,避免对等连接持有轨道引用导致停止操作不生效。
可行解决方案
1. 修复升级视频时的旧资源释放逻辑
修改getVideoStream方法,在获取新的音视频流之前先释放旧的流和对等连接资源:
getVideoStream() { // 新增:停止旧本地流所有轨道 if (this.state.localStream) { this.state.localStream.getTracks().forEach(track => track.stop()); } // 新增:关闭旧对等连接 if (this.state.peerConn) { this.state.peerConn.removeStream(this.state.localStream); this.state.peerConn.close(); } InCallManager.setSpeakerphoneOn(false); InCallManager.setMicrophoneMute(false); // 原有剩余逻辑保持不变 mediaDevices.enumerateDevices().then((sourceInfos) => { // ...原有代码 }); }
2. 调整挂断时的资源释放顺序
先操作对等连接,再停止本地流轨道,最后清空所有资源引用:
if (this.state.peerConn) { this.state.peerConn.removeStream(this.state.localStream); this.state.peerConn.close(); if (!this.state.callRatingSubmitted && this.state.remoteStream) { this._handleCallFeedbackModal(true); } } if (this.state.localStream) { const tracks = this.state.localStream.getTracks(); tracks.forEach((track) => { track.stop(); }); } // 新增:清空所有流和连接的引用,避免残留 this.setState({ localStream: null, peerConn: null, remoteStream: null })
3. InCallManager适配(可选)
如果需要调用InCallManager.stop()释放音频会话,需要在第二次通话初始化时主动调用InCallManager.start({media: 'audio'})重新初始化音频会话,即可解决第二次通话麦克风无法启用的问题。
优化建议(可选)
无需每次升级视频都重建对等连接和重新获取全量流,可以直接调用RTCPeerConnection的addTrack/removeTrack方法动态添加视频轨道,资源占用更低,也能从根源避免此类资源泄漏问题。
内容的提问来源于stack exchange,提问作者Avolox
相关产品推荐
相关产品推荐

