Как я Dead Space Downfall на кадры нарезал

В связи с грядущим выходом ремэйка Dead Space и неявным продолжителем серии The Callisto Protocol я пересмотрел приквел к оригинальной игре и хочу поделиться некоторыми интересными моментами из этого анимационного хоррора.

В конце статьи я разовью мысль одной из недавних статей о том, как же правильно делать автоматически запускающиеся видео и как это сделать при помощи ffmpeg. Разберусь сам и покажу на примере.

Приятного просмотра!

Алиса Винсент -- глава службы безопасности USG Ишимура
Экипаж Ишимуры сходит с ума
Им нужны наши тела...
Появление некроморфов в USG Ишимура
Тем временем в морге
I saw some shit
Первая встреча с некроморфом
Nice dick
Лазерный резак
Я капитан!
Толстяк
Мелкая тварь
Жилые помещения
Первая и единственная задница
Мертвый космос. Со звуком

Начало работы с ffmpeg

Немного вводных

Ранее я никогда не имел дело с видео контентом, но наткнувшись на одну из статей и комментарии к ней, мне стало любопытно попробовать способ нарезки через ffmpeg. Поскольку я сам работаю в IT, то порог вхождения меня не испугал. Да и в конце концов ffmpeg у меня уже давно лежит в беклоге программиста.

В качестве подопытного у меня оказался видео файл со следующими характеристиками:

В видео файле собран полный пакет необходимого: аудио дорожки и субтитры на разных языках, а также дополнительные метаданные
В видео файле собран полный пакет необходимого: аудио дорожки и субтитры на разных языках, а также дополнительные метаданные

Готовим рабочее место

В этом разделе я по шагам расскажу о том как я пришел от оригинального видео файла к одному из вырезанных кадров.

Первым делом надо посмотреть фильм, выделить интересные моменты и подготовить директорию к работе. У меня получился следующий сетап:

Основной видео файл, скрипт нарезки, тайминги и директория с итоговой нарезкой
Основной видео файл, скрипт нарезки, тайминги и директория с итоговой нарезкой

Теперь когда у нас все готово, можем начинать писать скрипт.

Собираем кадр

Для того чтобы загрузить и обработать видео файл через ffmpeg надо указать входной и выходной файлы. И тех и тех может быть несколько, но усложнять не будем:

ffmpeg -i .\DeadSpaceDownfall.mkv FirstEncounter\FirstEncounter_cut.mp4​

Команда в таком виде нам не нужна, но от нее уже можно отталкиваться. Нам же нужно вырезать кадр. Для этого укажем тайминги аргументами -ss и -to:

ffmpeg -ss 00:03:16.5 -to 00:03:33.5 -i .\DeadSpaceDownfall.mkv -y FirstEncounter\FirstEncounter_cut.mp4

Сразу добавим аргумент -y для автоматического пересохранения файла. Скрипт будет выполняться часто по мере написания, поэтому упрощаем себе жизнь где можем.

На выходе мы получил файл размером в 4мб. Неплохо! Уже укладываемся в заветные 5мб для авто воспроизведения, может нам тогда не продолжать? Как оказалось, нет. За авто воспроизведение отвечают не сколько размер файла, а его готовность к работе в браузере. Но об этом чуть-чуть попозже.

Вырезаем субтитры

В данном отрывке героиня в центре просто открывает рот, но хочется знать зачем. Давайте выведем субтитры для этого.

Как оказалось в ffmpeg удобнее всего работать последовательно по шагам и не пытаться сделать все сразу. Поэтому вырежем субтитры из видео файла и попробуем наложить их на результат.

Для того чтобы вырезать субтитры выполним команду:

ffmpeg -i .\DeadSpaceDownfall.mkv -map 0:s:0 -ss 00:03:16.5 -to 00:03:30.5 -y FirstEncounter_subs.ass

Здесь нас интересует параметр -map 0:s:0. Как я понимаю, читается это так на человеческом: из первого входного файла (-i) берем первый поток субтитров (s:0). В первом потоке лежат субтитры "по-умолчанию". В данном случае русские, во втором (s:1) английские.

Также я указываю интервал для вырезки субтитров, поскольку я не хочу иметь субтитры для всего видео ряда и потом его синхронизировать с отрезком. Уже пробовал -- затея дурацкая. Интервал для субтитров чуть короче самого кадра -- это потому что я не хочу отображать вторую фразу.

Содержимое получившегося файла субтитров
Содержимое получившегося файла субтитров

Теперь мы готовы наложить получившиеся субтитры на отрезок:

