用ffmpeg取帧数

有谁知道如何使用ffmpeg从video文件中获取总帧数? ffmpeg的渲染输出显示当前帧,我需要帧计数以百分比计算进度。

ffprobe

这种types的任务是ffprobe擅长的。

示例命令

 $ ffprobe -v error -count_frames -select_streams v:0 \ -show_entries stream=nb_read_frames -of default=nokey=1:noprint_wrappers=1 \ input.mkv 

输出示例

  2600 
  • 在这个例子中,输出2600是指读取帧的数量。

  • 由于整个文件必须被解码,所以命令可能需要一段时间才能完成,具体取决于您的input。

什么意思

  • -v error这隐藏了“信息”输出(版本信息等),使parsing更容易。

  • -count_frames计算每个stream的帧数并在相应的stream部分中报告。

  • -select_streams v:0只selectvideostream。

  • -show_entries stream=nb_read_frames只显示读取帧数。

  • -of default=nokey=1:noprint_wrappers=1将输出格式(即“writer”)设置为default ,不要打印每个字段的键( nokey=1 ),不要打印页眉和页脚( noprint_wrappers=1 )。

另见

  • FFprobe文档
  • FFmpeg维基:FFprobe提示

在Unix中,这就像魅力一样:

 ffmpeg -i 00000.avi -vcodec copy -acodec copy -f null /dev/null 2>&1 | grep 'frame=' | cut -f 2 -d ' ' 

根据时间计算它,而不是。

这就是我所做的,对我和其他人来说都很好。)首先,在下面的片段中findvideo的长度:

 Seems stream 0 codec frame rate differs from container frame rate: 5994.00 (5994/1) -> 29.97 (30000/1001) Input #0, mov,mp4,m4a,3gp,3g2,mj2, from '/Users/stu/Movies/District9.mov': Duration: 00:02:32.20, start: 0.000000, bitrate: 9808 kb/s Stream #0.0(eng): Video: h264, yuv420p, 1920x1056, 29.97tbr, 2997tbn, 5994tbc Stream #0.1(eng): Audio: aac, 44100 Hz, 2 channels, s16 Stream #0.2(eng): Data: tmcd / 0x64636D74 

您应该能够始终如一地安全地查找Duration: hh:mm:ss.nn以确定源video剪辑的大小。 然后,对于每个更新行(CR,没有LF),您可以parsing当前时间标记的文本:

 frame= 84 fps= 18 q=10.0 size= 5kB time=1.68 bitrate= 26.1kbits/s frame= 90 fps= 17 q=10.0 size= 6kB time=1.92 bitrate= 23.8kbits/s frame= 94 fps= 16 q=10.0 size= 232kB time=2.08 bitrate= 913.0kbits/s 

只是因为不能总是期待这些状态线的完美输出。 他们可以包含像这样的错误消息:

 frame= 24 fps= 24 q=-1.0 size= 0kB time=1.42 bitrate= 0.3kbits/s frame= 41 fps= 26 q=-1.0 size= 0kB time=2.41 bitrate= 0.2kbits/s [h264 @ 0x1013000]Cannot parallelize deblocking type 1, decoding such frames in sequential order frame= 49 fps= 24 q=26.0 size= 4kB time=0.28 bitrate= 118.1kbits/s frame= 56 fps= 22 q=23.0 size= 4kB time=0.56 bitrate= 62.9kbits/s 

一旦你有时间,这是简单的math: time / durration * 100 = % done

并非所有格式都存储了帧数或总持续时间 – 即使这样做,文件也可能不完整 – 所以ffmpeg在默认情况下不会准确地检测到它们中的任何一个。

相反,尝试查找文件的结尾并读取时间,然后计算当前时间。

或者,您可以尝试AVFormatContext->nb_index_entries或检测的持续时间,这应该工作在至less未损坏的AVI / MOV或库FFMS2上,这可能太慢而不能用于进度条。

尝试像这样:

 ffmpeg -i "path to file" -f null /dev/null 

它将帧编号写入标准错误,因此您可以从中检索最后一帧。

您可以使用ffprobe通过以下命令获取帧号

  1. 第一种方法

ffprobe.exe -i video_name -print_format json -loglevel fatal -show_streams -count_frames -select_streams v

这告诉以json格式打印数据

select_streams v将告诉ffprobe只给我们videostream数据,如果你删除它,它也会给你audio信息

