Video-spectrumizer с чего всё начиналось и к чему пришло

Сегодня я рад представить вам свой долгоиграющий (15 лет!) и долго развивающийся фан-проект — video-spectumizer в том виде, в котором его можно уже отдать общественности в опенсорс.



Что такое video-spectrumizer?

Video-spectrumizer — это cli утилита\программа, которая позволяет преобразовать любое видео в стилизованное под графику с zx spectrum.

Это чё, спектрум на максималках?
Ага, типа того. Представьте, что вам в спектрум завезли очень много мегагерц и\или все инструкции выполняются всего за такт и вы можете выплёвывать графику на экран с экстремально быстрой скоростью, одновременно всю её обсчитав. Т.е. графика у вас честная — пикселы, атрибуты и клешинг конечно же присутствует, а вот филрейт космический.

Ну и зачем?
Just for fun! В основном ради фана, интересно же глянуть как оно могло бы быть на сверхбыстром спектруме. Cчитайте такой виртуальный видео-ускоритель вставили в спек и оно полетело. Но и не только забавы для… Годами ранее (когда это всё было в полу ручном режиме на нескольких скриптах) я успешно делал видеоряд для музыкальных треков, получались довольно залипательные видеоролики (читай видеоклипы), которые не стыдно (а может и стыдно) выложить на видеохостинги. Но обо всём по порядку.

Начало



Всё началось в далёком 2010 году. Однажды я подумал, а как можно выложить демосценовую музыку на видеохостинг, чтобы это не просто было аудио с картинкой, а что-то более менее интересное. Что не только можно было бы слушать, но и с интересом смотреть. Просто мгновение, вспышка, картинка в голове, которая засела в мыслях и не давала мне покоя некоторое время. Крутилась в мозгу, как надоедливая муха. Навязчивая идея, от которой совершенно невозможно избавиться, пока не сделаешь то, что либо приблизит тебя к осуществлению идеи, либо навсегда отдалит.

Когда я понял, что просто так от этой мысли мне не избавиться, то решил попробовать осуществить то, что увидел в своём воображении.

Самое простое — это взять визуальную часть с клипа, обработать и подложить трек. Чтобы видео не превратилось в месиво пикселей и атрибутов я решил потренироваться на максимально монохромной картинке. Сразу вспомнилось музыкальное видео группы A-ha на трек «Take On Me» в таком черно-белом рисованном стиле. Да еще и чиптюн подходящий был под рукой и я начал экспериментировать.

План был достаточно простой:

  1. Из видео нужно сохранить все кадры
  2. Уменьшить размер кадра
  3. Пикселизировать, чтобы получить хоть что-то похожее на рисованный пиксельарт т.е. уменьшить кол-во цветов, привести к какой-то ограниченной палитре и обработать изображение таким образом, чтобы пиксели немного «заострились»
  4. Увеличить каждый кадр
  5. Собрать все кадры и присоединить музыкальный трек

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

Разбивку на кадры я делал в VirtualDub, обработку каждого кадра делал в Photoshop (единственный софт с которым я был хорошо знаком). Для Photoshop я примерно в то же время нашел очень неплохие плагины от XiMagic (XiColorDither, XiDenoiser, XiGrayDither и XiQuantizer) и они долгие годы мне пригождались еще не раз. Естественно, руками обработать тысячи и десятки тысяч кадров — это прям работа для очень упорных упоротых. Поэтому я начал искать способы автоматизации. В Photoshop это довольно просто делается через Actions. Конечно же это всё довольно долго и неповоротливо работало, но работало же!

Не помню уже за давностью лет, но скорее всего работая с первым видео я так и не смог качественно увеличить картинку и обрабатывал все кадры в том размере в котором потом и выгрузил на YouTube (тоже не ахти в каком размере и качестве).

Надо упомянуть, что первые ролики вот примерно в таком, наполовину ручном режиме, делались несколько часов. И если где-то в середине видео картинка превращалась в какое-то серое или наоборот сверхцветное месиво, то всё приходилось переделывать заново. Обычно хватало пару-тройку дублей и можно было управиться за день. Потом я начал видео немного обрабатывать перед разбивкой на кадры, добавлять контраст, яркость, резкость если необходимо. Это свело к минимуму дальнейшую переделку, но всё равно качество на выходе было малопредсказуемо.

Вот так выглядела первая версия пиксельного клипа «A-ha — Take on me»: YouTube | VK (6 декабря 2010 г.)



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

Cкриптуй меня полностью

