我的目录包含约 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. 如何运行:
-
安装 ffmpeg:
确保在的系统上安装了
ffmpeg
,并且可以通过命令行访问它。 -
保存脚本:
将代码保存为 Python 文件(例如
video_checker.py
)。 -
从终端运行:
使用
python video_checker.py
执行脚本。
重要提示:
- 测试: 始终首先在一个小型测试数据集上彻底测试脚本,然后再在的整个视频库中运行它。
-
删除谨慎:
在启用文件删除(取消注释
os.remove
行)之前,请务必备份的数据或仔细检查脚本的输出。 -
错误处理:
考虑实现更强大的错误处理,以处理潜在的问题(例如无法访问文件或
ffmpeg
错误)。 -
进度指示器:
对于大量文件,添加进度条(例如
tqdm
库)可以提供有关该过程的视觉反馈。
这个改进的脚本将帮助有效且并行地验证大量视频文件,从而充分利用的 64 核机器来更快地完成任务。请记住在将脚本应用于整个库之前对其进行彻底测试和调整!
标签:python,ffmpeg From: 78773613