我有一个视频文件,我想获取其中的视频帧数。我可以使用这个函数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]
答案1
这很可怕、愚蠢而且缓慢,但似乎有效:
ffmpeg -i foo.avi -vcodec copy -f rawvideo -y /dev/null 2>&1 | tr ^M '\n' | awk '/^frame=/ {print $2}'|tail -n 1
它也可以正确处理截断的文件和原始流(这就是为什么 .vob 文件什么都得不到的原因)
答案2
ffprobe
可用于获取有关媒体文件的信息:
ffprobe -select_streams v -show_streams input.avi
您将获得有关该流的详细信息:
nb_frames=159697
查找:nb_frames
grep
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
答案3
我发布于另一个问题。使用该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
请注意,这里两行给出了帧数(第二行输出和最后一行输出)。
答案4
直接使用mediainfo
,无需 grep,无需等待,无需任何操作:
mediainfo --Inform='Video;%FrameCount%' $the_file
其他信息请参阅mediainfo --info-parameters