卧式纯绿 2024-04-15 21:26 采纳率: 62.1%
浏览 1
已结题

安卓开发视频抽帧检测出错

安卓开发视频抽帧检测后渲染展示出错
以下是对从相册获取的视频uri进行处理的代码

img


各位帮我看看是哪里出现了问题 应该如何更改 每次一装到手机上就闪退

  • 写回答

6条回答 默认 最新

  • 专家-赤兔[在线] 优质创作者: 编程框架技术领域 2024-04-15 21:27
    关注

    引自免费微信小程序:皆我百晓生

    根据您提供的代码片段,看起来您正在尝试从视频中抽取帧并在每34毫秒的时间点执行目标检测。然后将检测结果应用到Bitmap上并将其显示在ImageView中。然而,由于没有看到完整的堆栈跟踪或错误信息,我只能根据代码本身推测可能的问题。

    以下是可能导致闪退的一些常见原因以及相应的建议:

    1. 权限:确保您的应用程序具有读取外部存储(READ_EXTERNAL_STORAGE)的权限,以便可以访问视频文件。
    2. 资源管理:确保正确地管理和释放资源,特别是MediaMetadataRetriever对象,以防止内存泄漏。您已经尝试在循环结束后释放资源,但这是一个在循环内部捕获异常的好做法。
    3. 目标检测库初始化:确保YoLoV5Ncnn类和相关的库已正确导入和初始化。检查是否有任何缺失的依赖项或版本不兼容问题。
    4. 多线程:确保在主线程中更新UI,因为Android不允许在非UI线程中更新UI组件。您已经在runOnUiThread中更新了ImageView,这很好。
    5. 空指针异常:确保在处理BitmapYoLoV5Ncnn等对象时,检查它们是否为null,以防止空指针异常。
    6. 设备兼容性:某些设备可能不支持特定的目标检测库或特定的GPU设置。检查设备兼容性,并相应调整代码。

    为了更好地帮助您定位问题,提供详细的错误日志或崩溃报告会很有帮助。但是,您可以先尝试以下优化代码:

    public class YourActivity extends AppCompatActivity {
    
        private MediaMetadataRetriever retriever;
        private ImageView imageView;
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_your_activity);
    
            retriever = new MediaMetadataRetriever();
            imageView = findViewById(R.id.imageView);
    
            // Add a try-catch block to handle exceptions during initialization
            try {
                retriever.setDataSource(this, Uri.parse("your_video_uri_here"));
            } catch (IOException e) {
                Log.e("YourActivity", "Error setting data source for MediaMetadataRetriever", e);
                return;
            }
    
            String timeFormat = retriever.extractMetadata(MediaMetadataRetriever.METADATA_KEY_DURATION);
            long videoLengthInMills = Long.parseLong(timeFormat) * 1000;
            long frameInterval = 34000L;
    
            new Thread(() -> {
                try {
                    processVideo(videoLengthInMills, frameInterval);
                } finally {
                    // Always release resources in the end
                    retriever.release();
                }
            }).start();
        }
    
        private void processVideo(long videoLengthInMills, long frameInterval) {
            for (long atTime = 0; atTime < videoLengthInMills; atTime += frameInterval) {
                Bitmap bitmap1 = retriever.getFrameAtTime(atTime * 1000, MediaMetadataRetriever.OPTION_CLOSEST);
                if (bitmap1 != null) {
                    YoLoV5Ncnn.obj[] objects = yoLov5ncnn.Detect(bitmap1, true /* use-gpu */);
                    Bitmap updatedBitmap = performObjectDetection(objects);
                    runOnUiThread(() -> {
                        imageView.setImageBitmap(updatedBitmap);
                    });
                }
            }
        }
    
        private Bitmap performObjectDetection(YoLoV5Ncnn.obj[] objects) {
            // Implement your object detection logic here
            // ...
        }
    }
    

    在这个优化过的版本中,我做了以下改进:

    • MediaMetadataRetrieverImageView作为活动成员变量,以便在整个生命周期内使用。
    • onCreate()方法中添加了一个异常处理块来处理setDataSource()可能出现的IOException
    • 使用finally块确保在循环结束时总是释放资源。
    • 删除了不必要的大括号。

    请替换"your_video_uri_here"为实际的视频URI,并确保在AndroidManifest.xml中添加了所需的权限:

    <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
    

    如果问题仍然存在,请分享更详细的错误日志或崩溃报告,以便我能进一步分析。

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论 编辑记录
查看更多回答(5条)

报告相同问题?

问题事件

  • 系统已结题 8月17日
  • 已采纳回答 8月9日
  • 创建了问题 4月15日