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

使用video_stream包启动Flutter相机触发运行时错误致应用崩溃

iOS Flutter直播功能启动相机预览时SIGABRT错误解决方案求助

我在实现Flutter直播功能时,点击相机按钮启动Camera Preview界面触发运行时错误,报错信息如下:

[VERBOSE-3:platform_message_handler_ios.mm(106)] Check failed: task_runners_.GetPlatformTaskRunner()->RunsTasksOnCurrentThread().

  • thread #6, queue = 'com.marshalltechnology.video_stream.dispatchqueue', stop reason = signal SIGABRT
    frame #0: 0x00000001d9339b38 libsystem_kernel.dylib__pthread_kill + 8 libsystem_kernel.dylib__pthread_kill:
    -> 0x1d9339b38 <+8>: b.lo 0x1d9339b58 ; <+40>
    0x1d9339b3c <+12>: pacibsp
    0x1d9339b40 <+16>: stp x29, x30, [sp, #-0x10]!
    0x1d9339b44 <+20>: mov x29, sp
    Target 0: (Runner) stopped.
    Lost connection to device.

怀疑是video_stream包的问题,当前使用依赖:permission_handler、video_stream,该功能旧版本构建可正常运行。

环境信息:

Flutter stable 3.0.5,Xcode 13.4.1


代码片段

Main.dart

void main() async { 
  WidgetsFlutterBinding.ensureInitialized();
  
  // 获取可用设备相机
  try {
    cameras = await availableCameras();
    } on CameraException catch (e) {
    debugPrint(e.toString());
  }
  runApp(const MyApp());
}

Livestream.dart

class LivestreamScreen extends StatefulWidget {

  @override
  State<LivestreamScreen> createState() => _LivestreamScreenState();
}

class _LivestreamScreenState extends State<LivestreamScreen> {
  CameraController? _controller;

  bool _isCameraPermissionGranted = false;
  bool _isCameraInitialized = false;
  bool _isInitializing = false;
  bool _isStreaming = false;
  bool _isFrontCamSelected = true;

 _getPermissionStatus() async {
 // 请求相机权限,授权后初始化相机
 await Permission.camera.request();
 var status = await Permission.camera.status;

 if (status.isGranted) {
    log('Camera Permission: GRANTED');
    setState(() {
     _isCameraPermissionGranted = true;
    });

  // 设置并初始化前置摄像头
  // camera[0]: 后置摄像头
  // camera[1]: 前置摄像头
  _onNewCameraSelected(cameras[1]);
} else {
  log('Camera Permission: DENIED');
    }
} 

void _onNewCameraSelected(CameraDescription cameraDescription) async {
// 初始化新相机
setState(() {
  _isCameraInitialized = false;
});

final previousCameraController = _controller;

final CameraController cameraController = CameraController(
  cameraDescription,
  ResolutionPreset.high,
  enableAudio: true,
  androidUseOpenGL: true,
);

await previousCameraController?.dispose();

if (mounted) {
setState(() {
    _controller = cameraController;
  });
}

_controller!.addListener(() {
  _isCameraInitialized = _controller!.value.isInitialized;

  if (mounted) setState(() {});
});

try {
  await cameraController.initialize();
} on CameraException catch (e) {
  log('Error initializing camera: $e');
}

    if (mounted) {
      setState(() {
      _isCameraInitialized = _controller!.value.isInitialized;
     });
   }
 } 

@override
  void didChangeAppLifecycleState(AppLifecycleState state) {
    // 应用状态变更时未完成初始化则直接返回
    if (_controller == null || !_controller!.value.isInitialized) {
      return;
    }
    if (state == AppLifecycleState.inactive) {
      _controller?.dispose();
    } else if (state == AppLifecycleState.resumed) {
      if (_controller != null) {
        _onNewCameraSelected(_controller!.description!);
      }
    }
  }   
@override
  void initState() {
    _getPermissionStatus();

    super.initState();
  }

  @override
      void dispose() {
        _controller?.dispose();

        super.dispose();
      }

 
@override
Widget build (BuildContext context) {
 return Scaffold(
appBar: AppBar(
actions: [
IconButton(
    onPressed: () {
       _isFrontCamSelected
           ? _onNewCameraSelected(cameras[0])
           : _onNewCameraSelected(cameras[1]);

       setState(() {
         _isFrontCamSelected = !_isFrontCamSelected;
       });
     },
    icon: Icon(Icons.flip_camera_ios),
    ),
],
),
body: Stack(
  children: [
     _isCameraPermissionGranted
        ? _isCameraInitialized
          ? Stack(
             children: [
              ClipRRect( 
                child: AspectRatio(
                  aspectRatio: _controller!.value.aspectRatio,
                  child: CameraPreview(_controller!),
                ),
               ),
            // UI body code
           ],
          )
          : Center(
              child: CircularProgressIndicator(),
            )
        : Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: [
        Text(
          'Permission denied',
        ),
       ElevatedButton(
         onPressed: () {
          _getPermissionStatus();
         },
         child: Text(
           'Give permission'
           ),
          ),
         ],
        ),
      ],
     ),
    );   
   } 
}

可能的解决方案

  1. 确保相机初始化在主线程执行
    错误提示核心是线程检查失败,说明相机初始化操作可能在非主线程执行。修改_onNewCameraSelected中的初始化逻辑,将其包裹在主线程回调中:
try {
  await WidgetsBinding.instance.addPostFrameCallback((_) async {
    await cameraController.initialize();
  });
} on CameraException catch (e) {
  log('Error initializing camera: $e');
}
  1. 回退video_stream包版本
    既然旧版本能正常运行,在pubspec.yaml中指定之前可用的版本号:
dependencies:
  video_stream: ^0.4.0 # 替换为你之前正常运行的版本
  1. 优化相机生命周期管理
    调整didChangeAppLifecycleState方法,避免应用恢复时重复销毁和初始化相机:
@override
void didChangeAppLifecycleState(AppLifecycleState state) {
  if (_controller == null) return;
  
  if (state == AppLifecycleState.inactive) {
    _controller?.pausePreview();
  } else if (state == AppLifecycleState.resumed) {
    if (_controller != null && !_controller!.value.isInitialized) {
      _onNewCameraSelected(_controller!.description!);
    } else {
      _controller?.resumePreview();
    }
  }
}
  1. 清理构建缓存
  • 执行flutter clean清除Flutter缓存
  • 删除iOS目录下的Pods文件夹和Podfile.lock,运行pod install重新安装依赖
  • 重启Xcode和Flutter项目

内容的提问来源于stack exchange,提问作者Zechst

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.24 21:39:18