如何检查视频文件(avi、mpeg、mp4……)的完整性?

如何检查视频文件(avi、mpeg、mp4……)的完整性?

这个标题可能有点误导,所以让我解释一下......

我正在下载一个视频文件...mpeg、avi 是流行的格式之一。现在,如果我正在下载它,下载在中间中断了,那么,例如,Windows Media Player 会给出一些错误并拒绝播放它(尽管该文件已经完成了 98%)。但是,像 KMPlayer 或 MediaPlayer Classic 这样的播放器会播放它直到那个时候(事实上,它们也可以在下载时播放它)。

所以,我很感兴趣,...如果不使用任何下载方式(下载管理器等)来确保文件完全下载,如何验证视频文件是否完整下载,以及是否完整?

答案1

您可以使用视频转换器中的一项功能ffmpeg:如果您指定它将视频重新编码为无内容,它将只读取输入文件并报告将出现的任何错误。这是一个非常快的过程,因为视频帧只是被读取、检查并默默丢弃。

命令行示例:(适用于 Linux)

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

-v error指的是某个详细程度(显示一些通常隐藏的错误,因为它们不会对可玩性产生太大影响)。

您将获得一个完整的错误日志,其中包含有关 ffmpeg 将输出的文件的一些一般信息,因此这可能需要您的注意,通过可以编写过滤器来执行类似文件的批量检查。

FFmpeg 也适用于 Windows这里。命令行几乎与 stderr 重定向不同:

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

答案2

我喜欢上面的想法ffmpeg -f null,但我实际上想自动化使用该输出的过程。具体来说,我的音乐视频收藏中常见的情况是,我有几个具有相同分辨率的剪辑,我想对这些文件的验证日志进行差异化,以删除最损坏的文件。

不幸的是,ffmpeg 目前还没有办法禁用其交互模式,在这种情况下,交互模式会输出噪音。我最终破解了简单的包装脚本来进行过滤:

#!/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

示例输出:

[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

答案3

对于 Windows,您可以使用此 bat 文件“批量”检查当前文件夹及其所有子文件夹中视频的完整性:

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
    

使用:

checkvideo.bat [filter]

如果您不提供任何过滤器,将会得到‘*.mp4’。

样品: checkvideo.bat checkvideo.bat *.avi

设置: 从这里下载适用于 Windows 的 FFmpeg:https://ffmpeg.zeranoe.com/builds/并解压它们C:\ffmpeg\bin\在bat文件中更改为解压ffmpeg的路径放在checkvideo.batPath中包含的文件夹或将其文件夹添加到Path环境变量中

更新:截至 2020 年 9 月 18 日,以上链接不再有效,因此 Windows 用户可以从这里或者这里

答案4

虽然这是一篇老帖子,但我相信现在还有其他方法可以验证视频文件。但是,要进行完整的视频文件检查,您可以使用 mplayer.exe。

使用下面的(.bat)脚本将递归检查视频文件并将验证的文件保存在 integritychecked.log 文件中(以便下次运行时跳过)。

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

相关内容