#ruby
#ruby
Вопрос:
Я пытаюсь написать сценарий преобразования видео ruby (с использованием ffmpeg), который зависит от файлов mov, передаваемых на сервер.
Проблема, с которой я столкнулся, заключается в том, что когда пользователь загружает большой файл, сценарий просмотра (с использованием rb-inotify) пытается выполнить (и запустить транскодер) до полной загрузки mov.
Я полный нуб. Но я пытаюсь выяснить, есть ли у меня способ убедиться, что мой сценарий просмотра не запускается до тех пор, пока файл (ы) не будет / не будут полностью загружены.
Мой сценарий просмотра здесь:
watch_me = INotify::Notifier.new
watch_me.watch("/directory_to_my/videos", :close_write) do |directories|
load '/directory_to_my/videos/.transcoder.rb'
end
watch_me.run
Спасибо за любую помощь, которую вы можете предоставить.
Ответ №1:
Просто полагаться на inotify(7)
сообщение о том, когда файл был обновлен, не очень подходит для определения того, когда загрузка «завершена» — например, время ожидания сеанса FTP может истечь и быть перезапущено, что позволяет пользователю загружать файл частями в течение нескольких дней, поскольку подключение является дешевым или надежнымили доступен. inotify(7)
только когда-либо видит открытие, закрытие, переименование и доступ к файлу, но никогда не событие более высокого уровня «Я закончил изменять этот файл», как это понимает пользователь.
Я могу придумать два механизма: один заключается в том, чтобы сначала загружать файлы в один каталог и просить пользователя переместить файл в другой каталог после завершения загрузки. Другой создает некоторые метаданные файла на клиенте и использует их, чтобы «знать», когда загрузка завершена.
Переместить завершенные файлы вручную
Если ваши пользователи загружают в каталог ftp/incoming/temporary/
, они могут загружать файл через столько подключений, сколько требуется. Как только файл «завершен», они могут переименовать файл ( rename ftp/incoming/temporary/hello.mov ftp/incoming/complete/hello.mov
), и ваш rb-inotify
интерфейс ищет переименования файлов в ftp/incoming/complete/
каталоге и запускает ffmpeg(1)
команду.
Генерировать метаданные
Чтобы передача была «полной», вам действительно нужны две вещи:
- Размер файла одинаков в обеих системах.
- Файл идентичен в обеих системах.
Поскольку «идентичный» в противном случае трудно проверить, большинство людей довольствуются проверкой, функционирует ли содержимое файла при запуске через криптографическую хэш-функцию, такую как MD5 или SHA-1 (или лучше, SHA-224, SHA-256, SHA-384 или SHA-512). MD5 вполне подходит, если вы защищаете от неполной передачи, но если вы намерены использовать вывод функции для других целей, было бы разумно использовать более сильную функцию.
MD5 действительно заманчив, поскольку инструменты для создания и проверки хэшей MD5 очень распространены: md5sum(1)
в большинстве систем Linux, md5(1)
в большинстве систем BSD (включая OS X).
$ md5sum /etc/passwd
c271aa0e11f560af419557ef49a27ac8 /etc/passwd
$ md5sum /etc/passwd > /tmp/sums
$ md5sum -c /tmp/sums
/etc/passwd: OK
md5sum -c
Команда просит md5sum(1)
программу проверить файл хэшей и имен файлов на правильность. Это выглядит немного глупо, когда используется только для одного файла, но когда у вас есть десятки или сотни файлов, приятно позволить программному обеспечению выполнить проверку за вас. Например: http://releases.mozilla.org/pub/mozilla.org/firefox/releases/3.0.19-real-real/MD5SUMS — Mozilla опубликовала такие файлы с 860 записями — проверять их вручную было бы утомительно.
Поскольку проверка хэшей может занять много времени (в моей системе пять минут на проверку часового видео высокой четкости, которое недавно не использовалось), было бы неплохо проверять хэши только при совпадении размеров файлов. Измените свой инструмент загрузки, чтобы отправлять некоторые метаданные о том, какой длины файл и каков его криптографический хэш. Когда ваш rb-inotify
скрипт видит запросы на закрытие файла, проверьте размер файла, и если размеры совпадают, проверьте криптографический хэш. Если хэши совпадают, запустите свою ffmpeg(1)
команду.
Ответ №2:
Кажется, проще загрузить файл во временную директорию на сервере и переместить его в то место, которое просматривает ваш скрипт, после завершения передачи.