Как проверить, совпадают ли 2 больших видео?
У меня есть система, в которой загружаются видеофайлы, а затем запускается несколько задач с интенсивным использованием процессора. Поскольку эти задачи требуют больших вычислительных ресурсов, я бы хотел пропустить обработку файла, если он уже был обработан.
Видео поступают из разных источников, поэтому имена файлов и т. Д. Не подходят.
Если бы я использовал изображения, я бы сравнил хеш MD5, но для видео размером 5–40 ГБ это может занять много времени.
Для сравнения 2 видео я тестирую этот метод:
- проверить соответствующие метаданные соответствия
- проверьте длину файла с помощью ffmpeg / ffprobe
- используйте ffmpeg для извлечения кадров с 100 предварительно заданными временными метками [1-100]
- создать MD5 хэши каждого из этих фреймов
- сравните хэши MD5, чтобы проверить совпадение
Кто-нибудь знает более эффективный способ сделать это? Или лучший способ подойти к проблеме?
4 ответа
Во-первых, вам нужно правильно определить, при каких условиях два видеофайла считаются одинаковыми. Вы имеете в виду точно такой же, как в байтах? Или вы имеете в виду идентичные по содержанию, тогда вам нужно определить правильный метод сравнения для содержания.
Я предполагаю первый (точно идентичные файлы). Это не зависит от того, что файлы на самом деле содержат. Когда вы получаете файл, всегда создайте хеш для файла, сохраните его вместе с файлом.
Проверка на дубликаты - это многоэтапный процесс:
1.) Сравните хэши, если вы не нашли подходящих хэшей, файл новый. В большинстве случаев нового файла вы можете ожидать, что этот шаг будет единственным шагом, хороший хеш (SHA1 или что-то большее) будет иметь несколько коллизий для любого практического числа файлов.
2.) Если вы нашли другие файлы с таким же хешем, проверьте длину файла. Если они не совпадают, файл новый.
3.) Если и хеш, и длина файла совпадают, вам нужно сравнить все содержимое файла, остановитесь, когда найдете первое различие. Если весь файл сравнения оказывается идентичным, то файл тот же.
В худшем случае (файлы идентичны), это не займет больше времени, чем скорость ввода-вывода для чтения двух файлов. В лучшем случае (хэши различаются) тест займет столько же времени, сколько и поиск хеша (в БД, в HashMap или в любом другом месте).
РЕДАКТИРОВАТЬ: Вы обеспокоены IO для создания хэша. Вы можете частично избежать этого, если сначала сравните длину файла и пропустите все, длина файла уникальна. С другой стороны, вам также необходимо отслеживать, для каких файлов вы уже создали хеш. Это позволит вам отложить создание хэша, пока он вам действительно не понадобится. В случае отсутствия хеша вы можете сразу перейти к сравнению двух файлов, создавая хеши за один проход. Его гораздо больше, чтобы отслеживать, но оно может стоить того, в зависимости от вашего сценария (вам нужна надежная база данных о том, как часто встречаются дубликаты файлов и их распределение по среднему размеру, чтобы принять решение).
Я бы начал с длины файла (быстрый и грязный), продолжил с MD5 и закончил с проверкой кадров. Быстро и просто.
Конечно, если вы получите отредактированный файл, он даст вам ложные отрицания, но тогда он, вероятно, даст вам ложные отрицания для MD5 и, возможно, даже с проверкой четных кадров; предотвращение ложных негативов из-за редакции было бы настолько вычислительно дорогим, что, вероятно, лучше просто игнорировать их.
Хэшируйте свои файлы и следите за хешами. Вот пример: Получение контрольной суммы MD5 в Java
имейте в виду, что, хотя это крайне маловероятно, математически возможно, чтобы два разных файла давали одинаковый хэш. если вы имеете дело с безбожно большим количеством файлов (порядка 2^128 файлов), то вам нужен лучший алгоритм хэширования... как SHA2-256. Но это, вероятно, не тот случай, здесь.
MD5 Hash довольно медленный. Подумайте об использовании более быстрой хеш-функции, такой как MurmurHash.
У него очень хорошее сопротивление столкновению, и оно довольно быстрое.
Кроме того, вы должны сначала проверить размер файла, который не займет много времени и позволит избежать ненужных вычислений хеша.