I am using the timestamps that FFmpeg outputs to get information about the video integrity. So far I have tested this on about 50 videos and only had one "Unusual time skip" false positive.
Is this method of checking a valid way to do this, could there be legitimate reasons why the time skip would significantly increase and is there a more accurate way to determine an invalid time skip than $dif*2
?
ffmpegIntegrityCheck() {
local frame=0
local prevFrame=0
local duration=0
local timestamp=0
local seconds=0
local prevSeconds=0
local dif=0
local line=""
ffmpeg -v debug -progress - -nostats -i "$1" -f null - 2>&1 \
| while read -r line; do
# Get the video duration
if [[ "$duration" = 0 && "$line" =~ "Duration: " ]]; then
duration=${line#* }
duration=${duration%, start*}
duration=${duration%.*}
echo "Duration $duration"
# Check if the frame number stops increasing
elif [[ "$line" =~ "frame=" ]]; then
frame=${line#*=}
if [ "$frame" = "$prevFrame" ]; then
echo "No frame change at $timestamp frame $frame"
fi
prevFrame="$frame"
# Check the increase in seconds between each timestamp,
elif [[ "$line" =~ "out_time=" ]]; then
timestamp=${line#*=}
timestamp=${timestamp%.*}
seconds=$(echo "$timestamp" \
| awk -F: '{ print ($1 * 3600) ($2 * 60) $3 }')
if [ "$dif" != 0 ] && (( $seconds-$prevSeconds > $dif*2 )); then
echo "Unusual time skip at $timestamp"
else
dif=$(($seconds-$prevSeconds))
fi
prevSeconds="$seconds"
# Check if the last timestamp matches the duration
elif [[ "$line" = "progress=end" ]]; then
if [ "$duration" != "$timestamp" ]; then
duration=$(echo "$duration" \
| awk -F: '{ print ($1 * 3600) ($2 * 60) $3 }')
if (( $seconds < $duration-1 || $seconds > $duration 1 )); then
echo "End time mismatch at $timestamp"
fi
fi
fi
done
}
The reason I am trying to check with more than just ffmpeg -v error
is because I have found corrupted files where ffmpeg has reported no errors. I have also found files where FFmpeg reports errors but when I watch the video there are no problems so I would like to try and check whether there are any playback problems without watching it.
The logic behind looking at the timestamp jumps was that if the file all of a sudden starts processing significantly faster, I assume it is having errors and skipping some processing. This assumption does seem to match my results with files where ffmpeg -v error
is reporting errors but it does produce some false positives
The log from a file producing errors in FFmpeg:
Duration 01:36:32
No frame change at 00:48:29 frame 69673
Unusual time skip at 00:49:42
No frame change at 00:49:42 frame 69673
Unusual time skip at 00:50:58
No frame change at 00:50:58 frame 69673
Unusual time skip at 00:51:44
No frame change at 00:51:44 frame 69673
Unusual time skip at 00:53:09
No frame change at 00:53:09 frame 69673
Unusual time skip at 00:54:04
No frame change at 00:54:04 frame 69673
Unusual time skip at 00:55:25
No frame change at 00:55:25 frame 69673
Unusual time skip at 00:56:32
No frame change at 00:56:32 frame 69673
Unusual time skip at 00:57:30
No frame change at 00:57:30 frame 69673
Unusual time skip at 00:58:08
No frame change at 00:58:08 frame 69673
Unusual time skip at 00:59:37
No frame change at 00:59:37 frame 69673
No frame change at 01:00:02 frame 69673
Unusual time skip at 01:01:19
No frame change at 01:01:19 frame 69673
Unusual time skip at 01:02:33
No frame change at 01:02:33 frame 69673
Unusual time skip at 01:03:39
No frame change at 01:03:39 frame 69673
No frame change at 01:03:39 frame 69673
No frame change at 01:06:02 frame 69673
No frame change at 01:06:25 frame 69673
Unusual time skip at 01:08:18
No frame change at 01:08:18 frame 69673
Unusual time skip at 01:09:19
No frame change at 01:09:19 frame 69673
Unusual time skip at 01:10:19
No frame change at 01:10:19 frame 69673
Unusual time skip at 01:11:26
No frame change at 01:11:26 frame 69673
Unusual time skip at 01:12:39
No frame change at 01:12:39 frame 69673
Unusual time skip at 01:13:53
No frame change at 01:13:53 frame 69673
Unusual time skip at 01:14:55
No frame change at 01:14:55 frame 69673
No frame change at 01:14:59 frame 69673
Unusual time skip at 01:17:04
No frame change at 01:17:04 frame 69673
No frame change at 01:17:04 frame 69673
No frame change at 01:19:01 frame 69673
No frame change at 01:19:25 frame 69673
Unusual time skip at 01:21:07
No frame change at 01:21:07 frame 69673
No frame change at 01:21:40 frame 69673
Unusual time skip at 01:23:34
No frame change at 01:23:34 frame 69673
No frame change at 01:24:18 frame 69673
No frame change at 01:25:34 frame 69673
No frame change at 01:26:41 frame 69673
No frame change at 01:27:48 frame 69673
No frame change at 01:28:06 frame 69673
Unusual time skip at 01:29:01
No frame change at 01:29:01 frame 69673
Unusual time skip at 01:30:38
No frame change at 01:30:38 frame 69673
No frame change at 01:30:38 frame 69673
No frame change at 01:33:15 frame 69673
No frame change at 01:33:51 frame 69673
Unusual time skip at 01:35:24
No frame change at 01:35:24 frame 69673
End time mismatch at 01:36:16
CodePudding user response:
Based on my results so far I can say that checking "End time mismatch" is useful but checking "Unusual time skip" so far, isn't telling me anything that ffmpeg -v error
was missing, I may be able to use it to quantify error though.
I have found several files with "End time mismatch" where the file stops playing too early but ffmpeg error/debug output doesn't report any problems.
Duration 01:53:53
progress=end
End time mismatch at 00:10:29
[AVIOContext @ 0x5587868cfcc0] Statistics: 0 seeks, 21 writeouts
video:7894kB audio:108396kB subtitle:0kB other streams:0kB global headers:0kB muxing overhead: unknown
Input file #0 (vid.avi):
Input stream #0:0 (video): 15082 packets read (74354639 bytes); 15082 frames decoded;
Input stream #0:1 (audio): 24088 packets read (8809327 bytes); 24088 frames decoded (27749376 samples);
Total: 39170 packets (83163966 bytes) demuxed
Output file #0 (pipe:):
Output stream #0:0 (video): 15082 frames encoded; 15082 packets muxed (8083952 bytes);
Output stream #0:1 (audio): 24088 frames encoded (27749376 samples); 24088 packets muxed (110997504 bytes);
Total: 39170 packets (119081456 bytes) muxed
39170 frames successfully decoded, 0 decoding errors
[AVIOContext @ 0x5587868d8c40] Statistics: 713804051 bytes read, 18836 seeks
ffprobe -show_streams -show_format FILE
results
[STREAM]
index=0
codec_name=mpeg4
codec_long_name=MPEG-4 part 2
profile=Advanced Simple Profile
codec_type=video
codec_time_base=417083/10000000
codec_tag_string=DX50
codec_tag=0x30355844
width=608
height=320
coded_width=608
coded_height=320
has_b_frames=1
sample_aspect_ratio=1:1
display_aspect_ratio=19:10
pix_fmt=yuv420p
level=5
color_range=unknown
color_space=unknown
color_transfer=unknown
color_primaries=unknown
chroma_location=left
field_order=unknown
timecode=N/A
refs=1
quarter_sample=false
divx_packed=false
id=N/A
r_frame_rate=10000000/417083
avg_frame_rate=10000000/417083
time_base=417083/10000000
start_pts=0
start_time=0.000000
duration_ts=163848
duration=6833.821538
bit_rate=N/A
max_bit_rate=N/A
bits_per_raw_sample=N/A
nb_frames=163848
nb_read_frames=N/A
nb_read_packets=N/A
DISPOSITION:default=0
DISPOSITION:dub=0
DISPOSITION:original=0
DISPOSITION:comment=0
DISPOSITION:lyrics=0
DISPOSITION:karaoke=0
DISPOSITION:forced=0
DISPOSITION:hearing_impaired=0
DISPOSITION:visual_impaired=0
DISPOSITION:clean_effects=0
DISPOSITION:attached_pic=0
DISPOSITION:timed_thumbnails=0
[/STREAM]
[STREAM]
index=1
codec_name=mp3
codec_long_name=MP3 (MPEG audio layer 3)
profile=unknown
codec_type=audio
codec_time_base=1/44100
codec_tag_string=U[0][0][0]
codec_tag=0x0055
sample_fmt=fltp
sample_rate=44100
channels=2
channel_layout=stereo
bits_per_sample=0
id=N/A
r_frame_rate=0/0
avg_frame_rate=0/0
time_base=1/14000
start_pts=0
start_time=0.000000
duration_ts=N/A
duration=N/A
bit_rate=112000
max_bit_rate=N/A
bits_per_raw_sample=N/A
nb_frames=95673053
nb_read_frames=N/A
nb_read_packets=N/A
DISPOSITION:default=0
DISPOSITION:dub=0
DISPOSITION:original=0
DISPOSITION:comment=0
DISPOSITION:lyrics=0
DISPOSITION:karaoke=0
DISPOSITION:forced=0
DISPOSITION:hearing_impaired=0
DISPOSITION:visual_impaired=0
DISPOSITION:clean_effects=0
DISPOSITION:attached_pic=0
DISPOSITION:timed_thumbnails=0
[/STREAM]
[FORMAT]
filename=vid.avi
nb_streams=2
nb_programs=0
format_name=avi
format_long_name=AVI (Audio Video Interleaved)
start_time=0.000000
duration=6833.821538
size=732241860
bit_rate=857197
probe_score=100
TAG:encoder=AVI-Mux GUI 1.17.8.3, Feb 16 201019:42:50
TAG:JUNK=
[/FORMAT]
CodePudding user response:
This looks to be an instance of an XY question.
Checking timestamp intervals will not tell you whether the file is corrupt i.e.
- is the container metadata missing (fully or partially) or malformed ?
- is any of the media data missing or malformed ?
At most, it will identify if a portion of the file will lead to subjective 'freezes' due to prolonged video frames or silences due to a large inter-packet intervals in the audio.
Running ffmpeg -i INPUT
and checking the exit code is sufficient to identify if the input header has any fatal errors.
To check media data, decoding the file is sufficient.
ffmpeg -v 48 -i INPUT -f null -
After completion, check the logs for Packet corrupt
to identify errors at the packet encapsulation level. And at the end of the log, look for a line of this form: X frames successfully decoded, Y decoding errors
for corrupt frames.