Flutter video_compress压缩视频报Null check operator空值异常
Unhandled Exception: Null check operator used on a null value
在iPhone 12 Pro上测试应用、尝试执行视频压缩操作时遇到上述报错,先后切换以下版本的video_compress依赖包均未解决问题:
- 3.1.1
- 3.1.0
- 3.0.0
开发与运行环境
- 开发电脑:Macbook Pro M1 13(系统版本Monterey 12.4)
- 测试手机:iPhone 12 Pro(系统版本15.5)
- 开发IDE:Visual Studio Code
- Flutter版本:3.0.3
相关实现代码
print("before compression"); final info = await VideoCompress.compressVideo( widget.filePath, quality: VideoQuality.MediumQuality, deleteOrigin: false, includeAudio: false, ); print("after compression"); setState(() { compressedInfo = info!.path!; // Dart 提示此处必须加空检查否则编译不通过 print("info set"); });
报错日志
flutter: before compression flutter: VideoCompress: You can try to subscribe to the flutter: compressProgress$ stream to know the compressing state. [VERBOSE-2:ui_dart_state.cc(198)] Unhandled Exception: Null check operator used on a null value #0 new MediaInfo.fromJson (package:video_compress/src/media/media_info.dart:43:21) #1 Compress.compressVideo (package:video_compress/src/video_compress/video_compressor.dart:154:24) <asynchronous suspension> #2 _VideoPageState.build.<anonymous closure> (package:apiir_bikefit/pages/record/video_page.dart:65:28) <asynchronous suspension>
已做排查
- 最初怀疑是压缩返回值
info的处理逻辑有误,或是async/await异步实现写法存在问题,尝试多种调整方案、查阅公开资料后始终无法定位问题。 - 日志中
print("after compression");始终未打印,判断异常在compressVideo方法内部执行时就已抛出。 - 核心疑问:该问题是
video_compress包本身存在的bug,还是代码中存在未注意到的疏漏?
问题根因与解决方案
该问题不属于业务代码写法错误,是video_compress 3.x版本在iOS端的已知实现缺陷。
从报错堆栈可定位异常抛出点为插件内部的MediaInfo.fromJson构造方法(第43行):iOS端完成压缩流程后,会将结果序列化为JSON回传给Dart层,当JSON中缺少插件预期的非空字段时,插件内部直接对null值使用了空检查操作符!,直接抛出异常,异常发生在compressVideo方法内部,因此业务代码中print("after compression")不会执行,和你自己写的info!.path!空判断逻辑无关。
这个缺陷的触发条件就是你配置的includeAudio: false参数:该参数在iOS端生效时,原生端不会处理音轨相关元数据,回传的JSON中自然缺少音频对应的字段,但Dart层的MediaInfo模型将音频相关元数据字段定义为了非空类型,转模型时找不到对应字段就会触发空检查报错。你切换的3.0.0、3.1.0、3.1.1三个版本都没有修复这个问题,所以换版本无法解决。
可落地的修复方案
- 最快绕过方案:将
includeAudio参数改为true,即可正常走完压缩流程。如果最终输出不需要音频,可以在压缩完成后额外做一步音视频分离处理,不影响核心压缩能力。 - 源码修改方案:如果需要在压缩阶段直接剔除音频,可以修改本地Pub缓存中的插件源码:找到
video_compress包下lib/src/media/media_info.dart文件的fromJson构造方法,将音频相关的元数据字段(如音轨标题、作者信息字段)从非空类型改为可空类型,移除对应字段上的强制空检查!即可。 - 依赖替换方案:无需手动改源码,直接在
pubspec.yaml中引用社区已修复该问题的Git分叉版本作为依赖即可。
补充提示:后续拿到压缩结果时,建议先对info做非空判断再取path属性,避免压缩失败时info为null触发空异常,不过本次报错和这段逻辑无关。
内容的提问来源于stack exchange,提问作者Henrik
相关产品推荐
相关产品推荐

