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

使用Flutter WebRTC切换前后置摄像头失败,求助解决方案

Flutter WebRTC 摄像头切换失败问题修复

问题分析

你遇到的两个核心错误原因:

  1. 并发修改异常:遍历videoStream.getVideoTracks()的同时调用removeTrack,直接修改了正在迭代的列表,触发Concurrent modification during iteration报错。
  2. 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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.25 07:06:34