安卓开发视频抽帧展示出错
想做一个从相册选择视频然后进行抽帧检测处理的app的时候,发现一直闪退,然后就试着只抽取了第一帧的bitmap图像并进行展示,然后就发现仅仅抽取一帧运行时就会直接闪退,想问问各位代码哪里有问题:
安卓开发视频抽帧出现问题
- 写回答
- 好问题 0 提建议
- 追加酬金
- 关注问题
- 邀请回答
-
4条回答 默认 最新
关注 引自免费微信小程序:皆我百晓生
在您的代码中,有几个可能的问题导致应用闪退。以下是针对您提供的代码段的修改建议:
首先,确保在尝试访问媒体文件之前已经获取了必要的权限。在AndroidManifest.xml中添加以下权限:
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" /> <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
其次,在Java代码中检查是否已授予存储权限,并请求它们,如果需要的话。您可以使用下面的方法:
// 检查读写权限 if (ContextCompat.checkSelfPermission(this, Manifest.permission.READ_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED || ContextCompat.checkSelfPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) { // 请求权限 ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.READ_EXTERNAL_STORAGE, Manifest.permission.WRITE_EXTERNAL_STORAGE}, MY_PERMISSIONS_REQUEST_READ_WRITE); } else { // 已经有权限,可以继续执行代码 }
接着,确保在调用
setDataSource()
方法时传递正确的数据源类型。对于从相册选择的视频,应该使用ContentResolver
来获取正确的URI。private void processVideo(Uri videoUri) { ContentResolver contentResolver = getContentResolver(); MediaMetadataRetriever retriever = new MediaMetadataRetriever(); try { retriever.setDataSource(contentResolver, videoUri); } catch (IOException e) { Log.e("TAG", "Error setting data source: ", e); return; } ... }
接下来,当处理位图时,确保正确地处理null值,因为
getFrameAtTime()
可能会返回null,特别是在视频开始时。同时,为了防止内存泄漏,建议使用BitmapFactory.Options
对象来优化位图加载。BitmapFactory.Options options = new BitmapFactory.Options(); options.inJustDecodeBounds = true; try { retriever.setDataSource(contentResolver, videoUri); } catch (IOException e) { Log.e("TAG", "Error setting data source: ", e); return; } int height = retriever.extractHeight(null); int width = retriever.extractWidth(null); options.inSampleSize = calculateInSampleSize(options, desiredWidth, desiredHeight); options.inJustDecodeBounds = false; Bitmap bitmap1 = null; try { bitmap1 = BitmapFactory.decodeStream(retriever.getInputStream(MediaMetadataRetriever.METADATA_KEY_MIME), null, options); } catch (IOException e) { Log.e("TAG", "Error decoding bitmap: ", e); } if (bitmap1 != null) { YoLoV5Ncnn.obj[] objs = yolov5ncnn.Detect(bitmap1, use_gpu: true); Bitmap updatedBitmap = performObjectDetection(objs); imageView.setImageBitmap(updatedBitmap); }
这里,
calculateInSampleSize()
是一个用于计算缩放因子的方法,以减小位图尺寸并降低内存消耗:private int calculateInSampleSize(BitmapFactory.Options options, int reqWidth, int reqHeight) { final int height = options.outHeight; final int width = options.outWidth; int inSampleSize = 1; if (height > reqHeight || width > reqWidth) { final int halfHeight = height / 2; final int halfWidth = width / 2; while ((halfHeight / inSampleSize) >= reqHeight && (halfWidth / inSampleSize) >= reqWidth) { inSampleSize *= 2; } } return inSampleSize; }
这些更改应该能解决闪退问题。请将上述代码片段替换到您的项目中,并根据需要调整参数。如果问题仍然存在,请提供具体的错误日志,以便进一步诊断。
解决 无用评论 打赏 举报 编辑记录
悬赏问题
- ¥15 Matlab在app上输入带有矩阵形式的初始条件发生错误
- ¥15 CST仿真别人的模型结果仿真结果S参数完全不对
- ¥15 误删注册表文件致win10无法开启
- ¥15 请问在阿里云服务器中怎么利用数据库制作网站
- ¥60 ESP32怎么烧录自启动程序
- ¥50 html2canvas超出滚动条不显示
- ¥15 java业务性能问题求解(sql,业务设计相关)
- ¥15 52810 尾椎c三个a 写蓝牙地址
- ¥15 elmos524.33 eeprom的读写问题
- ¥15 用ADS设计一款的射频功率放大器