使用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' ), ), ], ), ], ), ); } }
可能的解决方案
- 确保相机初始化在主线程执行
错误提示核心是线程检查失败,说明相机初始化操作可能在非主线程执行。修改_onNewCameraSelected中的初始化逻辑,将其包裹在主线程回调中:
try { await WidgetsBinding.instance.addPostFrameCallback((_) async { await cameraController.initialize(); }); } on CameraException catch (e) { log('Error initializing camera: $e'); }
- 回退video_stream包版本
既然旧版本能正常运行,在pubspec.yaml中指定之前可用的版本号:
dependencies: video_stream: ^0.4.0 # 替换为你之前正常运行的版本
- 优化相机生命周期管理
调整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(); } } }
- 清理构建缓存
- 执行
flutter clean清除Flutter缓存 - 删除iOS目录下的
Pods文件夹和Podfile.lock,运行pod install重新安装依赖 - 重启Xcode和Flutter项目
内容的提问来源于stack exchange,提问作者Zechst
相关产品推荐
相关产品推荐

