ffprobe/ffmpeg 报告通过标准输入提供文件时的不同视频持续时间

ffprobe/ffmpeg reports different video duration when file given via stdin

我正在尝试使用 ffmpeg 确定 MP4 视频的持续时间,这当然是可能的,除了当数据通过 stdin 流式传输时(在我的情况下是一个要求)报告的持续时间小于它实际上是。我和ffprobe有同样的问题。

视频的实际长度约为 13 秒。

下面是我使用 ffprobe 收到的输出示例。

正在从磁盘读取文件(正确的持续时间):

$ ffprobe video.mp4
...
Duration: 00:00:13.05, start: 0.000000, bitrate: 736 kb/s
...

在文件中流式传输(持续时间不正确):

$ cat video.mp4 | ffprobe -i -
...
Duration: 00:00:08.40, start: 0.080000, bitrate: N/A
...

如何让 ffprobe 报告正确的持续时间,同时通过标准输入在文件中进行流式传输?

您可以使用 ffprobe 的 -show_packets 选项,它将“显示有关输入多媒体流中包含的每个数据包的信息”。 (Read about it in the ffprobe docs.)

使用此选项,ffprobe 将为流中的每个数据包输出一个条目,如下所示:

dts_time=13.008000

所以我们可以 grep dts_time:

的输出
$ cat video.mp4 | ffprobe -i - -show_packets | grep dts_time
...
dts_time=13.008000
dts_time=13.029333

输出的最后一行将包含最后一个数据包的时间戳,可以将其视为视频的持续时间,因此我们可以这样做:

$ cat video.mp4 \
    | ffprobe -i - -show_packets -v quiet \
    | grep dts_time \
    | tail -n 1 \
    | awk -F"=" '{print }'
13.029333

您输入的 MP4 看起来是碎片化的,在这种情况下,ffmpeg 将在第一个碎片 moof 框之后停止探测,并报告其持续时间。这不是普通 MP4 的问题。

您可以 运行 cat fragmented.mp4 | ffmpeg -i - -c copy -f null - 2>&1 | grep -oP "(?<=time=)[\d:\.]+" 此类文件。