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採集文件信息