Android端OpenCV VideoWriter初始化失败 isOpened始终返回false
Android端OpenCV VideoWriter初始化失败(isOpened()返回false)解决方案
按优先级逐一排查以下问题即可解决:
- 存储权限与路径问题
直接写入存储根目录/storage/emulated/0/在高版本Android系统会被权限拦截:- 若targetSdk >=29,可临时在
AndroidManifest.xml的application标签下添加android:requestLegacyExternalStorage="true"绕过分区存储限制,长期适配建议将输出路径改为应用私有目录,该目录无需额外存储权限即可读写:String outputPath = getExternalFilesDir(null).getAbsolutePath() + "/test.avi"; - 对应版本动态权限必须申请到位:Android 12及以下申请
WRITE_EXTERNAL_STORAGE,Android 13及以上申请对应媒体权限,仅在Manifest声明权限不做动态申请无效。
- 若targetSdk >=29,可临时在
- FOURCC编码参数错误
代码中自定义的forcc变量大概率未按规范生成,且设备不支持对应编码:- 必须通过
VideoWriter.fourcc()方法生成编码值,Android端兼容性最高的编码组合为:MJPG编码配avi容器、MP4V编码配mp4容器,示例:int fourcc = VideoWriter.fourcc('M', 'J', 'P', 'G'); - 禁止使用未经验证的私有编码值,编码与文件后缀不匹配会直接导致初始化失败。
- 必须通过
- OpenCV库未正确初始化
调用VideoWriter相关逻辑前必须完成OpenCV的native库加载,建议在页面onCreate生命周期优先执行初始化:
打包时要确认所有目标ABI架构对应的OpenCV so库(含编解码相关依赖)都已被正确打包进APK,缺失对应架构so会导致所有native方法调用异常。// 静态集成OpenCV时使用initDebug即可,无需用户额外安装OpenCV Manager if (!OpenCVLoader.initDebug()) { // 此处处理初始化失败逻辑,比如so库缺失提示 } - 传入参数不合法
- VideoWriter要求传入的视频宽高必须为偶数,你当前使用的640*480符合要求,若后续修改分辨率注意不要传入奇数尺寸。
- 最后一个
isColor参数需要和后续写入的Mat格式匹配:写入三通道BGR彩色图传true,写入单通道灰度图传false,格式不匹配也会导致初始化失败。 - 帧率参数不要小于1,你当前传入的20.0为合法值。
修正后的可运行示例代码
private void initVideoWriter() { // 优先初始化OpenCV OpenCVLoader.initDebug(); // 使用应用私有目录作为输出路径 String outputPath = getExternalFilesDir(null).getAbsolutePath() + "/test.avi"; int fourcc = VideoWriter.fourcc('M', 'J', 'P', 'G'); VideoWriter videoWriter = new VideoWriter(); boolean isOpenSuccess = videoWriter.open(outputPath, fourcc, 20.0, new Size(640, 480), true); if (isOpenSuccess && videoWriter.isOpened()) { Toast.makeText(this, "VideoWriter初始化成功", Toast.LENGTH_SHORT).show(); // 后续执行视频帧写入逻辑 videoWriter.write(mat) } else { Toast.makeText(this, "VideoWriter初始化失败", Toast.LENGTH_SHORT).show(); } // 写入完成后记得释放资源 // videoWriter.release(); }
内容的提问来源于stack exchange,提问作者hamza janjua
相关产品推荐
相关产品推荐

