使用Flutter WebRTC切换前后置摄像头失败,求助解决方案
Flutter WebRTC 摄像头切换失败问题修复
问题分析
你遇到的两个核心错误原因:
- 并发修改异常:遍历
videoStream.getVideoTracks()的同时调用removeTrack,直接修改了正在迭代的列表,触发Concurrent modification during iteration报错。 - Track为空错误:重复执行轨道停止和移除操作,第二次处理时轨道已被移除,导致
Track is nil异常。
修复后的代码
// 先获取当前视频轨道的副本,避免迭代时修改原列表 final currentTracks = List.from(videoStream!.getVideoTracks()); // 停止并移除所有当前视频轨道 for (final track in currentTracks) { try { await track.stop(); await videoStream!.removeTrack(track, removeFromNative: true); } catch (e) { if (kDebugMode) { print('移除轨道失败: $e'); } } } // 请求新的摄像头流 final mediaConstraints = { 'audio': false, 'video': { 'deviceId': videoInputDeviceId, // 可按需添加分辨率约束 // 'width': {'ideal': 1280}, // 'height': {'ideal': 720}, } }; final newStream = await navigator.mediaDevices.getUserMedia(mediaConstraints); // 直接替换整个流(更简洁,避免旧流残留问题) videoStream = newStream; // 若需保留原流其他轨道(如音频),可改用以下方式: // final newVideoTrack = newStream.getVideoTracks().first; // await videoStream!.addTrack(newVideoTrack, addToNative: true);
关键修改点
- 避免并发修改:用
List.from()创建轨道列表副本,遍历副本而非原列表,防止迭代时修改原集合引发异常。 - 移除重复操作:只执行一次轨道停止和移除,避免重复操作导致的空轨道错误。
- 推荐替换整个流:直接将
videoStream替换为新获取的流,比添加轨道到旧流更可靠,减少状态不一致问题。
内容的提问来源于stack exchange,提问作者Oliver Dixon
相关产品推荐
相关产品推荐

