Flutter video_player iOS调试报视频加载失败Operation Stopped错误
问题场景
使用Flutter官方video_player包开发视频播放功能时,仅iOS端调试运行时抛出报错,检索通用解决方案未匹配当前业务场景。
报错信息如下:
Unhandled Exception: PlatformException(VideoError, Failed to load video: Operation Stopped, null, null)
报错原因
该报错为iOS平台专属触发问题,核心诱因共3点:
- 控制器生命周期处理不规范:
initState中直接链式调用初始化、播放逻辑,未等待初始化完成就触发播放,且build方法在控制器未完成初始化时直接读取controller.value.aspectRatio属性,造成iOS原生播放器组件生命周期冲突,直接中断资源加载抛出错误。 - 网络权限拦截:如果视频资源地址为HTTP非HTTPS协议,iOS系统默认ATS安全策略会拦截非加密网络请求,直接终止视频加载流程。
- 资源未释放:代码未实现
dispose回调释放播放器控制器实例,反复热重载、进出页面时残留的控制器实例会占用播放资源,中断新的加载任务。
修复方案
1. 重构播放页代码逻辑
补充初始化状态标记、空值兜底、异常捕获、页面销毁资源释放逻辑,确保控制器初始化完成后再渲染播放器组件、触发播放,修复后完整代码如下:
class MateriVidioDetailView extends StatefulWidget { final ListVideo? video; const MateriVidioDetailView({Key? key, this.video}) : super(key: key); @override State<MateriVidioDetailView> createState() => _MateriVidioDetailViewState(); } class _MateriVidioDetailViewState extends State<MateriVidioDetailView> { late VideoPlayerController controller; // 初始化完成标记 bool _controllerInitialized = false; @override void initState() { super.initState(); // 兜底视频链接空值场景 if (widget.video?.linkVideo == null) return; controller = VideoPlayerController.network(widget.video!.linkVideo!); controller.initialize().then((_) { // 页面已销毁时不再执行状态更新 if (!mounted) return; setState(() { _controllerInitialized = true; }); controller.play(); }).catchError((err) { debugPrint("视频初始化异常: $err"); }); } @override void dispose() { // 页面销毁时释放播放器资源 controller.dispose(); super.dispose(); } @override Widget build(BuildContext context) { return Scaffold( appBar: customAppBar(title: 'Materi Vidio'), body: Padding( padding: const EdgeInsets.all(16.0), child: ListView( children: [ Text( widget.video?.videoInfo?.name?.toString() ?? "", style: regheadingStyle, ), Text(widget.video?.videoInfo?.description?.toString() ?? ""), // 初始化完成前展示加载占位,避免读取未初始化的控制器属性 _controllerInitialized ? Container( decoration: BoxDecoration(border: Border.all()), child: AspectRatio( aspectRatio: controller.value.aspectRatio, child: ClipRRect( borderRadius: BorderRadius.circular(10.0), child: VideoPlayer(controller) ), ), ) : const SizedBox( height: 220, child: Center(child: CircularProgressIndicator()), ) ], ), ), ); } }
2. 配置iOS端网络权限
打开iOS项目路径下的ios/Runner/Info.plist文件,在根<dict>节点内(即</dict>闭合标签前)添加ATS配置,允许HTTP资源加载,若所有视频资源均为HTTPS协议可跳过该步:
<key>NSAppTransportSecurity</key> <dict> <key>NSAllowsArbitraryLoads</key> <true/> </dict>
3. 清理缓存重新运行
Flutter热重载不会重置iOS原生端播放器状态,修改完上述配置后,执行flutter clean清理项目缓存,重新编译运行即可,不要直接通过热重载验证修复效果。
内容的提问来源于stack exchange,提问作者Thufail Adib Al-Mutawakkil
相关产品推荐
相关产品推荐

