我有一个应用程序,要求我从视频中检索帧并使用它们进行一些处理。然而,似乎帧检索非常慢到不可接受的程度。有时需要2.5秒才能检索到一帧。我正在使用MediaMetadataRetriever作为建议的大多数stackoverflow问题。但表现非常糟糕。这就是我所拥有的:
private List<Bitmap> retrieveFrames() {
MediaMetadataRetriever fmmr = new MediaMetadataRetriever();
fmmr.setDataSource("/path/to/some/video.mp4");
String strLength = fmmr.extractMetadata(MediaMetadataRetriever.METADATA_KEY_DURATION);
long milliSecs = Long.parseLong(strLength);
long microSecLength = milliSecs * 1000;
Log.d("TAG", "length: " + microSecLength);
long one_sec = 1000000; // one sec in micro seconds
ArrayList<Bitmap> frames = new ArrayList<>();
int j = 0;
for (int i = 0; i < microSecLength; i += (one_sec / 5)) {
long time = System.currentTimeMillis();
Bitmap frame = fmmr.getFrameAtTime(i, MediaMetadataRetriever.OPTION_CLOSEST);
j++;
Log.d("TAG", "Frame number: " + j + " Time taken: " + (System.currentTimeMillis() - time));
// commented out because each frame would be written to disk instead of holding them in memory
// frames.add(frame);
}
fmmr.release();
return frames;
}
以上将记录:
03-26 21:49:29.781 13213-13239/com.example.naveed.myapplication D/TAG﹕ length: 4949000
03-26 21:49:30.187 13213-13239/com.example.naveed.myapplication D/TAG﹕ Frame number: 1 Time taken: 406
03-26 21:49:30.779 13213-13239/com.example.naveed.myapplication D/TAG﹕ Frame number: 2 Time taken: 592
03-26 21:49:31.578 13213-13239/com.example.naveed.myapplication D/TAG﹕ Frame number: 3 Time taken: 799
03-26 21:49:32.632 13213-13239/com.example.naveed.myapplication D/TAG﹕ Frame number: 4 Time taken: 1054
03-26 21:49:33.895 13213-13239/com.example.naveed.myapplication D/TAG﹕ Frame number: 5 Time taken: 1262
03-26 21:49:35.382 13213-13239/com.example.naveed.myapplication D/TAG﹕ Frame number: 6 Time taken: 1486
03-26 21:49:37.128 13213-13239/com.example.naveed.myapplication D/TAG﹕ Frame number: 7 Time taken: 1746
03-26 21:49:39.077 13213-13239/com.example.naveed.myapplication D/TAG﹕ Frame number: 8 Time taken: 1948
03-26 21:49:41.287 13213-13239/com.example.naveed.myapplication D/TAG﹕ Frame number: 9 Time taken: 2210
03-26 21:49:43.717 13213-13239/com.example.naveed.myapplication D/TAG﹕ Frame number: 10 Time taken: 2429
03-26 21:49:44.093 13213-13239/com.example.naveed.myapplication D/TAG﹕ Frame number: 11 Time taken: 376
03-26 21:49:44.707 13213-13239/com.example.naveed.myapplication D/TAG﹕ Frame number: 12 Time taken: 614
03-26 21:49:45.539 13213-13239/com.example.naveed.myapplication D/TAG﹕ Frame number: 13 Time taken: 831
03-26 21:49:46.597 13213-13239/com.example.naveed.myapplication D/TAG﹕ Frame number: 14 Time taken: 1057
03-26 21:49:47.875 13213-13239/com.example.naveed.myapplication D/TAG﹕ Frame number: 15 Time taken: 1278
03-26 21:49:49.384 13213-13239/com.example.naveed.myapplication D/TAG﹕ Frame number: 16 Time taken: 1508
03-26 21:49:51.112 13213-13239/com.example.naveed.myapplication D/TAG﹕ Frame number: 17 Time taken: 1728
03-26 21:49:53.096 13213-13239/com.example.naveed.myapplication D/TAG﹕ Frame number: 18 Time taken: 1983
03-26 21:49:55.315 13213-13239/com.example.naveed.myapplication D/TAG﹕ Frame number: 19 Time taken: 2218
03-26 21:49:57.711 13213-13239/com.example.naveed.myapplication D/TAG﹕ Frame number: 20 Time taken: 2396
03-26 21:49:58.065 13213-13239/com.example.naveed.myapplication D/TAG﹕ Frame number: 21 Time taken: 354
03-26 21:49:58.640 13213-13239/com.example.naveed.myapplication D/TAG﹕ Frame number: 22 Time taken: 574
03-26 21:49:59.369 13213-13239/com.example.naveed.myapplication D/TAG﹕ Frame number: 23 Time taken: 728
03-26 21:50:00.112 13213-13239/com.example.naveed.myapplication D/TAG﹕ Frame number: 24 Time taken: 742
03-26 21:50:00.834 13213-13239/com.example.naveed.myapplication D/TAG﹕ Frame number: 25 Time taken: 721
从上面可以看出,从4秒长的视频中检索25帧需要大约18到25秒。
我也试过this使用下面的FFmpeg来做同样的事情。我不确定这个库是如何实现的,但它只能将所有性能提高几秒钟,这意味着它需要大约15-20秒才能完成。
所以我的问题是:有没有办法更快地做到这一点?我的朋友有一个iOS应用程序,他做了类似的事情,但它只需要几秒钟,他抓住更多的帧,但他不知道如何在Android上做到这一点。
Android上有什么可以加速这个过程。我接近这个错吗?
最终目标是将这些帧拼接成一个gif。
答案 0 :(得分:0)
您可以尝试使用OPTION_CLOSEST_SYNC而不是OPTION_CLOSEST,这可能会加快一点,但这将获得视频中最接近的关键帧。我不知道是否有办法在Android上加快速度。