Android Studio中使用VideoCapture无法打开视频的问题
VideoCapture无法打开Android资源路径的视频(VideoView可正常播放)
我尝试使用OpenCV的VideoCapture打开raw目录下的AVI视频,但一直失败,已经测试了不同的AVI编码格式。目前的情况是:
- 视频路径确认有效,因为Android原生的
VideoView可以正常播放该路径的视频 - 点击按钮时Toast显示“isn't opened false”,说明
VideoCapture既没打开成功,grab()也返回了false
我的代码如下:
public void OnBtnStart(View view) { String videopath = "android.resource://com.example.msi.mhltryagain/"+R.raw.testmjpeg; VideoView videoview = (android.widget.VideoView) findViewById(R.id.VideoView); Uri uri = Uri.parse("android.resource://com.example.msi.mhltryagain/"+R.raw.test); videoview.setVideoURI(uri); videoview.start(); VideoCapture cap = new VideoCapture(videopath); boolean capGrab = cap.grab(); if (cap.isOpened()){ Toast.makeText(this,"is opened",Toast.LENGTH_SHORT).show(); }else{ Toast.makeText(this,"isn't opened"+capGrab,Toast.LENGTH_SHORT).show(); } }
请问为什么VideoCapture无法打开这个视频?
问题原因分析
核心问题在于OpenCV的VideoCapture并不支持直接解析Android的android.resource://格式URI——这是Android系统特有的资源定位方式,只有Android原生组件(比如VideoView)能识别并处理它,而OpenCV底层依赖的多媒体处理库(比如FFmpeg)只支持标准的文件系统路径,无法识别这种特殊URI。
解决方法:将资源文件复制到本地存储后再读取
你需要先把raw目录下的视频文件复制到应用的私有存储目录,然后用这个本地文件路径来初始化VideoCapture,具体步骤如下:
1. 编写文件复制方法
private String copyRawVideoToLocal(int rawResId, String fileName) throws IOException { File outputDir = getFilesDir(); File outputFile = new File(outputDir, fileName); if (outputFile.exists()) { return outputFile.getAbsolutePath(); } InputStream inputStream = getResources().openRawResource(rawResId); FileOutputStream outputStream = new FileOutputStream(outputFile); byte[] buffer = new byte[1024]; int length; while ((length = inputStream.read(buffer)) > 0) { outputStream.write(buffer, 0, length); } inputStream.close(); outputStream.close(); return outputFile.getAbsolutePath(); }
2. 修改原代码使用本地路径
public void OnBtnStart(View view) { // 先播放视频(保留原VideoView逻辑) Uri uri = Uri.parse("android.resource://com.example.msi.mhltryagain/"+R.raw.test); VideoView videoview = (android.widget.VideoView) findViewById(R.id.VideoView); videoview.setVideoURI(uri); videoview.start(); // 处理VideoCapture部分 try { // 复制raw视频到本地存储 String localVideoPath = copyRawVideoToLocal(R.raw.testmjpeg, "testmjpeg.avi"); VideoCapture cap = new VideoCapture(localVideoPath); boolean capGrab = cap.grab(); if (cap.isOpened()){ Toast.makeText(this,"is opened",Toast.LENGTH_SHORT).show(); }else{ Toast.makeText(this,"isn't opened"+capGrab,Toast.LENGTH_SHORT).show(); } } catch (IOException e) { e.printStackTrace(); Toast.makeText(this,"文件复制失败",Toast.LENGTH_SHORT).show(); } }
额外注意事项
- 确认你的OpenCV版本支持目标视频的编码格式:虽然你已经测试了不同编码,但如果OpenCV编译时没有包含对应编码的解码器,还是可能无法打开视频。可以尝试用最基础的MJPEG或H.264编码的AVI视频测试。
- 权限问题:如果是Android 10及以上,不需要额外的存储权限,因为我们是复制到应用的私有目录,只有应用本身可以访问。
内容的提问来源于stack exchange,提问作者Filip
相关产品推荐
相关产品推荐

