retriever.getFrameAtTime 不准确,如何获取视频截图?
Posted
技术标签:
【中文标题】retriever.getFrameAtTime 不准确,如何获取视频截图?【英文标题】:retriever.getFrameAtTime is not accurate, how can i get screenshot of video? 【发布时间】:2013-02-11 14:22:59 【问题描述】:这是我正在使用的功能:
public Bitmap getVideoFrame(String FD, long time)
MediaMetadataRetriever retriever = new MediaMetadataRetriever();
try
retriever.setDataSource(FD);
return retriever.getFrameAtTime(time * 1000, MediaMetadataRetriever.OPTION_CLOSEST);
catch (IllegalArgumentException ex)
ex.printStackTrace();
catch (RuntimeException ex)
ex.printStackTrace();
finally
try
retriever.release();
catch (RuntimeException ex)
return null;
其中:FD是视频的路径 时间 = videoview.getCurrentPosition();
问题是这个函数没有得到我需要得到的确切帧。在较长的视频(20 分钟)上,它会比在短视频(10-20 秒)中更准确。有没有我遗漏的东西,如果没有,我可以用什么来代替检索器?
【问题讨论】:
仅供参考:android 6.0 Marshmallow 存在已知错误,即getFrameAtTime
API - code.google.com/p/android/issues/detail?id=193194 未返回精确帧
【参考方案1】:
尝试不带选项使用... retriever.getFrameAtTime(time * 1000);
我遇到了同样的问题,在我进行此修改后,它运行完美。
【讨论】:
这使用 OPTION_CLOSEST_SYNC 而不是 OPTION_CLOSEST,它给出了最近的同步帧,因为它获得了一个同步帧,所以它不是很准确。【参考方案2】:该功能有一个错误,它显然不适用于小型视频并且非常不可靠,我最近在SO
,see this post 上问过这个问题,但没有得到正确答案,所以我做了大量研究并使用FFMPEG
代替,使用FFMPEG
我能够提取精确到毫秒的视频帧,还请注意,在手机上提取帧的过程很慢,对于大视频,即 50Mb 以上,它经常我花了 2 分钟来提取我想要的东西。
【讨论】:
您现在有任何链接或其他东西可以帮助我使用 FFMPEG 吗? 有很多为 FFMPeg 构建的 FFMPEG 库,你应该在 google 上输入 FFMPeg for Android 并获取你想要的库,我使用了来自 GitHub 的这个库,github.com/uday-rayala/video-trimmer 它是免费使用的,它有 Apache 许可证还是我必须付费才能使用它,因为我只被允许使用免费库。我在网上搜索了 FFMPEG,但很多人说这不是免费用于商业应用的 FFmpeg 可以免费合并,只要您使用开放的视频和音频格式,请查看有关 FFMpeg 许可的类似问题***.com/a/9272100/892055【参考方案3】:retriever.getFrameAtTime(second* 1000*1000);
它需要微秒而不是毫秒。
【讨论】:
毫秒,我忘了,大声笑,我曾经认为它需要毫秒。 :) 测试为真。这应该是公认的答案。其实从参数名就可以看出来:timeUs,意思是时间,单位是µs,当然也就是微秒。 该死的,整个 API 使用毫秒,但这种方法使用微秒。非常感谢!【参考方案4】:是的,我同意retriever.getFrameAtTime 不准确。
替代Android MediaMetadataRetriever
的getFrameAt
方法的替代解决方案。 AV_FrameCapture 使用MediaCodec
解码视频帧并使用OpenGL
将视频帧转换为RGB 位图。由于AndroidMediaMetadataRetriever
不保证调用getFrameAtTime
时会返回结果,所以这个AV_FrameCapture可以用来准确提取一帧视频。
https://***.com/a/60633395/6676310
【讨论】:
【参考方案5】:ImageView imageView1=(ImageView)findViewById(R.id.imageView1);
Bitmap bm=ThumbnailUtils.createVideoThumbnail(Environment.getExternalStorageDirectory() + "/videocapture.3gp",Thumbnails.MICRO_KIND);
imageView1.setImageBitmap(bm);
【讨论】:
问题是如何在给定时间获取视频的一帧,这个答案没有意义。 是的,更荒谬的是它被接受为正确答案。以上是关于retriever.getFrameAtTime 不准确,如何获取视频截图?的主要内容,如果未能解决你的问题,请参考以下文章