How to check if a video is completely downloaded?
ffmpeg
is an OS agnostic tool that is capable of determining if a video file has been completely downloaded. The command below instructs ffmpeg
to read the input video and encode the video to nothing. During the encoding process, any errors such as missing frames are output to test.log.
ffmpeg -v error -i FILENAME.mp4 -f null - 2>test.log
If a video file is not totally downloaded, there will be many lines in the test.log file. For example, .1 MB missing from a video file produced 71 lines of errors. If the video is fully downloaded and hasn’t been corrupted, no errors are found, and no lines are printed to test.log.
Edit
In the example I gave above, I tested the entire file because the test video I downloaded was a torrent, which can have missing chunks throughout the file.
Adding -sseof -60
to the list of arguments will check the last 60 seconds of the file, which is considerably faster.
ffmpeg -v error -sseof -60 -i FILENAME.mp4 -f null - 2>test.log
You'll need a newer version of ffmpeg, 2.8 was missing the sseof flag, so I used 3.0.
MediaInfo displays a line:
Truncated: Yes
if a file is not complete as expected by the format specifications.
As there is technically no difference between a file wrongly (not meeting the specs about file boundaries) muxed and partially downloaded files, it is technically impossible to do the difference between a buggy file and a partially downloaded file.
Another (advanced) test could be done e.g. reading the index of an .mp4 file and checking that the file offset + frame size of the last frame is within the file size of the file you get, but it is not exactly what your are looking for (if there is metadata e.g. posters in the source file, at the end of the file, and the file is truncated just before this poster, the partial download is still not detected in every case). It is not implemented in MediaInfo but you can add a MediaInfo feature request.
In all cases, it is very difficult to detect all partial downloads, because the total file size in not indicated in most video file formats so you can be sure a file is truncated, but you can not be sure a file is not truncated. The only way to be sure you downloaded the complete file is to get the file size from somewhere else (and better: have its hash e.g. MD5).
PS: this question is not specific to any operating system.
I had a file where ffmpeg (v3.1.1) with -sseof -60 did not show any warnings and just exited with no indication that something was wrong. Mediainfo did not show the file was truncated either. Only leaving out the -sseof -60 would report any error with ffmpeg. So I went back to trying ffprobe. It seemed slightly faster than ffmpeg.
ffprobe -v error -count_frames -i filename.mp4
produced this output
[h264 @ 00000000004e6a60] Invalid NAL unit size.
[h264 @ 00000000004e6a60] Error splitting the input into NAL units.
[mov,mp4,m4a,3gp,3g2,mj2 @ 00000000004e5280] stream 1, offset 0x1350135: partial file
I did not yet encounter any false positives (as reported by the OP).
Edit: ffprobe was on my testfiles about 10% faster than ffmpeg, but only if you instruct it to use all cores with the option '-threads 0'. Otherwise it uses only one core/thread and is slower.