获取视频过滤器的视频帧非常慢。还有其他方法吗?

时间:2018-01-09 06:41:18

标签: android video bitmap video-processing android-glide

我正在尝试使用视频帧过滤视频。有两种技术可用1)MediaMetadataRetriver和2)FFMpegMediaMetadataRetriver,但两者对我来说都很慢。

这是我得到框架的代码。

MediaMetadataRetriever metadataRetriever2;
metadataRetriever2 = new MediaMetadataRetriever();
    metadataRetriever2.setDataSource(context,
            Uri.parse(trimmedVideoPath));
setRvVideoFilter(metadataRetriever2.getFrameAtTime(0, MediaMetadataRetriever.OPTION_CLOSEST_SYNC));
    setRvVideoFilter(metadataRetriever2.getFrameAtTime(0, MediaMetadataRetriever.OPTION_CLOSEST_SYNC));
    setRvVideoFilter(metadataRetriever2.getFrameAtTime(0, MediaMetadataRetriever.OPTION_CLOSEST_SYNC));
    setRvVideoFilter(metadataRetriever2.getFrameAtTime(0, MediaMetadataRetriever.OPTION_CLOSEST_SYNC));
    setRvVideoFilter(metadataRetriever2.getFrameAtTime(0, MediaMetadataRetriever.OPTION_CLOSEST_SYNC));
    setRvVideoFilter(metadataRetriever2.getFrameAtTime(0, MediaMetadataRetriever.OPTION_CLOSEST_SYNC));
    setRvVideoFilter(metadataRetriever2.getFrameAtTime(0, MediaMetadataRetriever.OPTION_CLOSEST_SYNC));

将位图添加到模型和arraylist以在Adapter中进一步使用的函数:

private void setRvVideoFilter(Bitmap bitmap) {
    modelVideoFrames = new ModelVideoFrames(bitmap);
    arrayList.add(modelVideoFrames);
}

在RecyclerView Adapter中我写了这段代码:

RequestOptions requestOptions = new RequestOptions();
Glide.with(context)
            .load(arrayList.get(position).getFrameBitmap())
            .apply(requestOptions.skipMemoryCache(true))
            .apply(requestOptions.override(100, 100))
            .apply(requestOptions.diskCacheStrategy(DiskCacheStrategy.ALL))
            .apply(requestOptions.transform(new BitmapTransformation() {
                @Override
                protected Bitmap transform(@NonNull BitmapPool pool, @NonNull Bitmap toTransform, int outWidth, int outHeight) {
                    GPUImage gpuImage = new GPUImage(context);

                    switch (holder.getLayoutPosition()) {
                        case 0:
                            return toTransform;

                        case 1:
                            GPUImageGrayscaleFilter grayscaleFilter = new GPUImageGrayscaleFilter();
                            gpuImage.setImage(toTransform);
                            gpuImage.setFilter(grayscaleFilter);
                            return gpuImage.getBitmapWithFilterApplied();

                        case 2:
                            GPUImageGammaFilter gammaFilter = new GPUImageGammaFilter(.5f);
                            gpuImage.setImage(toTransform);
                            gpuImage.setFilter(gammaFilter);
                            return gpuImage.getBitmapWithFilterApplied();

                        case 3:
                            GPUImageSepiaFilter sepiaFilter = new GPUImageSepiaFilter(.05f);
                            gpuImage.setImage(toTransform);
                            gpuImage.setFilter(sepiaFilter);
                            return gpuImage.getBitmapWithFilterApplied();

                        case 4:
                            GPUImageContrastFilter contrastFilter = new GPUImageContrastFilter(.05f);
                            gpuImage.setImage(toTransform);
                            gpuImage.setFilter(contrastFilter);
                            return gpuImage.getBitmapWithFilterApplied();

                        case 5:
                            GPUImageColorInvertFilter colorInvertFilter = new GPUImageColorInvertFilter();
                            gpuImage.setImage(toTransform);
                            gpuImage.setFilter(colorInvertFilter);
                            return gpuImage.getBitmapWithFilterApplied();

                        case 6:
                            GPUImageVignetteFilter vignetteFilter = new GPUImageVignetteFilter();
                            gpuImage.setImage(toTransform);
                            gpuImage.setFilter(vignetteFilter);
                            return gpuImage.getBitmapWithFilterApplied();

                        default:
                            return toTransform;
                    }
                }

                @Override
                public void updateDiskCacheKey(MessageDigest messageDigest) {

                }
            }))
            .into(holder.ivFrame);

您可以看到我也在处理Glide位图以显示过滤器。但很大的问题是metadataRetriever2.getFrameAtTime(0,MediaMetadataRetriever.OPTION_CLOSEST_SYNC)非常慢。我还尝试将metadataRetriever2.getFrameAtTime(0,MediaMetadataRetriever.OPTION_CLOSEST_SYNC)压缩到另一个Bitmap中,但它导致位图已经回收问题。所以需要找到一些好的解决方案。

0 个答案:

没有答案