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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.28 07:11:30