目录
前言
FFmpeg是一个完整的跨平台音视频解决方案,它可以用于处理音频和视频的转码、录制、流化处理等应用场景。官网:http://ffmpeg.org/。FFmpeg有三大利器,分别是ffmpeg、ffprobe、ffplay。今天主要介绍ffprobe,它是FFmpeg用于查看媒体文件格式信息的强大工具。
实战
分析音频
话不多说,先来看ffprobe的简单使用实例:
ffprobe 少年.mp3
在 少年.mp3 文件的同级目录运行上述命令,会有如下输出信息:
[mp3 @ 0x7fdf85801400] Skipping 0 bytes of junk at 417.
Input #0, mp3, from '少年.mp3':
Duration: 00:03:56.15, start: 0.025057, bitrate: 128 kb/s
Stream #0:0: Audio: mp3, 44100 Hz, stereo, s16p, 128 kb/s
Metadata:
encoder : LAME3.99r
Side data:
replaygain: track gain - -8.000000, track peak - unknown, album gain - unknown, album peak - unknown,
它们都是什么意思呢?我们接下来逐行分析一下,首先看第一行:
Duration: 00:03:56.15, start: 0.025057, bitrate: 128 kb/s
表明了音频文件(少年.mp3)的主要信息,音乐时长是3分56.15秒,开始播放声音的时间是0.025057秒,码率是128kb/s。
接下来看下一行:
Stream #0:0: Audio: mp3, 44100 Hz, stereo, s16p, 128 kb/s
表明音频文件只有一路音频流,音频编码格式是mp3,采样率是44.1kHz,声道数是立体声双声道,采样格式是16位的平铺格式,码率是128kb/s。
再看下一行:
Metadata:
encoder : LAME3.99r
表明音频文件的音频编码器是LAME,版本号是3.99r,LAME 是最好的MP3编码器,一段时间内被业界认为是编码高品质MP3的最好也是唯一的选择。如果想具体了解LAME,可以点这里。
分析视频
接下来,我们看一个视频文件,自己比较喜欢的凉凉的MV。
运行如下命令:
ffprobe 凉凉-MV.mp4
命令执行结果,输出内容如下:
Input #0, mov,mp4,m4a,3gp,3g2,mj2, from '凉凉-MV.mp4':
Metadata:
major_brand : mp42
minor_version : 0
compatible_brands: mp42isom
creation_time : 2018-06-21 06:42:54
Duration: 00:03:24.13, start: 0.000000, bitrate: 507 kb/s
Stream #0:0(und): Audio: aac (LC) (mp4a / 0x6134706D), 44100 Hz, stereo, fltp, 64 kb/s (default)
Metadata:
creation_time : 2018-06-21 06:42:54
Stream #0:1(und): Video: h264 (High) (avc1 / 0x31637661), yuv420p, 640x368, 439 kb/s, 23 fps, 23 tbr, 90k tbn, 46 tbc (default)
Metadata:
creation_time : 2018-06-21 06:42:54
encoder : JVT/AVC Coding
接下来我们看看这些信息的具体意思,先看第一行:
Input #0, mov,mp4,m4a,3gp,3g2,mj2, from '凉凉-MV.mp4':
表明视频文件的封装格式属于 mov,mp4,m4a,3gp,3g2,mj2 格式集合。
接下来看下一行:
Metadata:
major_brand : mp42
minor_version : 0
compatible_brands: mp42isom
creation_time : 2018-06-21 06:42:54
其中,major_brand表明视频文件属于mp4的子格式mp42,兼容格式有mp42isom,视频文件创建时间是2018年6月21日6时42分54秒,具体Metadata数据格式可以参考:
aligned(8) class FileTypeBox extends Box(‘ftyp’)
{
unsigned int(32) major_brand;
unsigned int(32) minor_version;
unsigned int(32) compatible_brands[]; // to end of the box
}
接下来看下一行:
Duration: 00:03:24.13, start: 0.000000, bitrate: 507 kb/s
表明视频文件时间长度是3分钟24.13秒,开始播放时间是0.0秒,视频码率是507kb/s。
继续分析下一行:
Stream #0:0(und): Audio: aac (LC) (mp4a / 0x6134706D), 44100 Hz, stereo, fltp, 64 kb/s (default)
Metadata:
creation_time : 2018-06-21 06:42:54
表明视频文件中包含一路音频流,音频编码格式是aac,采样率是44.1kHz,声道数是立体声双声道,采样格式是32位的平铺格式,码率是默认的64kb/s(注意:这里只是音频码率,总码率的一部分)。其中fltp具体格式可以参考:
static const SampleFmtInfo sample_fmt_info[AV_SAMPLE_FMT_NB] = {
[AV_SAMPLE_FMT_U8] = { .name = "u8", .bits = 8, .planar = 0, .altform = AV_SAMPLE_FMT_U8P },
[AV_SAMPLE_FMT_S16] = { .name = "s16", .bits = 16, .planar = 0, .altform = AV_SAMPLE_FMT_S16P },
[AV_SAMPLE_FMT_S32] = { .name = "s32", .bits = 32, .planar = 0, .altform = AV_SAMPLE_FMT_S32P },
[AV_SAMPLE_FMT_S64] = { .name = "s64", .bits = 64, .planar = 0, .altform = AV_SAMPLE_FMT_S64P },
[AV_SAMPLE_FMT_FLT] = { .name = "flt", .bits = 32, .planar = 0, .altform = AV_SAMPLE_FMT_FLTP },
[AV_SAMPLE_FMT_DBL] = { .name = "dbl", .bits = 64, .planar = 0, .altform = AV_SAMPLE_FMT_DBLP },
[AV_SAMPLE_FMT_U8P] = { .name = "u8p", .bits = 8, .planar = 1, .altform = AV_SAMPLE_FMT_U8 },
[AV_SAMPLE_FMT_S16P] = { .name = "s16p", .bits = 16, .planar = 1, .altform = AV_SAMPLE_FMT_S16 },
[AV_SAMPLE_FMT_S32P] = { .name = "s32p", .bits = 32, .planar = 1, .altform = AV_SAMPLE_FMT_S32 },
[AV_SAMPLE_FMT_S64P] = { .name = "s64p", .bits = 64, .planar = 1, .altform = AV_SAMPLE_FMT_S64 },
[AV_SAMPLE_FMT_FLTP] = { .name = "fltp", .bits = 32, .planar = 1, .altform = AV_SAMPLE_FMT_FLT },
[AV_SAMPLE_FMT_DBLP] = { .name = "dblp", .bits = 64, .planar = 1, .altform = AV_SAMPLE_FMT_DBL },
};
继续分析下一行:
Stream #0:1(und): Video: h264 (High) (avc1 / 0x31637661), yuv420p, 640x368, 439 kb/s, 23 fps, 23 tbr, 90k tbn, 46 tbc (default)
Metadata:
creation_time : 2018-06-21 06:42:54
encoder : JVT/AVC Coding
表明MV文件中还包含另一路视频流,视频编码格式是h264,子类型是high类型,颜色空间是yuv420p,分辨率是640*368,码率是439kb/s,帧率是23帧每秒,tbr也是帧率的意思,tbn表示时间精度是1/90k,即1s=90000时间单位,tbc是编码时间精度,即1s=46时间单位。
注意:这里有一个大家需要注意的地方,不说的话,大家很可能忽略。上边我们看到了整个视频文件的码率是507kb/s,其中音频码率是64kb/s,视频码率是439kb/s,发现没有64kb/s+439kb/s≈507kb/s。整体视频文件的码率=音频码率+视频码率。
如果想获取更多的媒体信息可以使用如下命令:
ffprobe -show_format 凉凉-MV.mp4
输出的结果比之前多了其他的format信息:
Input #0, mov,mp4,m4a,3gp,3g2,mj2, from '凉凉-MV.mp4':
Metadata:
major_brand : mp42
minor_version : 0
compatible_brands: mp42isom
creation_time : 2018-06-21 06:42:54
Duration: 00:03:24.13, start: 0.000000, bitrate: 507 kb/s
Stream #0:0(und): Audio: aac (LC) (mp4a / 0x6134706D), 44100 Hz, stereo, fltp, 64 kb/s (default)
Metadata:
creation_time : 2018-06-21 06:42:54
Stream #0:1(und): Video: h264 (High) (avc1 / 0x31637661), yuv420p, 640x368, 439 kb/s, 23 fps, 23 tbr, 90k tbn, 46 tbc (default)
Metadata:
creation_time : 2018-06-21 06:42:54
encoder : JVT/AVC Coding
[FORMAT]
filename=凉凉-MV.mp4
nb_streams=2
nb_programs=0
format_name=mov,mp4,m4a,3gp,3g2,mj2
format_long_name=QuickTime / MOV
start_time=0.000000
duration=204.130433
size=12957343
bit_rate=507806
probe_score=100
TAG:major_brand=mp42
TAG:minor_version=0
TAG:compatible_brands=mp42isom
TAG:creation_time=2018-06-21 06:42:54
[/FORMAT]
比如nb_streams=2表示包含两路媒体流,一路音频流,一路视频流。
duration=204.130433,表示视频文件长204.130433秒。
size=12957343,表示视频文件大小约为13MB≈12957343/1000/1000,注意单位是字节Byte,不是bit,另外FFmpeg中的b/s单位,尽管是小b,但表示的意义是字节byte。FFmpeg这样做很容易让初学者混淆字节和比特的概念,一般来说我们都是说大B是字节,小b是比特。大家注意区分就好。
bit_rate=507806,表示码率是507kb/s≈507806/1000,注意进制没有使用1024,为了便于计算直接使用1000。
然后看一下系统给出的媒体概要信息,和我们用ffproge分析的结果是一致的。
另外,还是更详细的输出命令,并且还可以指定json格式化输出。命令如下:
ffprobe -print_format json -show_streams 凉凉-MV.mp4
输出结果如下:
{
Input #0, mov,mp4,m4a,3gp,3g2,mj2, from '凉凉-MV.mp4':
Metadata:
major_brand : mp42
minor_version : 0
compatible_brands: mp42isom
creation_time : 2018-06-21 06:42:54
Duration: 00:03:24.13, start: 0.000000, bitrate: 507 kb/s
Stream #0:0(und): Audio: aac (LC) (mp4a / 0x6134706D), 44100 Hz, stereo, fltp, 64 kb/s (default)
Metadata:
creation_time : 2018-06-21 06:42:54
Stream #0:1(und): Video: h264 (High) (avc1 / 0x31637661), yuv420p, 640x368, 439 kb/s, 23 fps, 23 tbr, 90k tbn, 46 tbc (default)
Metadata:
creation_time : 2018-06-21 06:42:54
encoder : JVT/AVC Coding
"streams": [
{
"index": 0,
"codec_name": "aac",
"codec_long_name": "AAC (Advanced Audio Coding)",
"profile": "LC",
"codec_type": "audio",
"codec_time_base": "1/44100",
"codec_tag_string": "mp4a",
"codec_tag": "0x6134706d",
"sample_fmt": "fltp",
"sample_rate": "44100",
"channels": 2,
"channel_layout": "stereo",
"bits_per_sample": 0,
"r_frame_rate": "0/0",
"avg_frame_rate": "0/0",
"time_base": "1/44100",
"start_pts": 0,
"start_time": "0.000000",
"duration_ts": 9001984,
"duration": "204.126621",
"bit_rate": "64000",
"max_bit_rate": "70384",
"nb_frames": "8791",
"disposition": {
"default": 1,
"dub": 0,
"original": 0,
"comment": 0,
"lyrics": 0,
"karaoke": 0,
"forced": 0,
"hearing_impaired": 0,
"visual_impaired": 0,
"clean_effects": 0,
"attached_pic": 0
},
"tags": {
"creation_time": "2018-06-21 06:42:54",
"language": "und"
}
},
{
"index": 1,
"codec_name": "h264",
"codec_long_name": "H.264 / AVC / MPEG-4 AVC / MPEG-4 part 10",
"profile": "High",
"codec_type": "video",
"codec_time_base": "1/46",
"codec_tag_string": "avc1",
"codec_tag": "0x31637661",
"width": 640,
"height": 368,
"coded_width": 640,
"coded_height": 368,
"has_b_frames": 2,
"sample_aspect_ratio": "0:1",
"display_aspect_ratio": "0:1",
"pix_fmt": "yuv420p",
"level": 30,
"chroma_location": "left",
"refs": 4,
"is_avc": "true",
"nal_length_size": "4",
"r_frame_rate": "23/1",
"avg_frame_rate": "140850000/6123913",
"time_base": "1/90000",
"start_pts": 7826,
"start_time": "0.086956",
"duration_ts": 18371739,
"duration": "204.130433",
"bit_rate": "439965",
"bits_per_raw_sample": "8",
"nb_frames": "4695",
"disposition": {
"default": 1,
"dub": 0,
"original": 0,
"comment": 0,
"lyrics": 0,
"karaoke": 0,
"forced": 0,
"hearing_impaired": 0,
"visual_impaired": 0,
"clean_effects": 0,
"attached_pic": 0
},
"tags": {
"creation_time": "2018-06-21 06:42:54",
"language": "und",
"encoder": "JVT/AVC Coding"
}
}
]
}
总结
至此,我们已经见识了ffprobe的强大之处,更多技能还没有陈述完,大家自己尝试解锁吧。 最后推荐大家使用如下命令:
ffprobe -h
or
man ffprobe
获取更多用法,比如:
FFPROBE(1)
NAME
ffprobe - ffprobe media prober
SYNOPSIS
ffprobe [options] [input_url]
DESCRIPTION
ffprobe gathers information from multimedia streams and prints it in human- and machine-readable fashion.
For example it can be used to check the format of the container used by a multimedia stream and the format and type of each media stream contained in it.
If a url is specified in input, ffprobe will try to open and probe the url content. If the url cannot be opened or recognized as a multimedia file, a
positive exit code is returned.
ffprobe may be employed both as a standalone application or in combination with a textual filter, which may perform more sophisticated processing, e.g.
statistical processing or plotting.
Options are used to list some of the formats supported by ffprobe or for specifying which information to display, and for setting how ffprobe will show it.
ffprobe output is designed to be easily parsable by a textual filter, and consists of one or more sections of a form defined by the selected writer, which
is specified by the print_format option.
Sections may contain other nested sections, and are identified by a name (which may be shared by other sections), and an unique name. See the output of
sections.
Metadata tags stored in the container or in the streams are recognized and printed in the corresponding "FORMAT", "STREAM" or "PROGRAM_STREAM" section.
来源:oschina
链接:https://my.oschina.net/u/4324861/blog/4325767