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 MediaMetadataRetrievergetFrameAt 方法的替代解决方案。 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 不准确,如何获取视频截图?的主要内容,如果未能解决你的问题,请参考以下文章