以友好的方式获取FFmpeg信息

135

每次我尝试用ffmpeg获取一些关于我的视频文件的信息时,它会输出许多混杂了有用和无用信息的东西。

我使用的命令是ffmpeg -i name_of_the_video.mpg

有没有可能以更友好的方式获得这些信息呢?我的意思是JSON格式将是很棒的选择(甚至丑陋的XML也可以)。

目前为止,我让我的应用程序通过正则表达式解析数据,但是对于特定的视频文件,有很多困难的角落。 我已经解决了所有遇到的问题,但还可能有更多。

我希望能够得到像这样的内容:

{
  "Stream 0": {
     "type": "Video",
     "codec": "h264",
     "resolution": "720x480"
  },
  "Stream 1": {
     "type": "Audio",
     "bitrate": "128 kbps",
     "channels": 2
  }
}

4
你看过ffprobe吗?它似乎提供了一个可读的JSON输出。 - NT3RP
我已经看过了,但是找不到JSON输出格式。 - JBernardo
4个回答

322

可能有些晚了,但或许对某些人仍然有用。

ffprobe 确实是一个很好的选择。不过需要注意的是,你需要告诉 ffprobe 你想要它显示哪些信息(使用 -show_format-show_packets-show_streams 参数),否则它会输出空白(就像你在评论中提到的那样)。

例如,ffprobe -v quiet -print_format json -show_format -show_streams somefile.asf 将会产生类似以下的输出:

{
  "streams": [{
    "index": 0,
    "codec_name": "wmv3",
    "codec_long_name": "Windows Media Video 9",
    "codec_type": "video",
    "codec_time_base": "1/1000",
    "codec_tag_string": "WMV3",
    "codec_tag": "0x33564d57",
    "width": 320,
    "height": 240,
    "has_b_frames": 0,
    "pix_fmt": "yuv420p",
    "level": -99,
    "r_frame_rate": "30000/1001",
    "avg_frame_rate": "0/0",
    "time_base": "1/1000",
    "start_time": "0.000",
    "duration": "300.066",
    "tags": {
        "language": "eng"
    }
  }],
  "format": {
    "filename": "somefile.asf",
    "nb_streams": 1,
    "format_name": "asf",
    "format_long_name": "ASF format",
    "start_time": "0.000",
    "duration": "300.066",
    "tags": {
        "WMFSDKVersion": "10.00.00.3646",
        "WMFSDKNeeded": "0.0.0.0000",
        "IsVBR": "0"
    }
  }
}

3
如果有人需要,我已经根据那个答案编写了一个基于PHP的解决方案:https://dev59.com/PGbWa4cB1Zd3GeqPbebY - Paulo Freitas
1
抱歉挖出这个问题,但有没有可能加快速度? 它需要5-6秒才能显示输出。 - mangia
我的应用程序在使用ffprob命令时关闭而没有显示任何消息!为什么?但是ffmpeg正常工作。 - farhad.kargaran
6
在一个回答已有4年历史的评论区提问,几乎没有被回答的可能性。 - patrick
3
你也可以使用-of json代替-print_format json。前者兼容avprobe,而后者则不兼容。 - Chih-Hsuan Yen
显示剩余6条评论

23

现在可以使用-progress -来打印以key=value格式排版的友好信息。

ffmpeg  -i video.mp4 .......-s 1920x1080 -progress - -y out.mp4

speed=5.75x
frame=697
fps=167.7
stream_0_0_q=39.0
bitrate=2337.0kbits/s
total_size=6979778
out_time_ms=23893333
out_time=00:00:23.893333
dup_frames=0
drop_frames=0

5
知道了。我想知道为什么这没有在文档中提到。 - Duvrai
这很好!“-progress -”没有在文档中提到的原因是“-”只是将其管道传输到标准输出。 - Chris W
它是否还打印持续时间? - Kemal Ahmed
为了只显示进度,最好添加-v quiet-v error以防止其他日志“污染”标准输出。 - kpostekk

13

你可以尝试使用ffprobe。获取JSON输出的正确命令应如下所示:

ffprobe ... -print_format json

2
我编译了最新的ffmpeg,但程序的json输出只有{}。它似乎无法处理我拥有的视频文件... - JBernardo
3
嗨,@JBernardo,如果其他人也遇到了这个问题,你需要使用-print_format而不是-of参数,否则它只会输出一个非常没有用的{...普通打印输出在这里...},请查看被采纳的答案获取一个示例命令行。 - mgrandi

4

ffprobe 的另一种使用方式,可以很好地解析:

ffprobe -v error -select_streams v:0 -show_entries stream=width,height,r_frame_rate,bit_rate,codec_name,duration -of csv=p=0:s=x video.mp4

结果为:

h264x600x480x25/1x385.680000x542326

-select_streams v:0 选择仅第一个视频流。如果您删除该参数,则会为每个流获取一行。


s=x 设置了在使用 csv 输出格式时分隔字段的字符。当需要获取类似于 1280x720 的输出时,可以很方便地使用它来请求 width,height。否则会非常丑陋。如果删除 :s=x,则默认为逗号,或者您可以始终使用不同的 -of 类型,例如 json。 - llogan

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接