Пока я укладывал в голове понимание к какому не избыточному качеству я хотел бы приблизится при захвате видео с эмулятора и как не потерять это качество при закидывании на сервера гугла, чтобы ютуб нам всем выдал приемлемую картинку, время от времени я отвлекался на странные, но довольно забавные проекты так или иначе связанные с обработкой видео, аудио и графики. В это же время мне под руку попался совершенно волшебный агрегат — ffmpeg. И всё, с этого момента изменилось практически всё. Обработку аудио и видео (а иногда и графики) я делал только с помощью этого мощнейшего инструмента. Поизучал возможности автоматизации и наделал себе кучку полезных скриптов (а по сути простых батников т.к. я на windows) под все случаи жизни. Пережатие видео, достать аудио, увеличить видео, подрезать начало и конец, сделать гифку в конце-концов. Все действия с медиа контентом были обложены скриптами на любой вкус и цвет.

Это небольшой набор скриптов «на все случаи жизни».




А поскольку скрипты максимально упрощали и автоматизировали процесс, по ходу дела появились несколько проектов, направленных на визуализацию музыкальных треков для выкладывания на видеохостинги. Среди них  Vinylizator — визуализация вращающейся виниловой пластинки. Waves and thumb (этот еще не выложен) — визуализация с обложкой трека и звуковой волной.



Пример Vinilyzator: YouTube | VK
Пример Waves and thumb: YouTube | VK

Попутно стал изучать python, но там меня понесло в сторону ботов для телеграмма, которых тоже уже несколько штук и они исправно работают и даже кто-то иногда ими пользуется :) Тем не менее, у меня был уже собран и работал один разухабистый скрипт для спектрумизации видео.

Пайплайн был уже отработан и выглядел примерно так:

  1. Ffmpeg разбивает видео на кадры и достаёт аудио
  2. Он же эти кадры уменьшает и подрезает под формат спектрум экрана 256×192px
  3. В скрипте делаем паузу и ждём когда пользователь подберёт параметры конвертирования
  4. Конвертируем каждый кадр конвертером img2spectrum и сохраняем как png
  5. Ffmpeg собирает кадры, приклеивает аудио и увеличивает без сглаживания итоговое видео

Да, работало это тоже не сильно быстро, но гораздо быстрее первоначального варианта, ну и каноничная картинка спектрума опять же на выходе, а не какой-то фейковый псевдопиксельарт. Да и возможность подбора параметров конвертера в середине процесса была сильно на руку. Таким образом у меня получился прототип будущего video-spectrumizer. На тот момент такой скрипт у меня жил под рабочим названием FakePixelsVideo.



Единственный недостаток, который меня смущал — это весьма низкая скорость работы этого монструозного агрегата. Вроде бы и машинка не слабая и видео жмётся видеокартой, а всё равно, десяток тысяч кадров могли обрабатываться около часа.

Пример FakePixelsVideo: YouTube | VK

Слабое звено я нашел довольно быстро. Обернул всю внутрянку батника в скрипт на питоне и поизучал скорости выполнения разных частей программы, получилось чуть более удобнее, но скорости в итоге практически не прибавило, хотя стало резвее конечно, а всё от того, что конвертер img2spectrum для каждой конверсии подгружает SDL и конкретно так подтормаживает при этом. Я даже писал разработчику (Sol^hsa) в ишью на гитхабе, мол такая фигня: не могу скриптом тысячу картинок быстро конвертнуть, на что мне дали понять, что я понимаю вашу боль, но софт не был на это рассчитан… конвертируйте по одному и не страдайте гигантизмом. Ну, хозяин барин, не дождёмся мы новой версии, будем обходить эти препятствия. Как известно, если мы не можем решить проблему эффективным кодом, будем заваливать железом! В моём случае «виртуальным».

Кстати, тот же самый «Take on me» через несколько лет я сделал заново и уже с накопленным багажом знаний.

Пример клипа «A-ha — Take on me», сделанного уже при помощи FakeVideoPixels: YouTube | VK (11 октября 2017 г.)— т.е. через 7 лет после первых экспериментов с видео.



Погромируй это

Вот тут надо оговориться, что от осознания невозможности победить тормознутость конвертера до попытки хитро обойти слабое место прошло не много ни мало, два года. За это время как раз я начал чуть глубже интересоваться не только питоном и возможностью использования его как удобнейшего средства скриптования чего бы то ни было, но и стал поглядывать на компилируемые языки. Изучать на старости лет Си — это я прям сразу отверг и понял, что не под силу мне это, да и не добавит в жизни никакой радости. Стал присматриваться к Rust и Go. Ну как присматриваться… попадётся в ютубе что-то про язык и разработку — гляну. Ничего не пойму, вернусь к уже родному и не такому страшному питону. Потом снова что-то почитаю, гляну и снова нее… точно не моё, я ж дизайнер вроде как… Можно мне попроще что-то. Не то чтобы я боюсь, нет, скорее наоборот — весьма меня интересует программирование и даже влечёт временами…

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

