daner1257

1、 前言


ffprobe是ffmpeg的其中一个模块,主要用于查看文件信息,咱们知道一个MP4文件其实不仅仅包含了音视频数据,还有如元数据等其它信息,但是实际上咱们关心的往往是音视频数据部分,今天来看下如何使用ffprobe来获取音视频信息。
先看看ffprobe的帮助信息
ffprobe -v error --help
在输出的信息中,有这一行
-sections print sections structure and section information, and exit
可以看看具体作用是什么
ffprobe -v error -sections test.mp4
输出如下

Sections:
W.. = Section is a wrapper (contains other sections, no local entries)
.A. = Section contains an array of elements of the same type
..V = Section may contain a variable number of fields with variable keys
FLAGS NAME/UNIQUE_NAME
---
W..   root
.A.      chapters
...          chapter
..V              tags/chapter_tags
...      format
..V          tags/format_tags
.A.      frames
...          frame
..V              tags/frame_tags
.A.              side_data_list/frame_side_data_list
...                  side_data/frame_side_data
.A.                      timecodes
...                          timecode
.A.                      components
...                          component
.A.                              pieces
...                                  section
.A.              logs
...                  log
...          subtitle
.A.      programs
...          program
..V              tags/program_tags
.A.              streams/program_streams
...                  stream/program_stream
...                      disposition/program_stream_disposition
..V                      tags/program_stream_tags
.A.      streams
...          stream
...              disposition/stream_disposition
..V              tags/stream_tags
.A.              side_data_list/stream_side_data_list
...                  side_data/stream_side_data
.A.      packets
...          packet
..V              tags/packet_tags
.A.              side_data_list/packet_side_data_list
...                  side_data/packet_side_data
...      error
...      program_version
.A.      library_versions
...          library_version
.A.      pixel_formats
...          pixel_format
...              flags/pixel_format_flags
.A.              components/pixel_format_components
...                  component

其实打印的是一个视频文件在ffmpeg眼中的大致结构:顶层是root,下面有chapters、frames、streams等。

2、 如何采集视频信息


而如果你仔细看ffprobe -v error --help命令打印出来的日志,就会发现上面的这些结构一一对应了一个命令参数,拿chapters举例,可以发现help命令打印出来包含有这个参数:-show_chapters
所以,咱们可以从这个角度来看下如何获取文件信息,先试一下前面提到的chapters部分
ffprobe -v error -show-chapters -of json test.mp4
输出如下:

{
    "chapters": [

    ]
}

虽然没有信息,但是ffprobe确实是打印了信息出来,咱们换一个section
ffprobe -v error -show-streams -of json test.mp4
这时你就会发现这次将视频文件的每一个数据流的信息打印了出来,考虑到篇幅,这里只将视频流的一部分数据贴出来

{
    "streams": [
        {
            "index": 0,
            "codec_name": "h264",
            "codec_long_name": "H.264 / AVC / MPEG-4 AVC / MPEG-4 part 10",
            "profile": "Main",
            "codec_type": "video",
            "codec_tag_string": "avc1",
            "codec_tag": "0x31637661",
            "width": 640,
            "height": 360,
            "coded_width": 640,
            "coded_height": 360,
            "closed_captions": 0,
            "film_grain": 0,
            "has_b_frames": 0,
            "sample_aspect_ratio": "1:1",
            "display_aspect_ratio": "16:9",
            "pix_fmt": "yuv420p",
            "level": 30,
            "chroma_location": "left",
            "field_order": "progressive",
            "refs": 1,
            "is_avc": "true",
            "nal_length_size": "4",
            "id": "0x1",
            "r_frame_rate": "24/1",
            "avg_frame_rate": "24/1",
            "time_base": "1/12288",
            "start_pts": 0,
            "start_time": "0.000000",
            "duration_ts": 124928,
            "duration": "10.166667",
            "bit_rate": "2004518",
            "bits_per_raw_sample": "8",
            "nb_frames": "244",
            "extradata_size": 48
        }
}

可以看到,视频流中诸如分辨率、帧率等参数的详细信息都罗列了出来。
除了-show_streams参数,大家可以试试其它的参数-show_format-show_frames-show_packets 看看具体的效果

3、 show_entries


这里再说一个比较有用的参数:-show_entries,这个参数的作用你可以理解为一个选择器,选择要打印哪些数据流的参数.
以上面打印出来的视频流信息为例,假如咱们只想知道视频的分辨率,该怎么办?这时候就可以用-show_entries了:
ffprobe -v error -show_entries stream=width,height -of json test.mp4
打印如下:

    "programs": [

    ],
    "streams": [
        {
            "width": 640,
            "height": 360
        },
        {

        }
    ]
}

可以看到,只把分辨率的信息打印了出来,唯一的问题是同时也打印了一些空白数据- -

4、 多section信息拼接


另外如果想既打印stream信息,又打印format信息怎么办呢,对于不同的section,可以使用:来区分,如下面这样
ffprobe -v error -show_entries stream=width,height:format=nb_streams -of json test.mp4
实际输出如下:

{
    "programs": [

    ],
    "streams": [
        {
            "width": 640,
            "height": 360
        },
        {

        }
    ],
    "format": {
        "nb_streams": 2
    }
}

这样就输出了两个section的信息

5、附录


最后说两个比较有用的参数

-count_frames:计算所有的frame,也就是有效的视频帧,当添加了该参数后,stream信息中,会多出nb_read_frames参数
-count_packets:计算所有的packet,当添加了该参数后,stream信息中,会多出nb_read_packets参数

ffmpeg系列文章目录

ffmpeg第1篇:日志级别控制、保存日志到指定文件、处理进度查询
ffmpeg第2篇:简单滤镜与复杂滤镜的区别
ffmpeg第3篇:为视频添加静态水印
ffmpeg第4篇:为视频添加动态水印
ffmpeg第5篇:让水印图片旋转起来
ffmpeg第6篇:滤镜语法
ffmpeg第7篇:数据流选择神器-map指令
ffmpeg第8篇:使用ffprobe采集文件信息

番外篇

ffmpeg番外篇:听说这款水印曾经在某音很火?办它!

有问题请留言沟通,欢迎转载,转载请注明出处

欢迎点击个人博客地址:愉快编程

相关文章: