简体   繁体   English

如何使用MediaCodec,MediaExtractor或MediaMetadataRetriever确定视频文件的帧率?

[英]How to determine a video file's framerate with MediaCodec, MediaExtractor or MediaMetadataRetriever?

How to I extract the frame rate of a recorded video file? 如何提取录制的视频文件的帧频? I know that there is MediaFormat.KEY_FRAME_RATE and that I can access MediaFormat objects through MediaExtractor. 我知道这里有MediaFormat.KEY_FRAME_RATE,并且可以通过MediaExtractor访问MediaFormat对象。 However KEY_FRAME_RATE is only available for encoders. 但是,KEY_FRAME_RATE仅适用于编码器。 Instead I want to find out the frame rate of an already recorded video. 相反,我想找出已经录制的视频的帧速率。

Any ideas? 有任何想法吗?

When using MediaExtractor , if your video track has a stable FPS, then you know for sure your MediaExtractor is advancing by the frame duration you are searching for. 使用MediaExtractor ,如果您的视频轨道具有稳定的FPS,则可以确定MediaExtractor会按搜索的帧时长前进。

Before doing anything, just after having set up your MediaExtractor , you can do the following: 在做任何事情之前,在设置MediaExtractor ,您可以执行以下操作:

mediaExtractor.Advance();
var fps = 1000000f / (float) mediaExtractor.SampleTime;
mediaExtractor.SeekTo(0, MediaExtractorSeekTo.None);

Like I said, you can't take for grant that all your frames have the same duration. 就像我说的那样,您不能认为所有帧都具有相同的持续时间。 Frame presentation time are totally arbitrary, but I feel it's not common to not have a stable FPS. 帧显示时间完全是任意的,但是我觉得没有稳定的FPS并不常见。

It looks like there is no way to get framerate through any of official API functions. 似乎无法通过任何官方API函数获得帧速率。 It might require some extra logic - count times between timestamps or to parse headers info. 它可能需要一些额外的逻辑-在时间戳之间计数时间或解析标头信息。 in general h.264 standard allows variable framerate, so frame times could differ from one to one. 通常,h.264标准允许可变的帧速率,因此帧时间可能不一。 for example if can show some static picture for several seconds or so 例如,如果可以显示静态图片几秒钟左右