Впоследствии, чуть пристальнее присмотревшись к Go я понял, что это именно то, что мне нужно. Он быстрый, он достаточно простой для вхождения не программистам. Т.е. если не углубляться в дебри, то для простых алгоритмов хватает базовых принципов — условия, циклы, математика, какие-то структуры данных простые, функции. Хоть язык и достаточно молодой, но по нему много литературы, документации и куча информации в сети. Согласитесь, вообще ведь то что доктор прописал! Попробовал что-то на простых примерах пописать, поупражняться, покомпилировать и мне понравилось. Да еще и нейросетки сейчас под боком могут кучу всего подсказать, если где затык. Милое дело. Что не сможем додумать, навайбкодим!

Вернёмся к нашему долгоиграющему проекту. Мы помним его слабое место — запуская конвертер мы не можем обрабатывать более одного файла за раз, а вызывая конвертер в цикле, он постоянно подгружает библиотеку и изрядно тормозит нам всю автоматизацию. Так вот, а нельзя ли запустить параллельно несколько конвертеров, чтобы они тормозили, но одновременно? Это уже должно нам сократить время. Т.е. один небыстрый землекоп будет долго копать яму, но 32 небыстрых землекопа всё равно выкопают яму заметно быстрее. Давайте закидаем нашу тормозную задачу виртуальным железом. Как вы уже догадались этим как раз и будет заниматься наша программа на Go. Go изначально рассчитан на работу во многоядерных системах и может запускать процессы параллельно. Вот этим и воспользуемся.



Тут как в фильмах показывают: «Прошло 8 лет»… прежде чем начал появляться первый прототип на Go взамен нашего скрипта на Python или того самого первого батника FakePixelsVideo.bat

И что самое удивительное, предположение с распараллеливанием процессов превзошло все ожидания. Даже самые первые версии программы, где просто брались из папки уже готовые файлы кадров, обрабатывались конвертером и складывались в другую папку, показали, что это происходит гораздо быстрее. Да и похоже это всё больше и больше на магию. Запустил экзешник, получил результат. Это мы дизайнеры такое любим. Не секрет, что наша любимая кнопка «сделать красиво» есть во всех наших дизайнерских программах, просто не все её могут найти и воспользоваться. А тут настоящая кнопка «сделать вообще всё что угодно» — тайная кнопка программистов, которую они от всех скрывают, вдруг нашлась и её можно нажимать.

Начинал я с простого оборачивания уже известного пайплайна обработки и внедрял по ходу дела всякие удобные штуки типа конфига, логов, визуального отображения процесса работы и т.п. Конечно же логика усложнялась т.к. появлялись всякие условия по ходу дела. Например, к версии v1.0.4 появилась возможность сохранять также и все .scr файлы, но сохраняются они только если не установлен флаг удаления временных файлов в конфиге\строке запуска. Добавился выбор каким образом кодировщик будет жать видео: с использованием графического ускорителя или без (даже с выбором nvidia\amd). На amd я, кстати, еще не тестировал (негде пока), так что если не заработает, будем чинить по ходу дела с помощью настоящих программистов, а не только отдельно взятого дизайнера, например.

Как это работает сейчас

Сейчас это программа на Go, которая в многопотоке запускает конвертер, тем самым в разы ускоряя весь процесс обработки. Внутри небольшая логика обработки конфига, а также вызов ffmpeg для разделения аудио и видео, а также для сборки отдельных кадров обратно в видео. По сути это всё та же обёртка для вызова конвертера и ffmpeg, только в исполняемом файле с возможностью разделить на потоки нашу обработку.

Для работы нужно прописать в системную переменную PATH путь, где у вас лежит ffmpeg и ffprobe (используется для определения есть ли звук в исходном видео или нет), еще нужен конвертер «Image Spectrumizer»  img2spec на GitHub от Jari Komppa aka Sol\^hsa. Путь где лежит конвертер прописывается в конфиге (это я сделал заранее, чтобы можно было воспользоваться другим конвертером), но не вынес пока аргументы строки запуска, сделать это надо обязательно, чтобы смена конвертера была вообще прозрачной. Пока что это захардкожено.

  1. Запускаем наш video-spectrumizer, указываем необходимые аргументы или просто прописываем всё в конфиге.
  2. Ждём когда видео заскейлится в нужный нам размер, распакуется на кадры и отделит аудио.
  3. Если в конфиге указана пауза, то программа приостановится, чтобы можно было запустить img2spectrum, подобрать необходимые параметры конвертирования по разным кадрам, сохранить настройки в conv.isw
  4. Далее программа будет на максимальной скорости в несколько потоков конвертировать нам кадры
  5. В конце соберёт видео и удалит все временные файлы (если в конфиге указано их удалять конечно же)

Какие планы

  • Совершенно точно нужно убирать в конфиг захардкоженные аргументы конвертера.
  • Вероятнее всего нужно менять и сам конвертер на что-то более производительное + настройки конвертирования.
  • Может быть прикрутить также сборку .sca раз уж у нас под рукой есть пачка .scr

Всё.

Проект доступен на  Github |  GitVerse

0 комментариев

Только зарегистрированные и авторизованные пользователи могут оставлять комментарии.