和输出将是一样的

 { "streams": [ { "index": 0, "codec_name": "mpeg4", "codec_long_name": "MPEG-4 part 2", "profile": "Simple Profile", "codec_type": "video", "codec_time_base": "1/25", "codec_tag_string": "mp4v", "codec_tag": "0x7634706d", "width": 640, "height": 480, "coded_width": 640, "coded_height": 480, "has_b_frames": 1, "sample_aspect_ratio": "1:1", "display_aspect_ratio": "4:3", "pix_fmt": "yuv420p", "level": 1, "chroma_location": "left", "refs": 1, "quarter_sample": "0", "divx_packed": "0", "r_frame_rate": "10/1", "avg_frame_rate": "10/1", "time_base": "1/3000", "start_pts": 0, "start_time": "0:00:00.000000", "duration_ts": 256500, "duration": "0:01:25.500000", "bit_rate": "261.816000 Kbit/s", "nb_frames": "855", "nb_read_frames": "855", "disposition": { "default": 1, "dub": 0, "original": 0, "comment": 0, "lyrics": 0, "karaoke": 0, "forced": 0, "hearing_impaired": 0, "visual_impaired": 0, "clean_effects": 0, "attached_pic": 0 }, "tags": { "creation_time": "2005-10-17 22:54:33", "language": "eng", "handler_name": "Apple Video Media Handler", "encoder": "3ivx D4 4.5.1" } } ] } 

2.你可以使用

 ffprobe -v error -show_format -show_streams video_name 

这将给你stream数据,如果你想select像帧速率的信息,使用下面的命令

 ffprobe -v error -select_streams v:0 -show_entries stream=avg_frame_rate -of default=noprint_wrappers=1:nokey=1 video_name 

它给你的video信息的数字基础上,问题是当你使用这种方法,它可能会得到一个N/A作为输出。

欲了解更多信息,请查看此页FFProbe提示

尝试这个:

 ffmpeg -i "path to file" -f null /dev/null 2>&1 | grep 'frame=' | cut -f 2 -d ' ' 

build立在斯图的答案上。 这是我如何find我的手机video的帧速率。 我跑了一段时间以下的命令。 在让我不耐烦的时候,我让帧数达到了大概一万人左右,

 $ ffmpeg -i 2013-07-07\ 12.00.59.mp4 -f null /dev/null 2>&1 ... Press [q] to stop, [?] for help [null @ 0x7fcc80836000] Encoder did not produce proper pts, making some up. frame= 7989 fps= 92 q=0.0 Lsize=N/A time=00:04:26.30 bitrate=N/A dup=10 drop=0 video:749kB audio:49828kB subtitle:0 global headers:0kB muxing overhead -100.000042% Received signal 2: terminating. $ 

然后,我从该行以“frame =”,帧数7989,以及时间00:04:26.30开始抓取两条信息。 您首先需要将时间转换为秒,然后将秒数除以得到“帧/秒”。 “每秒帧数”是您的帧速率。

 $ bc -l 0*60*60 + 4*60 + 26.3 266.3 7989/(4*60+26.3) 30.00000000000000000000 $ 

我的video的帧率是30帧/秒。

我使用php_ffmpeg,然后我可以得到所有的时间和电影的所有帧。 如下所示

 $input_file='/home/strone/workspace/play/CI/abc.rmvb'; $ffmpegObj = new ffmpeg_movie($input_file); echo $ffmpegObj->getDuration(); echo $ffmpegObj->getFrameCount(); 

然后详细信息在页面上。

http://ffmpeg-php.sourceforge.net/doc/api/ffmpeg_movie.php

我能做到的唯一准确的是:

 ffprobe -i my_video.mp4 -show_frames 2>&1|grep -c '^\[FRAME' 

为了确保这与video工作:

 ffprobe -i my_video.mp4 -show_frames 2>&1 | grep -c media_type=video 

对不起,necro的答案,但也许会需要(因为我没有find最新的ffmpeg发布的解决scheme。

用ffmpeg 3.3.4我发现可以用以下find:

 ffprobe -i video.mp4 -show_streams -hide_banner | grep "nb_frames" 

最后它会输出帧数。 它适用于我的video与audio。 虽然它提供了两倍的“nb_frames”行,但是第一行是我testing的video的实际帧数。