You can use ffmpeg to get the frame rate of a video ( https://www.ffmpeg.org ) - subject to the comments that fadden and Marlon make on variable frames rates in the comments to the accepted answer. 您可以使用ffmpeg获取视频的帧速率( https://www.ffmpeg.org )-取决于fadden和Marlon在接受的答案的注释中对可变帧速率所作的注释。

There are a number of ways to include ffmpeg in Android - the one I found the best compromise between complexity and functionality was to wrap the command line ffmpeg program in a Java JNI wrapper. 在Android中包含ffmpeg的方法有很多种,我发现在复杂性和功能之间最好的折衷方法是将命令行ffmpeg程序包装在Java JNI包装器中。

There are a couple of issues to look out for, including an issue with invoking ffmpeg twice via the wrapper, so it is worth either using or studying existing Android wrapper solutions - eg: 需要注意几个问题,包括通过包装程序两次调用ffmpeg的问题,因此值得使用或研究现有的Android包装程序解决方案-例如:

From the documentation there: 从那里的文档:

FFmpeg ffmpeg = FFmpeg.getInstance(context);
try {
  // to execute "ffmpeg -version" command you just need to pass "-version"
  ffmpeg.execute(cmd, new ExecuteBinaryResponseHandler() {

    @Override
    public void onStart() {}

    @Override
    public void onProgress(String message) {}

    @Override
    public void onFailure(String message) {}

    @Override
    public void onSuccess(String message) {}

    @Override
    public void onFinish() {}
  });
} catch (FFmpegCommandAlreadyRunningException e) {
  // Handle if FFmpeg is already running
}

An example of ffmpeg cmd to get the frame rate, replacing filename with the name of the file you want to check: ffmpeg cmd获取帧率的示例,将filename替换为要检查的文件名:

cmd = "-i filename";

Your code can then parse the output for the fps - see example output below: 然后,您的代码可以解析f​​ps的输出-请参见下面的示例输出:

ffmpeg version 2.6.1 Copyright (c) 2000-2015 the FFmpeg developers
  built with llvm-gcc 4.2.1 (LLVM build 2336.11.00)
  configuration: --prefix=/Volumes/Ramdisk/sw --enable-gpl --enable-pthreads --enable-version3 --enable-libspeex --enable-libvpx --disable-decoder=libvpx --enable-libmp3lame --enable-libtheora --enable-libvorbis --enable-libx264 --enable-avfilter --enable-libopencore_amrwb --enable-libopencore_amrnb --enable-filters --enable-libgsm --enable-libvidstab --enable-libx265 --disable-doc --arch=x86_64 --enable-runtime-cpudetect
  libavutil      54. 20.100 / 54. 20.100
  libavcodec     56. 26.100 / 56. 26.100
  libavformat    56. 25.101 / 56. 25.101
  libavdevice    56.  4.100 / 56.  4.100
  libavfilter     5. 11.102 /  5. 11.102
  libswscale      3.  1.101 /  3.  1.101
  libswresample   1.  1.100 /  1.  1.100
  libpostproc    53.  3.100 / 53.  3.100
Input #0, mov,mp4,m4a,3gp,3g2,mj2, from '/Users/BBB/Desktop/vid_bigbuckbunny.mp4':
  Metadata:
    major_brand     : mp42
    minor_version   : 1
    compatible_brands: mp42avc1
    creation_time   : 2010-02-09 01:55:39
  Duration: 00:01:00.10, start: 0.000000, bitrate: 733 kb/s
    Stream #0:0(eng): Audio: aac (LC) (mp4a / 0x6134706D), 22050 Hz, stereo, fltp, 65 kb/s (default)
    Metadata:
      creation_time   : 2010-02-09 01:55:39
      handler_name    : Apple Sound Media Handler
    Stream #0:1(eng): Video: h264 (Constrained Baseline) (avc1 / 0x31637661), yuv420p(tv, smpte170m/smpte170m/bt709), 640x360, 612 kb/s, 23.96 fps, 24 tbr, 600 tbn, 1200 tbc (default)
    Metadata:
      creation_time   : 2010-02-09 01:55:39
      handler_name    : Apple Video Media Handler
    Stream #0:2(eng): Data: none (rtp  / 0x20707472), 45 kb/s
    Metadata:
      creation_time   : 2010-02-09 01:55:39
      handler_name    : hint media handler
    Stream #0:3(eng): Data: none (rtp  / 0x20707472), 5 kb/s
    Metadata:
      creation_time   : 2010-02-09 01:55:39
      handler_name    : hint media handler

Bear in mind that ffmpeg syntax and output format can change over time, so for the parsing in particular you need to allow for this, although looking for 'fps' in the output will probably generally work anyway. 请记住,ffmpeg语法和输出格式可能会随时间而变化,因此,尽管通常在输出中查找“ fps”通常可能仍然有效,但特别是对于解析,您需要允许这样做。

Also be aware that many video 'containers' (eg mp4, often referred to as the video file) may contain multiple video streams and the different streams may have different frame rates. 还应注意,许多视频“容器”(例如mp4,通常称为视频文件)可能包含多个视频流,并且不同的流可能具有不同的帧速率。 This will be included in the output from ffmpeg so something else to check for when parsing the output. 它将包含在ffmpeg的输出中,因此在解析输出时需要检查其他内容。

And finally, just a reminder again that the frame rate may not be constant for a video so use with this in mind. 最后,再次提醒您,视频的帧频可能不是恒定的,因此请牢记这一点。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM