如何在Linux命令行上获取视频中的帧数?


30

我有一个视频文件,我想获取其中的视频帧数。我可以ffmpeg用来获取视频和FPS的长度。但是,对于总帧数,我看不到任何明显的东西。

从理论上讲,应该可以将长度(以秒为单位)乘以FPS来获得帧数,但是在这种情况下,长度(34.43秒)和帧速率(29.97 fps)给出的是非整数,这使我认为我做错了。

我需要能够以完全自动化且非图形的方式在命令行上执行此操作。我还需要做到这一点非常准确,而不是估算值(如果使用视频文件甚至可以估算)

我尝试tcprobe在某些文件上使用。对于某些AVI文件,它可以工作,但对于某些VOB文件,tcprobe输出没有帧数。我得到以下输出:

[tcprobe] MPEG program stream (PS)
[tcprobe] summary for myfile.vob, (*) = not default, 0 = not detected
import frame size: -g 720x480 [720x576] (*)
     aspect ratio: 4:3 (*)
       frame rate: -f 29.970 [25.000] frc=4 (*)
                   PTS=2199.3972, frame_time=33ms bitrate=7000 kbps
      audio track: -a 0 [0] -e 48000,16,5 [48000,16,2] -n 0x2000 [0x2000] (*)
                   PTS=2199.2763, bitrate=192 kbps
                   -D 3 --av_fine_ms 20 (frames & ms) [0] [0]

您的方程将为您提供良好的估算;仅将浮点运算结果四舍五入。如果您需要准确的帧数,则需要直接检查文件-由于视频编解码器的特殊性,您的估计值可能会在任一方向上偏离一到两个。
嘎嘎吉x德09年

这些全合一文件的VOB或DVD样式的拆分成多个文件的VOB?
quack quixote 09年

Answers:


17

这是可怕的,愚蠢的,缓慢的,但似乎可行:

ffmpeg -i foo.avi -vcodec copy -f rawvideo -y /dev/null 2>&1 | tr ^M '\n' | awk '/^frame=/ {print $2}'|tail -n 1

它也可以在截断的文件和原始流上正常工作(这就是为什么.vob文件什么都看不到的原因)


很好 以我的经验,并不需要很长时间。但是,一个40分钟的文件大约需要3秒才能运行。请记住,“ ^ M”不是2个字符^和M,必须按Control-V,然后输入。我使用的不是您的命令:ffmpeg -i somefile.avi -vcodec copy -f rawvideo -y / dev / null 2>&1 | tr“ ^ M”'\ n'| grep'^ frame ='| perl -pe's / ^ frame = \ s *([0-9] +)\ s。* $ / \ 1 /'| tail -n 1如果在“ frames =“之后没有空格,您的命令将失败
Rory 2010年

1
在Ubuntu 12.04中,ffmpeg版本git-2013-04-15-a4f03f0可以省略| tr ^M '\n'|tail -n 1。而且,之后没有空间frames=不会失败。(也许在过去四年中有所改变。)
卡米尔·古德塞内

对我来说,每次返回不同的值时
都会

1
Mediainfo解决方案可与VOB一起使用。我建议您这样做。root @ lanparty:/ mnt / films#mediainfo --fullscan Bugs_Bunny.vob | grep -i frame \ count帧数:175715帧数:183218
kevinf

32

ffprobe 可以用来获取有关媒体文件的信息:

ffprobe -select_streams v -show_streams input.avi

您将获得有关流的详细信息:

nb_frames=159697

寻找nb_framesgrep

ffprobe -select_streams v -show_streams input.avi 2>/dev/null | grep nb_frames | sed -e 's/nb_frames=//'

适用于avi,mp4等。对于某些容器,它不显示有效值,例如mpeg。

在这种情况下,这可行 ffprobe -show_packets a.mpg 2>/dev/null | grep video | wc -l


好主意。我对命令做了一些修改,以便仅选择视频流并过滤输出。这样就可以得到帧数。
slhck 2014年

1
恭喜您的第二个解决方案适用于MPEG-2!
malat

1
它不适用于MKV容器。
恩克·阿尔蒂,2015年

1
nb_frames =此文件上的N / A:web.archive.org/web/20180117220713/http://techslides.com/demos / ...
西罗桑蒂利新疆改造中心法轮功六四事件

似乎第一种方法在VBR编码的文件上失败。第二种方法更可靠。
极客长老

16

我把这个贴在另一个问题上。使用该tcprobe工具(来自transcode包装),帧数包含在信息中。使用-i开关从文件中获取信息转储:

$ tcprobe -i foo.avi
[tcprobe] RIFF data, AVI video
[avilib] V: 29.970 fps, codec=XVID, frames=38630, width=512, height=384
[avilib] A: 48000 Hz, format=0x55, bits=16, channels=2, bitrate=128 kbps,
[avilib]    53707 chunks, 21768720 bytes, VBR
[tcprobe] summary for foo.avi, (*) = not default, 0 = not detected
import frame size: -g 512x384 [720x576] (*)
       frame rate: -f 29.970 [25.000] frc=4 (*)
      audio track: -a 0 [0] -e 48000,16,2 [48000,16,2] -n 0x55 [0x2000] (*)
                   bitrate=128 kbps
           length: 38630 frames, frame_time=33 msec, duration=0:21:28.954

请注意,此处的帧数在两行上给出(第二个输出行和最后一个输出行)。


这看起来是一个很好的答案,并且适用于某些文件,但是对于某些我拥有的VOB文件,我的输出中没有该数据。我已经用输出更新了问题
Rory

我期望(但不确定)tcprobe正在检查此信息的文件头。如果它不包含在标题中,则tcprobe可能不会尝试对其进行计算。好问题; 希望我对你有一个好的答复。
quack quixote

这对VBR编码的文件似乎不起作用,但没有帧计数输出。我确实获得了分辨率,宽高比和帧频。
极客长老

7

我发现mediainfo --fullscan inputfile | grep "Frame count"它对大多数文件都很好用。

基于Debian的系统可以使用 apt-get install mediainfo

如果得到2行而不是输出之一,则第一行是视频轨道,第二行是音频轨道。看来这发生在具有可变比特率音频的文件上。

自编辑之日起对.mkv,.m4v,.mp4,flv,vob和.avi样本进行了测试。

来源:如何在Linux下从命令行检索视频文件信息?并在Ubuntu风格下进行测试。

您可以在此处找到适用于您的操作系统的mediainfo


4

ffprobe -select_streams v -show_frames -count_frames INPUT_FILE | grep pkt_duration_time =

加总持续时间。可能对sed / awk更感兴趣,而其他方面则不然。

从我们的测试中我可以说,到目前为止,它已被证明是最可靠的。您将获得准确的帧数和确切的持续时间。即使具有可变的帧速率,所有其他工具(例如mediainfo)似乎也变得流行起来。


3

我发现帧数实际上是fps *持续时间的两倍(不知道为什么,我很高兴知道)。

在我的脚本中,我有:

# Get duration and fps
duration=$($FFMPEG -i $input 2>&1 | sed -n "s/.* Duration: \([^,]*\), start: .*/\1/p")
fps=$($FFMPEG -i $input 2>&1 | sed -n "s/.*, \(.*\) tb.*/\1/p")

hours=$(echo $duration | cut -d":" -f1)
minutes=$(echo $duration | cut -d":" -f2)
seconds=$(echo $duration | cut -d":" -f3)
# For some reason, we have to multiply by two (no idea why...)
# Get the integer part with cut
frames=$(echo "($hours*3600+$minutes*60+$seconds)*$fps*2" | bc | cut -d"." -f1)

是的,由于某种原因,我必须得到它的整数部分。这没有任何意义,但是到目前为止,此脚本始终可以正确转换我的视频。


因为FPS代表每秒帧数(或第一人称射击者:D),并且如果有30 FPS,只需将其乘以视频中的秒数即可。
约翰T

是的,约翰,我可以弄清楚,但这并不能解释为什么我必须将其乘以2才能获得正确的帧数...就我而言,在计算完帧数之后,我在ffmpeg中启动了并分析日志以制作进度条。日志显示转换中已传递了多少帧。一旦整个视频被转换,帧#为INT(秒* FPS * 2),因此我的代码,但我想知道为什么;-)
ℝaphink

很好奇 tcprobe我的答案中的输出给出的帧数精确为秒* fps(四舍五入)。我希望您能看到ffmpeg的怪癖。您是否尝试过使用其他工具分析文件以查看它们是否显示相同数量的帧?
嘎嘎吉x德09年

嗯...有趣。我试了一个视频,我得到了seconds*fps=1001.59tcprobe=1002。所以很明显,tcprobe告诉我,我不需要乘以2。为什么ffmpeg在转换时会给我一个两倍大的数字?
ℝaphink

2
是隔行录像吗?如果是这样,则每帧有两个字段,这可能为您提供了字段数。
stib 2014年

3

在Ubuntu上测试。

melt icecap.mp4 -consumer xml
  • melt-melt原本是MLT框架的测试工具,但它还是一款功能强大的面向多轨命令行的视频编辑器。它也可以用作音频和视频文件的简约媒体播放器。

  • -consumerid [:arg] [name = value] *
    设置使用者(接收器)

  • xml -将使用者(接收器)设置为xml格式的输出

  • <property name="length">nnnn</property>-显示帧数,其中nnnn用等于帧数的整数代替

如果您没有融化,可以使用以下命令在Ubuntu和其他基于Debian的系统上安装 sudo apt-get install melt


1
这很短,您想扩展它的作用,为什么起作用等等吗?
戴维(David)

这在无法通过提供帧数的h264 mp4文件上效果很好mediainfo -fullscan filename
极客长老

3

直接使用mediainfo,无需grep,无需等待,无需任何操作:

mediainfo --Inform='Video;%FrameCount%' $the_file

有关其他信息,请参见 mediainfo --info-parameters


0

您可以通过添加和乘以从ffprobe获得的值来实现。

注意:ffprobe是libav(avconv)的一部分-libmpeg的Linux版本。

#your command -
 ffprobe man.avi

当您这样做时,您将获得每秒的帧数以及剪辑的持续时间。

将剪辑的持续时间转换为秒,然后将该值乘以每秒的帧数。

请记住将数字四舍五入到最接近的值。


在Ubuntu 14.04 LTS ffprobe是不可用的,但有一些所谓avprobelibav-tools(也提供avconv)。但是在我这边,它不会打印任何数量的帧,至少不会打印出我尝试过的格式。它只是打印,也打印什么avprobe -i,可悲的是,这只是关于格式的一些小细节。即使这样,-v debug它也只能告诉我所安装的硬件和软件的一些不错的属性,而不能告诉我一些有关要探测的文件/流的有趣信息。也许它隐藏了许多可用的选项。谁知道?
蒂诺2015年

实际上,@ Tino ffprobe是ffmpeg软件包的一部分。avconv是ffmpeg的一个分支,引起了一些混乱。请参阅:stackoverflow.com/questions/9477115/...
野人长老

@ElderGeek对于Ubuntu 14.04 LTS ffmpeg,官方存储库中没有此文件。您提供的链接正确指出了它:FFmpeg在Ubuntu 15.04“ Vivid Vervet”中返回。。但是现在情况发生了变化,因为16.04 LTS失效了。
蒂诺

@Tino确实是事实。但是,我不会将不可用等同于存储库中不存在。您会在此处注意到可用于Trusty(14.04):ffmpeg.org/download.html
Geek Elder


-2

最佳方法:(直接通过计算正确的参数,由ffmpeg确认)

Cmd->

ffprobe.exe -v error -select_streams v:0 -show_entries stream=r_frame_rate,duration -of default=nw=1 "d:\movies\The.Matrix.1999.1080p.BrRip.x264.YIFY.dut.mp4"

结果->

r_frame_rate=24000/1001
duration=8177.794625

计算->

Frames=24000/1001*8177.794625=196071 (exactly... ;P)

证明->

ffmpeg -i "d:\movies\The.Matrix.1999.1080p.BrRip.x264.YIFY.dut.mp4" -f 

null /dev/null
ffmpeg version N-92938-g0aaaca25e0-ffmpeg-windows-pacman Copyright (c) 2000-2019 the FFmpeg developers
  built with gcc 8.2.0 (GCC)
  configuration: --pkg-config=pkg-config --pkg-config-flags=--static --extra-version=ffmpeg-windows-pacman --enable-version3 --disable-debug --disable-w32threads --arch=x86_64 --target-os=mingw32 --cross-prefix=/opt/sandbox/cross_compilers/mingw-w64-x86_64/bin/x86_64-w64-mingw32- --enable-libcaca --enable-gray --enable-libtesseract --enable-fontconfig --enable-gmp --enable-gnutls --enable-libass --enable-libbluray --enable-libbs2b --enable-libflite --enable-libfreetype --enable-libfribidi --enable-libgme --enable-libgsm --enable-libilbc --enable-libmodplug --enable-libmp3lame --enable-libopencore-amrnb --enable-libopencore-amrwb --enable-libopus --enable-libsnappy --enable-libsoxr --enable-libspeex --enable-libtheora --enable-libtwolame --enable-libvo-amrwbenc --enable-libvorbis --enable-libvpx --enable-libwebp --enable-libzimg --enable-libzvbi --enable-libmysofa --enable-libaom --enable-libopenjpeg --enable-libopenh264 --enable-liblensfun --enable-nvenc --enable-nvdec --extra-libs=-lm --extra-libs=-lpthread --extra-cflags=-DLIBTWOLAME_STATIC --extra-cflags=-DMODPLUG_STATIC --extra-cflags=-DCACA_STATIC --enable-amf --enable-libmfx --enable-gpl --enable-avisynth --enable-frei0r --enable-filter=frei0r --enable-librubberband --enable-libvidstab --enable-libx264 --enable-libx265 --enable-libxvid --enable-libxavs --enable-avresample --extra-cflags='-march=core2' --extra-cflags=-O2 --enable-static --disable-shared --prefix=/opt/sandbox/cross_compilers/mingw-w64-x86_64/x86_64-w64-mingw32 --enable-nonfree --enable-decklink --enable-libfdk-aac
  libavutil      56. 25.100 / 56. 25.100
  libavcodec     58. 43.100 / 58. 43.100
  libavformat    58. 25.100 / 58. 25.100
  libavdevice    58.  6.101 / 58.  6.101
  libavfilter     7. 47.100 /  7. 47.100
  libavresample   4.  0.  0 /  4.  0.  0
  libswscale      5.  4.100 /  5.  4.100
  libswresample   3.  4.100 /  3.  4.100
  libpostproc    55.  4.100 / 55.  4.100
Input #0, mov,mp4,m4a,3gp,3g2,mj2, from 'd:\movies\The.Matrix.1999.1080p.BrRip.x264.YIFY.dut.mp4':
  Metadata:
    major_brand     : isom
    minor_version   : 512
    compatible_brands: isomiso2avc1mp41
    encoder         : Lavf58.25.100
  Duration: 02:16:17.91, start: 0.000000, bitrate: 2497 kb/s
    Stream #0:0(und): Video: h264 (High) (avc1 / 0x31637661), yuv420p, 1920x800 [SAR 1:1 DAR 12:5], 2397 kb/s, 23.98 fps, 23.98 tbr, 24k tbn, 47.95 tbc (default)
    Metadata:
      handler_name    : VideoHandler
    Stream #0:1(und): Audio: aac (LC) (mp4a / 0x6134706D), 44100 Hz, stereo, fltp, 93 kb/s (default)
    Metadata:
      handler_name    : GPAC ISO Audio Handler
Stream mapping:
  Stream #0:0 -> #0:0 (h264 (native) -> wrapped_avframe (native))
  Stream #0:1 -> #0:1 (aac (native) -> pcm_s16le (native))
Press [q] to stop, [?] for help
Output #0, null, to '/dev/null':
  Metadata:
    major_brand     : isom
    minor_version   : 512
    compatible_brands: isomiso2avc1mp41
    encoder         : Lavf58.25.100
    Stream #0:0(und): Video: wrapped_avframe, yuv420p, 1920x800 [SAR 1:1 DAR 12:5], q=2-31, 200 kb/s, 23.98 fps, 23.98 tbn, 23.98 tbc (default)
    Metadata:
      handler_name    : VideoHandler
      encoder         : Lavc58.43.100 wrapped_avframe
    Stream #0:1(und): Audio: pcm_s16le, 44100 Hz, stereo, s16, 1411 kb/s (default)
    Metadata:
      handler_name    : GPAC ISO Audio Handler
      encoder         : Lavc58.43.100 pcm_s16le

这里

frame=196071 fps=331 q=-0.0 Lsize=N/A time=02:16:17.90 bitrate=N/A speed=13.8x

输出量

video:102631kB audio:1408772kB subtitle:0kB other streams:0kB global headers:0kB muxing overhead: unknown
shareeditdeleteflag

我得到r_frame_rate = 25/1持续时间= N / A
怪杰长老
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.