Как я 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 представляет большое количество функционала и возможностей, я ознакомился только с частью из них. В том числе у меня получилось наложить на кадр несколько файлов в посте с Банхаммером с их позиционированием.

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

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

Спасибо, это полезно.
Сам я пробую HandBrake — его в той же статье посоветовали.
У него уже есть готовые пресеты, так что можно конвертить одной кнопкой.

4

Благодарю! Да, мне ночью на него кидал кто-то ссылку. Посмотрю вечером что она предлагает

Помню у меня Мама зашла в комнату, а там в одном из моментов были маты , диск тут же полетел разломанным в мусорку))😂

2

Субтитры пропали. Почему?Потому что -vf subtitles открывает файл субтитров с начала и не знает о перемотке (а в первых секундах надписей не оказалось, они бы прояснили ошибку). Узнает, если добавить -copyts. Но тогда плеер будет показывать, что видео проигрывается не с 00:00, а с 03:16. Это исправляется магией - таким же -ss к выходным аргументам https://stackoverflow.com/a/59576487

Это потому что у меня так и не получилось указать нормальный путь до субтитров.-vf требует линуксового экранирования как минимум для : \ ] [. Легко автоматически преобразовать не получится.
-vf "subtitles=С:\folder\[1080p x264].mkv" - нет
-vf "subtitles=С:/folder/[1080p x264].mkv" - уже лучше
-vf "subtitles=С\\:/folder/\[1080p x264\].mkv" - почему-то да
-vf "subtitles=С\\:\\\\folder\\\\\[1080p x264\].mkv" - к сожалению, да
Но можно заранее переместиться в батнике в папку с этим файлом. Субтитры можно брать из видеофайла https://ffmpeg.org/ffmpeg-filters.html#subtitles-1

-s 640x480Это 4:3. Которое за счёт метаданных показывается как 16:9. Кодировать с неквадратным пикселем плохо. Тебе нужно -vf "...,scale=-2:480".

:: Извлекаем видео без аудиоВ таком варианте оно лишний раз перекодируется. Нужен -c copy или -c:v copy. Хотя тогда вырежет менее точно. Можно перекодировать, но без потерь (-crf 0).
Останутся субтитры и шрифты, есть есть. Можно делать -map 0:v:0 вместо -an.
Ещё если переместить коммент в конец блока, будет ошибка. :: - хак, который плохо дружит со скобками, лучше официальный rem.

-movflags +faststartНужен при кодировании. Только в последнем вызове ffmpeg.

-filter:v fps=23.976Это для прореживания кадров. Для 60fps, например.

В целом получается путь страданий. Надо видеть, какой кусок вырезать, есть вариант использовать Vapoursynth/Avisynth вместе с ffmpeg ради этого.

1

Vapoursynth/AvisynthВ них же можно накладывать субтитры.
Легко автоматически преобразовать не получится.Хотя нет, это просто: https://pastebin.com/T7uhPJnX

1

Спасибо за конструктив! Приму к сведению и попробую в ближайшее время.

Потому что -vf subtitles открывает файл субтитров с начала и не знает о перемоткеДа, поэтому мне пришлось сначала вырезать субтитры из определенного отрезка. Работы в 2 раза больше, но зато есть возможность отредактировать сабы при необходимости, вырезав ненужный кусок.

-s 640x480. Это 4:3Ох, ещё раз спасибо! Набивал от руки и не заметил проблемы, хотел конечно же 16:9.

Комментарий недоступен

1