ffmpeg -ss 00:03:16.5 -to 00:03:33.5 -i .\DeadSpaceDownfall.mkv -vf "subtitles=FirstEncounter_subs.ass" -y FirstEncounter\FirstEncounter_subs.mp4

Вы должны были заметить, что субтитры лежат почему-то в корне, а не в папке с остальными файлами кадра. Это потому что у меня так и не получилось указать нормальный путь до субтитров.

Готовим файл к работе в браузере

Получившийся видео файл мне нравится уже больше. Вырезан нужный отрезок и понятно о чем говорит персонаж. Что нам остается?

А теперь мы можем подготовить файл к исполнению в браузере. Для этого добавим специальный флаг, который перенесет некоторые метаданные о файле в самое начало бинарника. Таким образом, можно будет начать воспроизводить файл без полной его загрузки на устройство:

ffmpeg -ss 00:03:16.5 -to 00:03:33.5 -i .\DeadSpaceDownfall.mkv -vf "subtitles=FirstEncounter_subs.ass" -movflags +faststart -y FirstEncounter\FirstEncounterFastStart.mp4

Теперь видео файл автоматически запускается, но все еще имеет один недостаток: это по прежнему видео файл с аудио дорожкой, который автоматически воспроизводится без звука и останавливается после его окончания. Наша же цель получить плавный автозапуск и зацикленность. Поэтому добавим также флаг -an:

ffmpeg -ss 00:03:16.5 -to 00:03:33.5 -i .\DeadSpaceDownfall.mkv -vf "subtitles=FirstEncounter_subs.ass" -movflags +faststart -an -y FirstEncounter\FirstEncounter_woaudio.mp4

Сжимаем файл

Теперь мы получили то что хотели! Осталось только поработать под размером файла.

Для этого добавим сжатие флагом -crf x, где x число от 0 до 51. Чем число больше, тем хуже качество и меньше размер результативного файла.

Также укажем новое разрешение флагом -s 640x480 и количество fps. Их я взял из метаданных видео файла и не изменял. Получается строка такого вида:

ffmpeg -ss 00:03:16.5 -to 00:03:33.5 -i .\DeadSpaceDownfall.mkv -vf "subtitles=FirstEncounter_subs.ass" -filter:v fps=23.976 -crf 28 -s 640x480 -y FirstEncounter\FirstEncounter_LowRes_wosubs.mp4

На выходе получаем файл размером 284 кб и совершенно не тот результат, который я хотел. Субтитры пропали. Почему?

Как оказалось, ffmpeg накладывает субтитры по его исходному размеру видео. Поэтому субтитры как бы присутствуют, но ты их не видишь. Они за экраном. Я пробовал масштабировать размер субтитров, но у меня это не удалось. Поэтому я сделал проще: взял для сжатия за основу видео файл предыдущего шага.

Итоговый скрипт

Поработав еще чуть-чуть над скриптом, добавив переменные и условия, у меня получился скрипт следующего содержания:

0.general.cmd

@echo off set dirName=%1 set from=%2 set to=%3 set includeSubs=%4 set toSubs=%5 set quality=%6 if "%quality%"=="" set quality=28 if not exist %dirName% mkdir %dirName% if %includeSubs%==1 ( :: Извлекаем сабы ffmpeg -i .\DeadSpaceDownfall.mkv -map 0:s:0 -ss %from% -to %toSubs% -y %dirName%_subs.ass ffmpeg -ss %from% -to %to% -i .\DeadSpaceDownfall.mkv -vf "subtitles=%dirName%_subs.ass" -movflags +faststart -an -y %dirName%\%dirName%_woaudio.mp4 ) else ( :: Извлекаем видео без аудио ffmpeg -ss %from% -to %to% -i .\DeadSpaceDownfall.mkv -movflags +faststart -an -y %dirName%\%dirName%_woaudio.mp4 ) :: Сжимаем ffmpeg -i .\%dirName%\%dirName%_woaudio.mp4 -filter:v fps=23.976 -crf %quality% -s 640x480 -y %dirName%\%dirName%_LowRes.mp4

FirstEncounter.cmd

@echo off .\0.general.cmd FirstEncounter 00:03:16.5 00:03:33.5 1 00:03:30.5

В результате выполнения получаем сжатый файл с автозапуском, зацикленностью, субтитрами и возможностью регулирования качества. В процессе написания скрипта были моменты, которые не получилось решить, но получилось обойти.

ffmpeg представляет большое количество функционала и возможностей, я ознакомился только с частью из них. В том числе у меня получилось наложить на кадр несколько файлов в посте с Банхаммером с их позиционированием.

Оригинальная статья

36
14 комментариев