我有一个系统,其中会摄取视频文件,然后启动多个 CPU 密集型任务。由于这些任务的计算成本很高,如果文件已经被处理过,我想跳过处理该文件。
视频来自各种来源,因此文件名等不是可行的选项。
如果我使用图片,我会比较 MD5 哈希值,但对于 5GB - 40GB 的视频,这可能需要很长时间才能计算。
为了比较我正在测试此方法的 2 个视频:
- 检查相关元数据匹配
- 使用 ffmpeg/ffprobe 检查文件长度
- 使用 ffmpeg 以 100 个预定义时间戳 [1-100] 提取帧
- 为每个帧创建 MD5 哈希
- 比较 MD5 哈希值以检查是否匹配
有谁知道更有效的方法吗?或者有更好的方法来解决这个问题?
最佳答案
首先,您需要正确定义在什么条件下两个视频文件被视为相同。您的意思是与逐字节完全相同吗?或者你的意思是内容相同,那么你需要为内容定义一个合适的比较方法。
我假设第一个(完全相同的文件)。这与文件实际包含的内容无关。当您收到文件时,始终为该文件构建哈希值,并将哈希值与文件一起存储。
检查重复项是一个多步骤的过程:
1.) 比较哈希值,如果没有找到匹配的哈希值,则文件是新的。在大多数情况下,对于新文件,您可以预期此步骤是唯一的步骤,良好的哈希(SHA1 或更大的哈希值)对于任何实际数量的文件都很少有冲突。
2.) 如果您发现其他具有相同哈希值的文件,请检查文件长度。如果它们不匹配,则该文件是新的。
3.) 如果哈希值和文件长度都匹配,则您必须比较整个文件内容,当找到第一个差异时停止。如果整个文件比较结果相同,则文件相同。
在最坏的情况下(文件相同),读取两个文件所需的时间不应超过原始 IO 速度。在最好的情况下(散列不同),测试将只花费与散列查找(在数据库或 HashMap 或您使用的任何东西中)一样多的时间。
编辑:您担心构建哈希的 IO。如果您首先比较文件长度并跳过文件长度唯一的所有内容,您可能可以部分避免这种情况。另一方面,您还需要跟踪您已经构建了哈希值的文件。这将允许您推迟构建哈希,直到您真正需要它为止。如果缺少哈希值,您可以直接跳到比较两个文件,同时在同一遍中构建哈希值。需要跟踪的状态要多得多,但根据您的情况,这可能是值得的(您需要一个可靠的数据基础,了解重复文件发生的频率及其平均大小分布才能做出决定)。
关于java - 如何测试两个大视频是否相同?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17090453/