How can I check the integrity of a video file (avi, mpeg, mp4...)?

This title could be somewhat misleading, so let me explain ...

I'm downloading a video file ... mpeg, avi - being one of the popular formats. Now, if I am downloading it, and the download breaks in the middle of the uhm ... download, then, for example, Windows Media Player will give out some error and refuse to play it (although the file is, let's say, 98% complete). But, players like KMPlayer, or MediaPlayer Classic will play it up until that point (as the matter of fact, they can play it while it is being downloaded as well).

So, I'm interested, ... without using any means of download (download managers and alike) to secure the file is completely downloaded, how can one verify whether the video file is downloaded whole, and that it is complete ?

3

11 Answers

You can use a feature in ffmpeg video converter: if you will specify it to recode video to nothing it will just read input file and report any errors that will appear. This is a very fast process because video frames are just being read, checked and silently dropped.

Example command line: (for Linux)

ffmpeg -v error -i file.avi -f null - 2>error.log 

-v error means a certain level of verbosity (to show some errors that are normally hidden because they don't affect playability a much).

You will get a full error log with some generic information about file ffmpeg will output, so this will probably require your attention, through filters can be written to perform batch check of similar files.

FFmpeg is also available for Windows here. The command line will be almost identical with an exception of stderr redirect:

ffmpeg.exe -v error -i file.avi -f null - >error.log 2>&1 
19

I liked idea of using ffmpeg -f null above, but I'd actually like to automate process of using that output. In particular, common scenario I have with my music video collection is that I have few clips which have same resolution, and I'd like to diff verification logs for those files to remove ones broken the most.

Unfortunately, ffmpeg so far doesn't have a way to disable its interactive mode, which outputs noise for this case of usage. I ended up hacking simple wrapper script to do filtering:

#!/usr/bin/env python import sys import os import re t = os.popen('ffmpeg -v 5 -i "%s" -f null - 2>&1' % sys.argv[1]).read() t = re.sub(r"frame=.+?\r", "", t) t = re.sub(r"\[(.+?) @ 0x.+?\]", "[\\1]", t) print t 

Example output:

[mpeg1video]ac-tex damaged at 21 17 [mpeg1video]Warning MVs not available [mpeg1video]concealing 22 DC, 22 AC, 22 MV errors [mpeg1video]Warning MVs not available [mpeg1video]concealing 22 DC, 22 AC, 22 MV errors [mpeg1video]ac-tex damaged at 13 9 
4

For windows, You can 'batch' check integrity for videos on current folder and all subfolders with this bat file:

checkvideo.bat

@echo off set "filtro=%1" if [%filtro%]==[] ( set "filtro=*.mp4" ) for /R %%a in (%filtro%) do call :doWork "%%a" PAUSE exit /B :doWork C:\ffmpeg\bin\ffmpeg.exe -v error -i %1 -f null - > "%~1.log" 2>&1 

Use:

checkvideo.bat [filter]

If you don't give one filter, will get '*.mp4'.

Samples: checkvideo.bat checkvideo.bat *.avi

Setup: Download FFmpeg for Windows from here: and unzip them Change C:\ffmpeg\bin\ in the bat file for the path where you have unzipped ffmpeg Put checkvideo.bat on a folder included in the Path or add his folder to Path environment variable

UPDATE: As of September 18,2020, the above link is no longer valid so Windows users can download FFmpeg form here or here

1

Although this is an old post, and I'm sure there's other ways to valid video files now. However, for a full video file check, you can use mplayer.exe.

Using the below (.bat) script will recursively check video files and save validated ones in a integritychecked.log file (to skip next time its run).

if not "%1" equ "" ( pushd %1 ) else ( pushd "%~dp0" ) setlocal EnableDelayedExpansion for /F "tokens=1,2 delims=#" %%a in ('"prompt #$H#$E# & echo on & for %%b in (1) do rem"') do ( set "DEL=%%a" ) echo This script with validate video files in the folder/sub-folders. Please ensure mplayer.exe is accessible in PATH. echo. echo Either run this script from the desired (parent) directory or specify the directory when running this script. eg checkvideo.bat <full path> echo. pause echo. REM Append date and time to integritychecked.log file for /f "tokens=1-9 delims=/:. " %%d in ("%date% %time: =0%") do echo Started: %%g%%f%%e_%%h%%i%%j>>integritychecked.log FOR /F "delims=*" %%G in ('dir /b /s *.mkv *.mp4 *.mpg *.mpeg *.xvid *.webm *.m2v *.m4v *.3gp *.3g2 *.avi *.mov *.flv *.wmv') DO ( REM Confirm if already checked or not from log file set found=0 for /F "usebackq tokens=*" %%s in ("integritychecked.log") do ( if %%G equ %%s ( set found=1 REM echo "FOUND = %%G = %%s" ) ) if !found! equ 0 ( echo Verifying "%%G" mplayer -tsprobe 10000000 -benchmark -forcedsubsonly -mc 0 -nosound -nosub -noautosub -vo null "%%G" 2>"%%G.log" REM ffmpeg -v error -i "%%G" -map 0:1 -f null - 2>"%%G.log" FOR %%F in ("%%G.log") DO ( if %%~zF equ 0 ( del %%F call :colour 0a "Video is good" echo. echo. ) else ( call :colour 0c "Error in video file:" echo. type %%F call :colour 0e "This can be found in the video's .log file" echo. echo. ) ) REM Save entry to log file (as checked) echo %%G>>integritychecked.log ) else ( echo already verified "%%G"...skipping. ) ) call :colour 0a "Verifying complete!" && echo. pause cd %~p0 exit /b :colour set "param=^%~2" ! set "param=!param:"=\"!" rem Prepare a file "X" with only one dot <nul > X set /p ".=." findstr /p /A:%1 "." "!param!\..\X" nul <nul set /p ".=%DEL%%DEL%%DEL%%DEL%%DEL%%DEL%%DEL%" rem Delete "X" file del X exit /b 
2

I really liked the ffmpeg version provided by How can I check the integrity of a video file (avi, mpeg, mp4...)? but I wanted a version that would only tell me if ffmpeg failed to play the video in a way that stopped it (I can deal with frame drops), and I wanted it to be linux based. I came to the solution below. I also wanted more information about what was happening while it was scanning, so I opted for scanned/total/errored outputting whenever a file starts scanning.

#!/bin/bash # Name: mediaCheck # Purpose: Confirm all media in a path can be played back using ffmpeg # Requires: # * ffmpeg in $PATH # * date in $PATH # * find in $PATH function checkReqs { # checks requirements for the script requires="ffmpeg date find" re=0 for i in $requires; do if ! which $i > /dev/null; then ((re++)) echo "$i is required in path for this script" fi done if [ "$re" -gt 0 ]; then echo "Requirements not met" exit 1 fi } function pathCheck { # if there isn't a path, use pwd, otherwise clean up whatever is provided. if [ -z "$1" ]; then lPath=mediaCheck.log cPath=$(pwd) else cPath=$(readlink -f $1) lPath=$1 fi } function pdate { # my prefered date formatting date +%FT%H:%M:%S } function checkMedia { # the actual ffmpeg command ffmpeg -v error -i $1 -f null - &> "$1.log" } function findItems { # our main loops # first a set of common file types for mtype in flv avi m4v mkv mp4; do c=0; e=0 # Get a total per file type ttotal=$(find $1 -type f -name \*.$mtype | wc -l) # then the actual lookup and check for i in $(find $1 -type f -name \*.$mtype); do echo -ne "$(pdate) $c out of $ttotal $mtype files checked with $e errors.\r" ((c++)) # check media, and if we fail, increment error counter. if ! checkMedia "$i" ; then ((e++)) echo "$i failed" >> $lPath.log fi done echo "$(pdate) $c out of $ttotal $mtype files checked with $e errors." unset c e done } # set blank cpath cPath='' # uncomment the line below if this script isn't behaving as expected # set -x # Check requirements before anything else checkReqs # Then generate a path pathCheck $1 # Make sure we don't stumble on names with spaces IFS=$'\n' echo "$(pdate) scan started." findItems $cPath echo "$(pdate) scan complete." 

I have developed this python script which checks media files integrity (or tries to), please read instructions for details and limits, also feedbacks are appreciated:

The issue with the other answer using ffmpeg to recode to null format is that it takes really a long time. Especially, if you want to check multiple files in a directory.

A quick way would be to generate thumbnails for all the videos, and see where thumbnail generation fails.

find . -iname "*.mp4" | while read -r line; do line=`echo "$line" | sed -r 's/^\W+//g'`; echo 'HERE IT IS ==>' "$line"; if ffmpeg -i "$line" -t 2 -r 0.5 %d.jpg; then echo "DONE for" "$line"; else echo "FAILED for" "$line" >>error.log; fi; done; 

This method turned out to be much FASTER than other methods.

However, there is a CAVEAT. This method can yield wrong results, because sometimes thumbnail can be generated even for corrupt files. E.g. if the video file is corrupted only at the end, this method will fail.

2

Easier version

for file in *.mp4; do ffmpeg -v error -i "$file" -f null - >error.log 2>&1; print "$file"; done 

This will print the file name as they are being processed.

error.log will contain the errors.

1
def check(dirpath): files = [f for f in listdir(dirpath) if isfile(join(dirpath, f))] invalidfiles = [] for filename in files: cmd_args = ['ffprobe', dirpath + '/' + filename] pipes = subprocess.Popen(cmd_args, stdout=subprocess.PIPE, stderr=subprocess.PIPE) #If you are using python 2.x, you need to include shell=True in the above line std_out, std_err = pipes.communicate() if 'invalid data' in std_out.decode('utf-8').lower() : invalidfiles.append(dirpath + '/' + filename) continue if 'invalid data' in std_err.decode('utf-8').lower() : invalidfiles.append(dirpath + '/' + filename) continue return invalidfiles 
1

MediaInfo is a great tool for getting info about any video file you care to throw at it. This may be able to highlight the info you want.

Another tool is GSpot but it hasn't been updated since 2007.

Try giving each one a known good and known bad file and compare the results.

I used to use GSpot until it stopped being updated, then switched to MediaInfo

5

fluent-ffmpeg

var ffmpeg = require('fluent-ffmpeg'); var ff = new ffmpeg(); ff.on('start', function(commandLine) { // on start, you can verify the command line to be used }) .on('progress', function(data) { // do something with progress data if you like }) .on('end', function() { // do something when complete }) .on('error', function(err, stdout, stderr) { // handle error conditions console.log('Error: ' + err.message) console.log('ffmpeg output:\n' + stdout) console.log('ffmpeg stderr:\n' + stderr) }) .addInput('path\to\file') .addInputOption('-xerror') .addInputOption('-v error') .output('-') .outputOptions('-f null') .run(); 

Reference:

Your Answer

Sign up or log in

Sign up using Google Sign up using Facebook Sign up using Email and Password

Post as a guest

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

You Might Also Like