怎么判断一个视频是否正常 - 学习使用 ffprobe

简介: 经常有运营反馈视频上传到系统之后,变短了,原版视频200分钟,上传上来之后,只有40分钟了。这个时候可以使用 ffprobe 来检查

场景

经常有运营反馈视频上传到系统之后,变短了。原版视频200分钟上传上来(转码)之后,只有40分钟了。这种情况通常是视频的时间戳混乱导致的,比如视频的40分钟处,时间戳变为0。下面学习下使用 ffprobe 来分析确认这种问题。

本地安装 ffmpeg

mac 系统可以先配置清华大学的镜像,然后执行 brew install ffmpeg
Debian / Ubuntu 系统:sudo apt-get install ffmpeg
Windows 系统:下载 ffmpeg 并将其添加到环境变量中。

使用 ffprobe 分析

查询视频帧率

ffprobe 工具可以用来分析视频文件,可以得到视频的信息,包括视频时长、码率、分辨率等。
可以简单的理解视频是一帧一帧的图片组成,一帧就是这个视频最小切割单元,也可以叫一个数据包。

ffprobe -i '/Users/zhoumengkang/Documents/normal_video.mp4'
...
Input #0, mov,mp4,m4a,3gp,3g2,mj2, from '/Users/zhoumengkang/Documents/normal_video.mp4':
  Metadata:
    major_brand     : mp42
    minor_version   : 1
    compatible_brands: isommp41mp42
    creation_time   : 2022-11-04T09:46:54.000000Z
  Duration: 00:01:12.64, start: 0.000000, bitrate: 2164 kb/s
  Stream #0:0[0x1](und): Video: h264 (High) (avc1 / 0x31637661), yuvj420p(pc, unknown/bt470bg/iec61966-2-1, progressive), 960x544, 2095 kb/s, SAR 1:1 DAR 30:17, 28 fps, 28 tbr, 600 tbn (default)
    Metadata:
      creation_time   : 2022-11-04T09:46:54.000000Z
      handler_name    : Core Media Video
      vendor_id       : [0][0][0][0]
  Stream #0:1[0x2](und): Audio: aac (LC) (mp4a / 0x6134706D), 44100 Hz, mono, fltp, 62 kb/s (default)
    Metadata:
      creation_time   : 2022-11-04T09:46:54.000000Z
      handler_name    : Core Media Audio
      vendor_id       : [0][0][0][0]

可以看到视频文件有两个StreamStream #0:0是视频;Stream #0:1是音频。我主要是关注视频的帧率28 fps,也就是说一帧的时长大概是是1/28秒,也就是0.035714秒。

逐帧分析视频

ffprobe -select_streams v -show_entries packet=pts_time,duration_time '/Users/zhoumengkang/Documents/normal_video.mp4'

-select_streams v:选择视频流进行分析,v 表示视频流。如果视频文件中包含多个视频流,则需要根据实际情况进行调整。
-show_entries packet=pts_time,duration_time:输出视频数据包的 PTS 时间戳和时长信息。

[PACKET]
pts_time=0.000000
duration_time=0.035000
[/PACKET]
[PACKET]
pts_time=0.071667
duration_time=0.035000
[/PACKET]
[PACKET]
pts_time=0.035000
duration_time=0.035000
[/PACKET]
[PACKET]
pts_time=0.143333
duration_time=0.035000
[/PACKET]
[PACKET]
pts_time=0.106667
duration_time=0.035000
[/PACKET]
[PACKET]
pts_time=0.215000
duration_time=0.035000
[/PACKET]
[PACKET]
pts_time=0.178333
duration_time=0.035000
[/PACKET]
[PACKET]
pts_time=0.285000
duration_time=0.035000
[/PACKET]
...

可以再增加一个参数输出位 csv 格式,方便后续分析

ffprobe -select_streams v -show_entries packet=pts_time,duration_time -of csv '/Users/zhoumengkang/Documents/normal_video.mp4'|head -n 10
...
packet,0.000000,0.035000
packet,0.071667,0.035000
packet,0.035000,0.035000
packet,0.143333,0.035000
packet,0.106667,0.035000
packet,0.215000,0.035000
packet,0.178333,0.035000
packet,0.285000,0.035000

第二列是时间戳,第三列是这一帧的时长。

可以发现时间戳不是完全顺序的,这就是有问题的么?

这样的结果并不一定说明时间戳是乱序的。每个视频数据包的 pts_time 属性表示该数据包的显示时间,而 duration_time 属性表示该数据包的显示时长,这两个属性并不依赖于视频数据包的先后顺序。因此,这些数据包的先后顺序并不一定是乱序的,可能是正常的时间顺序。

另外,对于视频数据包的时间戳顺序,需要根据实际情况进行分析。有时候,由于视频的编码方式或其他因素,视频数据包的时间戳可能会存在跳跃或非线性变化的情况。这种情况下,需要特别注意分析视频数据包的时间戳和时长信息,以确保分析结果的正确性。

我理解可能算法上有一些优化,我可以粗估如果前后两个数据包时间差距不大于5帧秒就是正常的。(我的外行理解)

5*0.035=0.175

下面的命令的意思就是上下两帧时间戳差距了0.175了,就报错。

ffprobe -select_streams v -show_entries packet=pts_time,duration_time -of csv '/Users/zhoumengkang/Documents/normal_video.mp4'|awk -F ',' '{print $2}'| awk '{if ($1-p>0.175 || p-$1>0.175) {print "timestamps error:" p,$1} p=$1}'

分析视频是否有错

实际遇到的场景就是分析一个远程文件,就会遇到这种问题。线上文件有问题,不用下载,支持 https 文件。

image.png

目录
相关文章
|
6月前
|
Python
晶闸管阴阳极的判断
晶闸管阴阳极的判断
150 0
|
6月前
|
C++
c++判断
c++判断
39 1
|
6月前
|
C语言
C判断
C判断
42 0
|
6月前
|
存储 C++
C++ 判断
C++ 判断
43 0
|
程序员 C语言
C 判断
C 判断。
44 0
判断两棵树是否完全一致
给你两棵二叉树的根节点 p 和 q ,编写一个函数来检验这两棵树是否相同。
122 0
|
索引
判断字符串回文
判断字符串回文
60 0
|
程序员 C++
用C++如何进行判断
用C++如何进行判断
|
前端开发 程序员
大量if else判断如何优化?@Valib详解
大量if else判断如何优化?@Valib详解
大量if else判断如何优化?@Valib详解
|
存储 算法
使用 UnionFind 判断他到底是不是你的远房表亲
不晓得大家晓不晓得并查集这个算法,我之前是没怎么听过(孤陋寡闻),其实这个算法是非常常见的一个算法,也是能用固定的套路去解决某一类问题,最为经典的就是亲戚问题。
137 0