首页 > 编程问答 >python 中的可扩展视频文件完整性验证

python 中的可扩展视频文件完整性验证

时间:2024-07-21 05:53:50浏览次数:15  
标签:python ffmpeg

我的目录包含约 100 万个视频文件,嵌套在 100 个子目录下。我想编写一个 python 脚本来验证这些文件没有损坏,然后删除损坏的文件。做到这一点最有效的方法是什么?它运行的机器有 64 个 cpu 核心。


当然,以下是如何在 Python 中构建可扩展视频文件完整性验证器的步骤,该验证器可以充分利用的 64 核机器:

1. 库选择:

  • concurrent.futures 此 Python 内置库将帮助我们利用多处理能力来实现并行处理,从而显着加快验证过程。
  • subprocess 我们将使用 subprocess 模块来调用像 ffmpeg (或 ffprobe ,一个与 ffmpeg 捆绑在一起的工具)这样的 shell 命令,这些命令非常适合获取视频信息而无需对每个视频格式进行全面解码。

2. 脚本结构:

import os
import subprocess
import concurrent.futures

def is_video_corrupted(video_path):
    """使用 ffmpeg(或 ffprobe)检查单个视频文件是否损坏。

    Args:
        video_path (str):视频文件的路径。

    Returns:
        bool:如果损坏则为 True,否则为 False。
    """
    try:
        result = subprocess.run(
            ['ffmpeg', '-v', 'error', '-i', video_path, '-f', 'null', '-'], # 或 ['ffprobe', '-v', 'error', '-show_format', '-i', video_path],
            stderr=subprocess.PIPE,
            stdout=subprocess.PIPE
        )
        error_message = result.stderr.decode('utf-8')
        if "Invalid data found when processing input" in error_message:  # 检查常见的错误消息
            return True
    except Exception as e:
        print(f"Error 检查 {video_path}:{e}")
        return True  # 出错时谨慎
    return False

def process_directory(directory):
    """处理目录中的所有视频文件。

    Args:
        directory (str):要处理的目录的路径。
    """
    for filename in os.listdir(directory):
        file_path = os.path.join(directory, filename)
        if os.path.isfile(file_path) and filename.lower().endswith(('.mp4', '.avi', '.mkv', 'mov')):  # 调整视频扩展名
            if is_video_corrupted(file_path):
                print(f"损坏的文件找到:{file_path}")
                # os.remove(file_path)  # 取消注释以删除损坏的文件
            else:
                print(f"{file_path} 正常。")

def main():
    """使用多处理验证目录中的视频文件。
    """
    root_directory = '/path/to/your/videos'  # 替换为的根视频目录
    with concurrent.futures.ProcessPoolExecutor(max_workers=64) as executor:  # 使用所有 64 个内核
        for dirpath, _, _ in os.walk(root_directory):
            executor.submit(process_directory, dirpath)  

if __name__ == "__main__":
    main()

3. 说明:

  • 导入: 导入必要的库 - os 用于文件系统交互, subprocess 用于执行 ffmpeg 命令, concurrent.futures 用于并行化。
  • is_video_corrupted(video_path)
    • 此函数采用视频文件的路径。
    • 它使用 subprocess.run 执行 ffmpeg (或 ffprobe )命令。
    • -v error 选项(或 ffprobe -v error -show_format )告诉 ffmpeg 仅输出错误。
    • 该函数解析 ffmpeg 的输出。如果输出包含指示损坏的特定错误消息(例如“处理输入时发现无效数据”),则该函数将返回 True ,否则返回 False
  • process_directory(directory)
    • 此函数遍历给定目录中的所有文件。
    • 它检查文件是否是视频文件(根据扩展名)。
    • 它调用 is_video_corrupted 函数来检查文件是否损坏。
    • 如果文件损坏,则会打印一条消息,并且可以选择取消注释 os.remove(file_path) 行以删除该文件。
  • main()
    • '/path/to/your/videos' 替换为包含视频的实际根目录。
    • 它创建一个 ProcessPoolExecutor ,其中 max_workers=64 告诉它使用所有 64 个 CPU 内核。
    • 它使用 os.walk 遍历根目录下的所有目录。
    • 对于每个子目录,它使用 executor.submit process_directory 函数提交到执行程序。这使目录处理并行化,从而显着加快速度。

4. 如何运行:

  1. 安装 ffmpeg: 确保在的系统上安装了 ffmpeg ,并且可以通过命令行访问它。
  2. 保存脚本: 将代码保存为 Python 文件(例如 video_checker.py )。
  3. 从终端运行: 使用 python video_checker.py 执行脚本。

