在Android中提取所有视频帧

7

我录制了一个有时间限制的视频。现在我想获取视频的所有帧。我正在使用以下代码,通过使用它,我能够获取帧,但我没有获取到所有的视频帧。 3到4帧被重复,然后我得到了一个不同的帧。但正如我们都知道的那样,我们可以获得每秒25-30帧以显示平滑的视频。 如何获取所有帧。

 for (int i = 0; i < 30; i++) {

                    Bitmap bArray = mediaMetadataRetriever.getFrameAtTime(
                            1000000 * i,
                            MediaMetadataRetriever.OPTION_CLOSEST);

                    savebitmap(bArray, 33333 * i);

                }

我不想使用NDK。我得到了这个链接,但不知道"argb8888"应该是什么值。我在这里遇到了错误。有人能解释一下如何做吗? 在Android中从视频图像获取帧


2
尝试使用 OPTION_CLOSEST 看看会发生什么。 - Sam R.
感谢您宝贵的回答。 - Akanksha Rathore
是的,我已经做到了。不需要NDK或任何特殊的东西。只需尝试从预览中提取帧即可获得流畅的视频。当你绑定所有帧时。 - Akanksha Rathore
2
@Akanksha,你是如何实现视频平滑的?我也遇到同样的问题。 - TOP
@AkankshaRathore,你尝试过下面提供的FFmpegMediaMetadataRetriever吗?你能通过FFmpegMediaMetadataRetriever获取到正确的帧吗? - Mohit Nigam
能否得到savebitmap(bArray, 33333 * i);方法!! - Akash Dubey
4个回答

13

我之前也遇到过同样的问题,而Android的MediaMetadataRetriever似乎不适合这项任务,因为它的精度不够好。我在Android Studio中使用了一个名为"FFmpegMediaMetadataRetriever"的库:

  1. 在module应用程序的build.graddle文件中添加以下行:

    compile 'com.github.wseemann:FFmpegMediaMetadataRetriever:1.0.14'

  2. 重新构建项目。

  3. 使用FFmpegMediaMetadataRetriever类来以更高的精度获取帧:

    FFmpegMediaMetadataRetriever med = new FFmpegMediaMetadataRetriever();
    
    med.setDataSource("your data source");
    
  4. 在您的循环中,您可以使用以下方式获取帧:

     Bitmap bmp = med.getFrameAtTime(i*1000000, FFmpegMediaMetadataRetriever.OPTION_CLOSEST);
    

我的循环结束索引是什么?我如何获取捕获帧的数量?我必须迭代循环直到捕获的帧数。 - Parin Parikh
1
方法“getFrameAtTime”的第一个参数是视频时间轴上帧的位置,单位为微秒(1秒=1,000,000毫秒)。因此,在该特定代码中,我们每隔1秒获取一帧。因此,i的循环限制可能是以秒为单位的视频长度。附注:如果您想在更短的间隔(例如毫秒)内获取帧,则可以更改0的数量。 - Milorenus Lomaliza

4
要从视频中获取图像帧,我们可以使用ffmpeg。为了在android中集成FFmpeg,我们可以使用预编译库,例如ffmpeg-android
要从视频中提取图像帧,我们可以使用以下命令
String [] complexCommand = {"-y", "-i", inputFileAbsolutePath, "-an", "-r", "1/2", "-ss", "" + startMs / 1000, "-t", "" + (endMs - startMs) / 1000, outputFileAbsolutePath};
在这里,
-y
覆盖输出文件
-i
ffmpeg从由-i选项指定的任意数量的输入“文件”中读取
-an
禁用音频记录。
-r 设置帧速率
-ss
寻找位置
-t
限制从输入文件中读取的数据持续时间
在这里,您必须在inputFileAbsolutePath的位置上指定要提取图像的视频文件的绝对路径。

要查看完整的代码,请访问我的存储库中的this。在extractImagesVideo()方法中,我正在运行提取视频图像的命令。

有关集成ffmpeg库和使用ffmpeg命令编辑视频的完整教程,请查看我在博客上写的this文章。


2
您需要做的是:
  1. 解码视频。
  2. 以至少每秒24帧的速度呈现解码后的图像。我认为您可以跳过此步骤。
  3. 保存解码后的图像。
看起来解码视频可能是最具挑战性的步骤。人们和公司花费了多年时间开发各种视频格式的编解码器。
请使用此库JMF for FFMPEG

0

[2023年更新]

在这种情况下,你可能会发现这个存储库很有用:https://github.com/duckyngo/Fast-Video-Frame-Extraction。它是一个高性能的解决方案,可以从视频中提取所有帧。

另一方面,如果你只想提取有限数量的帧,你可以尝试使用MediaMetadataRetriever类中的"getFrameAtIndex()"函数。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接