You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.17 00:15:06