使用 ffprobe 分析音视频流
背景
当排查推流问题时,第一步就是拿到流地址,观察 packet 的情况,介绍下如何通过 ffprobe 快速排查。
查看流信息
命令:
ffprobe -hide_banner -i "https://your.flv"
结果:
1
2
3
4
5
6
7
Input #0, flv, from 'https://your..flv':
Metadata:
encoder : Lavf59.27.100
Duration: 00:00:00.00, start: 546.625000, bitrate: N/A
Stream #0:0: Subtitle: text
Stream #0:1: Video: h264 (Constrained Baseline), yuv420p(progressive), 1920x1080 [SAR 1:1 DAR 16:9], 6000 kb/s, 30 fps, 30 tbr, 1k tbn
Stream #0:2: Audio: aac (LC), 44100 Hz, stereo, fltp, 128 kb/s
只看音频
命令:
ffprobe -v error -select_streams a -show_packets -i "https://your.flv"
结果:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
[PACKET]
codec_type=audio
stream_index=1
pts=780051
pts_time=780.051000
dts=780051
dts_time=780.051000
duration=23
duration_time=0.023000
size=337
pos=51817356
flags=K__
[/PACKET]
[PACKET]
codec_type=audio
stream_index=1
pts=780074
pts_time=780.074000
dts=780074
dts_time=780.074000
duration=23
duration_time=0.023000
size=400
pos=51842728
flags=K__
当采样率是 44.1KHz时 duration 通常是 23ms 也就是1024 个采样。但是 size 不是固定的,跟 AAC 帧的特性有关系,AAC 在编码时存在比特池(Bit Reservoir)机制,允许当前帧“借用”之前帧剩余的空闲空间,从而导致每帧实际占用的字节数不固定。 所以不用太关注 size 的变化。
需要观察以下字段: pts_time: 是连续递增的(如 780.051 -> 780.074,差值约 23ms),说明播放时间轴正常。 flags=K__:音频包几乎每一帧都是关键帧(Keyframe),这是正常的。 pos:文件偏移量应当是递增的。
只看视频
命令:
ffprobe -v error -select_streams a -show_packets -i "https://your.flv"
结果:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
[PACKET]
codec_type=video
stream_index=1
pts=693258
pts_time=693.258000
dts=693258
dts_time=693.258000
duration=33
duration_time=0.033000
size=24998
pos=4476048
flags=___
[/PACKET]
[PACKET]
codec_type=video
stream_index=1
pts=693292
pts_time=693.292000
dts=693292
dts_time=693.292000
duration=33
duration_time=0.033000
size=24998
pos=4502077
flags=___
[/PACKET]
以下是视频流着重关注的字段:
pts/pts_time:检查 pts 是否平滑递增。如果出现跳跃(Gap)或回退(Backwards),播放器会发生卡顿或音画不同步。 dts/dts_time:视频帧被送入解码器解码的时间。通常 dts 必须严格递增。如果 dts 乱序,解码器可能会报错。 duration/duration_time : 该帧预计持续显示的时间。计算帧率:例如 duration_time=0.040000 表示 25 FPS (1/0.040=25)。