有没有一种有效的方法可以从 Android 视频中检索帧?

Nav*_*eed 5 video android ffmpeg

我有一个应用程序,需要我从视频中检索帧并对其进行一些处理。然而,帧检索似乎非常慢,以至于无法接受。有时检索单个帧需要长达 2.5 秒的时间。我正在使用MediaMetadataRetriever作为大多数 stackoverflow 问题的建议。然而性能却非常糟糕。这是我所拥有的:

\n\n
   private List<Bitmap> retrieveFrames() {\n\n        MediaMetadataRetriever fmmr = new MediaMetadataRetriever();\n        fmmr.setDataSource("/path/to/some/video.mp4");\n        String strLength = fmmr.extractMetadata(MediaMetadataRetriever.METADATA_KEY_DURATION);\n        long milliSecs = Long.parseLong(strLength);\n        long microSecLength = milliSecs * 1000;\n\n        Log.d("TAG", "length: " + microSecLength);\n        long one_sec = 1000000; // one sec in micro seconds\n\n        ArrayList<Bitmap> frames = new ArrayList<>();\n        int j = 0;\n        for (int i = 0; i < microSecLength; i += (one_sec / 5)) {\n            long time = System.currentTimeMillis();\n            Bitmap frame = fmmr.getFrameAtTime(i, MediaMetadataRetriever.OPTION_CLOSEST);\n            j++;\n            Log.d("TAG", "Frame number: " + j + " Time taken: " + (System.currentTimeMillis() - time));\n            // commented out because each frame would be written to disk instead of holding them in memory\n            //  frames.add(frame);\n        }\n        fmmr.release();\n        return frames;\n    }\n
Run Code Online (Sandbox Code Playgroud)\n\n

上面将记录:

\n\n
03-26 21:49:29.781  13213-13239/com.example.naveed.myapplication D/TAG\xef\xb9\x95 length: 4949000\n03-26 21:49:30.187  13213-13239/com.example.naveed.myapplication D/TAG\xef\xb9\x95 Frame number: 1 Time taken: 406\n03-26 21:49:30.779  13213-13239/com.example.naveed.myapplication D/TAG\xef\xb9\x95 Frame number: 2 Time taken: 592\n03-26 21:49:31.578  13213-13239/com.example.naveed.myapplication D/TAG\xef\xb9\x95 Frame number: 3 Time taken: 799\n03-26 21:49:32.632  13213-13239/com.example.naveed.myapplication D/TAG\xef\xb9\x95 Frame number: 4 Time taken: 1054\n03-26 21:49:33.895  13213-13239/com.example.naveed.myapplication D/TAG\xef\xb9\x95 Frame number: 5 Time taken: 1262\n03-26 21:49:35.382  13213-13239/com.example.naveed.myapplication D/TAG\xef\xb9\x95 Frame number: 6 Time taken: 1486\n03-26 21:49:37.128  13213-13239/com.example.naveed.myapplication D/TAG\xef\xb9\x95 Frame number: 7 Time taken: 1746\n03-26 21:49:39.077  13213-13239/com.example.naveed.myapplication D/TAG\xef\xb9\x95 Frame number: 8 Time taken: 1948\n03-26 21:49:41.287  13213-13239/com.example.naveed.myapplication D/TAG\xef\xb9\x95 Frame number: 9 Time taken: 2210\n03-26 21:49:43.717  13213-13239/com.example.naveed.myapplication D/TAG\xef\xb9\x95 Frame number: 10 Time taken: 2429\n03-26 21:49:44.093  13213-13239/com.example.naveed.myapplication D/TAG\xef\xb9\x95 Frame number: 11 Time taken: 376\n03-26 21:49:44.707  13213-13239/com.example.naveed.myapplication D/TAG\xef\xb9\x95 Frame number: 12 Time taken: 614\n03-26 21:49:45.539  13213-13239/com.example.naveed.myapplication D/TAG\xef\xb9\x95 Frame number: 13 Time taken: 831\n03-26 21:49:46.597  13213-13239/com.example.naveed.myapplication D/TAG\xef\xb9\x95 Frame number: 14 Time taken: 1057\n03-26 21:49:47.875  13213-13239/com.example.naveed.myapplication D/TAG\xef\xb9\x95 Frame number: 15 Time taken: 1278\n03-26 21:49:49.384  13213-13239/com.example.naveed.myapplication D/TAG\xef\xb9\x95 Frame number: 16 Time taken: 1508\n03-26 21:49:51.112  13213-13239/com.example.naveed.myapplication D/TAG\xef\xb9\x95 Frame number: 17 Time taken: 1728\n03-26 21:49:53.096  13213-13239/com.example.naveed.myapplication D/TAG\xef\xb9\x95 Frame number: 18 Time taken: 1983\n03-26 21:49:55.315  13213-13239/com.example.naveed.myapplication D/TAG\xef\xb9\x95 Frame number: 19 Time taken: 2218\n03-26 21:49:57.711  13213-13239/com.example.naveed.myapplication D/TAG\xef\xb9\x95 Frame number: 20 Time taken: 2396\n03-26 21:49:58.065  13213-13239/com.example.naveed.myapplication D/TAG\xef\xb9\x95 Frame number: 21 Time taken: 354\n03-26 21:49:58.640  13213-13239/com.example.naveed.myapplication D/TAG\xef\xb9\x95 Frame number: 22 Time taken: 574\n03-26 21:49:59.369  13213-13239/com.example.naveed.myapplication D/TAG\xef\xb9\x95 Frame number: 23 Time taken: 728\n03-26 21:50:00.112  13213-13239/com.example.naveed.myapplication D/TAG\xef\xb9\x95 Frame number: 24 Time taken: 742\n03-26 21:50:00.834  13213-13239/com.example.naveed.myapplication D/TAG\xef\xb9\x95 Frame number: 25 Time taken: 721\n
Run Code Online (Sandbox Code Playgroud)\n\n

从上面可以看出,从 4 秒长的视频中检索 25 帧大约需要 18 - 25 秒。

\n\n

我也尝试过这个使用 FFmpeg 来做同样的我不确定这个库的实现情况如何,但它仅将整体性能提高了几秒钟,这意味着大约需要 15-20 秒才能完成同样的工作。

\n\n

所以我的问题是:有没有办法更快地做到这一点?我的朋友有一个 iOS 应用程序,他在其中执行类似的操作,但只需要几秒钟,并且他捕获了更多帧,但他不确定如何在 Android 上执行此操作。

\n\n

安卓上有什么可以加快这个过程的吗?我这样做是错误的吗?

\n\n

最终目标是将这些帧拼接成 gif。

\n

l-l*_*l-l 0

您可以尝试使用 OPTION_CLOSEST_SYNC 而不是 OPTION_CLOSEST,这可能会稍微加快速度,但这将获得视频中最接近的关键帧。不知道安卓上有没有什么办法可以加快速度。

  • 我之前尝试过 OPTION_CLOSET_SYNC 但检索到的帧确实不准确,而且大多数都是重复的。最终结果(gif)看起来很糟糕。 (3认同)