2014-07-16 85 views

回答

2

看起来像没有办法通过任何官方API函数来获取帧率。它可能需要一些额外的逻辑 - 时间戳之间的计数时间或解析标题信息。一般而言,h.264标准允许可变帧率,因此帧时间可能会不同于一比一。例如,如果可以显示几秒钟左右的静态图片

+1

VFR的一个简单的例子是通过在奇巧的“screenrecord”命令生成的视频。如果视频没有以一个固定的帧速率记录下来,那么就无法知道帧的数量(除了对它们进行计数),并且没有像帧速率那样的东西。你可以计算一个峰值帧速率,这可能是OP后面的。 – fadden

+0

是否需要安卓设备上的hw编码器才能在vfr模式下工作,并且是否有测试\计划来进行测试以检查它? – Marlon

+0

我不知道。我现在不在那里工作,所以很难找到答案。 :-) – fadden

2

您可以使用ffmpeg获取视频的帧速率(https://www.ffmpeg.org) - 服从fadden和Marlon对注释中的可变帧速率做出的评论接受的答案。

有许多方法可以在Android中包含ffmpeg - 我发现复杂性和功能性之间最好的折中方法是将命令行ffmpeg程序包装在Java JNI包装中。

有几个问题看出来的,包括通过包装两次调用的ffmpeg的问题,所以它是值得或者使用或学习现有的Android包装解决方案 - 例如:

从文档有:

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 
} 

的ffmpeg CMD的一个例子,以获得帧速率,与文件的名称替换文件名要检查:

cmd = "-i filename"; 

你的代码可以解析输出的FPS - 参见下面的示例输出:

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 

记住,FFmpeg的语法和输出格式可能会随时间而改变,所以对于解析特别是你需要考虑到这一点,尽管在输出中寻找'fps'可能通常会起作用。另外请注意,许多视频“容器”(例如,mp4,通常被称为视频文件)可能包含多个视频流,并且不同的流可能具有不同的帧速率。这将包含在ffmpeg的输出中,以便在解析输出时检查其他内容。

最后,再次提醒您,视频的帧频可能不是恒定的,因此请牢记这一点。

+0

你是对的,但包括FFMPEG仅计算帧速率是一个巨大的开销,我认为 – Florian

+1

形成视图的复杂性和着力点,开销显著,绝对 - 对此也无异议。对于速度,应用程序大小等可能不是这样的问题。 – Mick

+0

最后一个环节 - 404,这将是巨大的,如果你能告诉一个片段与FFMPEG – Inoy

2

当使用MediaExtractor时,如果您的视频轨道具有稳定的FPS,那么您肯定知道您的MediaExtractor正在前进您正在搜索的帧持续时间。

做什么,只是已经成立后,之前你MediaExtractor,你可以做到以下几点:

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

就像我说的,你不能把补助金,所有的帧具有相同的持续时间。帧展示时间完全是任意的,但我觉得没有稳定的FPS并不常见。

相关问题