我正在尝试使用视频帧过滤视频。有两种技术可用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中,但它导致位图已经回收问题。所以需要找到一些好的解决方案。