首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何在Android中获取视频文件的关键帧(同步帧)时间戳列表?

如何在Android中获取视频文件的关键帧(同步帧)时间戳列表?
EN

Stack Overflow用户
提问于 2012-08-03 23:11:01
回答 5查看 5.5K关注 0票数 11

有没有什么API可以给我一个Android视频文件的关键帧的时间戳列表?

EN

回答 5

Stack Overflow用户

回答已采纳

发布于 2012-11-20 04:42:05

我相信正确的答案是http://code.google.com/p/mp4parser/

isoparser API可以读写MP4文件结构。它是一个低级工具,可以处理所谓的盒子,但它也可以处理像音轨和电影这样的结构。

不错的API和比ffmpeg behemoth快得多的方式

票数 5
EN

Stack Overflow用户

发布于 2012-08-15 23:31:12

对于一个优雅的解决方案,似乎你需要使用ffmpeg For android来实现这一点。另一个人尝试了这种方式:How to get the frame from video file in android;并被建议使用ffmpeg。

我查看了参考手册,但只能找到一种方法来获得相对于给定位置的关键帧本身(没有时间戳),使用MediaMetadataRetriever(),如下所示:http://developer.android.com/reference/android/media/MediaMetadataRetriever.html#extractMetadata%28int%29

如果你不想使用ffmpeg,你可以尝试以下方法:

代码语言:javascript
复制
private ArrayList<int> getKeyFrameTimestamps(String filename) {
  ArrayList<int> timeStamps = new ArrayList<int>();

  try {
    MediaMetadataRetriever mRetriever = new MediaMetadataRetriever();
    mRetriever.setDataSource(getDataSource(filename));
    mRetriever.getFrameAtTime(i, MediaMetadataRetriever.OPTION_CLOSEST_SYNC);

    Bitmap lastFame = mRetriever.getFrameAtTime(0, MediaMetadataRetriever.OPTION_NEXT_SYNC);
    result.add(0);

    for(int time=1; frame ; ++time) {
      Bitmap frame = mRetriever.getFrameAtTime(time, MediaMetadataRetriever.OPTION_PREVIOUS_SYNC);
      if (frame && !frame.sameAs(lastFrame)) {
        result.add(time);
        lastFrame = frame;
      }
    }
  } catch (Exception e) {  /* TODO: HANDLE THIS */ }

  return timeStamps;
}

这当然不是很优雅,但安装ffmpeg可能会很容易。它可能也很慢(我不知道)。但也许这正是你所需要的。

PS:可以在这里找到适合您的问题的ffmpeg教程:http://dranger.com/ffmpeg/tutorial07.html

票数 10
EN

Stack Overflow用户

发布于 2015-04-13 23:40:21

4.1+ -比mp4parser更快,因为它是在底层的本机中完成的,而且代码更整洁

你必须从getsyncsamples + getsampledurations中计算时间戳,这也很烦人,而且它们与mp4parser不匹配。这样可以得到准确的结果

代码语言:javascript
复制
MediaExtractor extractor = new MediaExtractor();
extractor.setDataSource(getVideoPath());

int trackindex = MediaExtractorUtil.selectVideoTrack(extractor);
extractor.selectTrack(trackindex);

while (extractor.getSampleTime() != -1) {
    long sampleTime = extractor.getSampleTime();

    // check not really necessary but JIC
    if ((extractor.getSampleFlags() & MediaExtractor.SAMPLE_FLAG_SYNC) > 0) {
        mKeyframeTimestampsMS.add(sampleTime / 1000);
    }

    extractor.seekTo(sampleTime + 1, MediaExtractor.SEEK_TO_NEXT_SYNC);
}
票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/11798424

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档