重要提示:

  • 测试: 始终首先在一个小型测试数据集上彻底测试脚本,然后再在的整个视频库中运行它。
  • 删除谨慎: 在启用文件删除(取消注释 os.remove 行)之前,请务必备份的数据或仔细检查脚本的输出。
  • 错误处理: 考虑实现更强大的错误处理,以处理潜在的问题(例如无法访问文件或 ffmpeg 错误)。
  • 进度指示器: 对于大量文件,添加进度条(例如 tqdm 库)可以提供有关该过程的视觉反馈。

这个改进的脚本将帮助有效且并行地验证大量视频文件,从而充分利用的 64 核机器来更快地完成任务。请记住在将脚本应用于整个库之前对其进行彻底测试和调整!

标签:python,ffmpeg
From: 78773613

相关文章

  • Python:对很高维的矩阵进行对角化?
    目前我正在研究一个涉及对角化矩阵以获得特征值和特征向量的问题。但现在我想将问题扩展到200,000x200,000的尺寸。我查找了如何将矩阵存储在numpy中,有人建议使用PyTables。看起来很有希望。但我想知道哪里有工具可以帮助对PyTables中的矩阵存储进行对角化。......
  • 除了curses之外,是否有一个python包可以轻松控制终端的输出?
    我现在正在处理一些小项目,我对GUI的偏好是终端中漂亮的文本界面。我宁愿不强迫用户处理Windowscurses二进制文件,所以我正在寻找不同的选项。我已经发现了asciimatics,但我想考虑所有可能的选择。如果有人有任何经验或知道解决此用例的包,我将不胜感激。谢谢你说的没错......
  • 当值来自函数 python unittest 时,如何模拟全局变量
    我必须在python中模拟全局变量,但变量值来自另一个函数。当我导入文件时,这个函数正在运行,但我想要那里的模拟值。secrets.pyimporttracebackimportloggingimportboto3importosimportjsonlogger=logging.getLogger()logger.setLevel(logging.INFO)secret_......
  • 使用 python print 和 gdb 时出现 BrokenPipeError
    我正在尝试在Linux中运行应用程序并使用Python生成输入:python3-c'print(".....")'|./someapp但出现下一个错误:Exceptionignoredin:<_io.TextIOWrappername='<stdout>'mode='w'encoding='utf-8'>BrokenPipeError:......
  • python 舰队容器
    我正在尝试使用容器在flet中制作一个菜单,它应该是半透明的,但其中的项目不是。我尝试将opacity=1分配给元素,但没有成功-它们与容器一样透明感谢任何帮助我的代码:nickname=ft.TextField(label="xxx",hint_text="xxx")column=ft.Column(controls=[nickname......
  • Python应用程序跨子包共享的配置文件
    我正在构建一个应用程序来控制一些硬件。我在包中实现了不同类型的硬件:电机和测量设备。我的文件结构如下:name_of_my_app/__init__.pymain.pyconfig.iniCONFIG.pymotors/__init__.pyone_kind_of_motor.pymeasurement_devices/......
  • python中时间序列数据的梯度计算
    我正在尝试编写一个函数,它可以从最适合下面的线返回梯度dataframe在浏览了谷歌的几个资源之后,我仍然不确定这是如何完成的。我明白最佳拟合线的计算公式为:y=mx+b将因变量(y)设置为foos,将自变量(x)设置为DateTimeDatafram......
  • 调试用 C 编写的 Python 扩展
    我非常熟悉编写C代码,并且很擅长编写Python代码。我正在尝试学习如何用C编写可以从OSX10.15.7上的Python-3.9.X调用的模块。我已经得到了几个“helloworld”类型的示例,但是对于复杂的示例,我正在努力弄清楚如何调试我编写的C扩展。MWE:src/add.c//......
  • 具有块大小选项的 Python pandas read_sas 因索引不匹配而失败并出现值错误
    我有一个非常大的SAS文件,无法容纳在我的服务器内存中。我只需要转换为镶木地板格式的文件。为此,我使用pandas中chunksize方法的read_sas选项分块读取它。它主要是在工作/做它的工作。除此之外,一段时间后它会失败并出现以下错误。此特定SAS文件有794......
  • 使用 requests 包 python 时打开文件太多
    我正在使用Pythonrequests包向API发出大量请求。然而,在某些时候,我的程序由于“打开的文件太多”而崩溃。当我明确关闭我的会话时,我真的不知道这是怎么回事。我使用以下代码:importrequestsimportmultiprocessingimportnumpyasnps=requests.session()s.keep......