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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.29 11:15:17