От холста к студии: библиотека, параллельный запуск и авто-оформление роликов
В прошлой части я показывал холст — граф, на котором собирается один ролик. С тех пор у него появилось имя, Vini Studio, и, что важнее, он перестал быть просто графом. Он стал рабочим пространством. Не линейкой, как CapCut или Premiere, где ты таскаешь клипы по дорожке и живёшь в рамках таймлайна. А холстом, где помещается вся идея целиком и где можно разложить по полочкам и мысли, и ресурсы.
Сам холст я разбирал в четвёртой части, а работу с элементами — в пятой. Здесь — про то, что я добавил как архитектор, чтобы конвейер из одного ролика превратился в студию, где ролики идут пачками.
Библиотека: закладки всегда сверху
Элементы — персонажи, объекты, локации — раньше жили как «души» и референсы. Теперь это нормальная библиотека: у каждого элемента есть описание и характеристики, а любимые я держу в закладках, и они всегда сверху. Не надо каждый раз выуживать нужного героя из общей кучи.
Но интереснее то, что под капотом. Библиотека и кэш рендера у меня — это одно и то же. Внизу одна таблица артефактов, и у каждого артефакта есть подпись: хэш от модели, промпта, набора референсов и параметров. Когда нода собирается что-то генерить, она сначала смотрит — а нет ли уже артефакта с такой подписью? Есть — берём готовое, ноль долларов. Нет — генерим и пишем новую строчку. А «выбрать из библиотеки» — это ровно тот же запрос, только руками, а не автоматом. Один механизм закрывает сразу две задачи: не платить дважды за одно и то же и переиспользовать то, что уже сделал. Про бесплатный перепрогон я говорил ещё в четвёртой части — это его вторая половина, повёрнутая к пользователю лицом.
И описания у элементов не для красоты. Они уходят в два места разом: в генератор референсов, чтобы картинка вышла правильной, и в сценариста, чтобы он не пририсовал шерифу шляпу из капусты — про этот баг я подробно рассказывал в четвёртой части. Раньше, когда я готовил сценарий, я таскал описания героев между вкладками руками. Теперь элемент несёт свою справку сам, и всё складывается без копипаста.
Менеджер промптов: системные и свои
Промпт — это тоже артефакт, который глупо писать заново каждый раз. Поэтому появился менеджер промптов, и в нём два уровня. Есть системные — они лежат в файлах как источник истины и доступны всем. И есть мои личные, которые я накапливаю между проектами и переиспользую.
Звучит буднично, но именно из таких мелочей и собирается ощущение инструмента, а не игрушки. Не надо бегать, крутиться и в сотый раз набивать один и тот же текст — открыл, вставил, поехали.
Пересказ прошлой серии: узел памяти
Мне нравится давать модели контекст из прошлых серий — так история не рвётся между роликами. Но полный сценарий предыдущей серии огромный, его не вклеишь целиком: разом сожрёшь весь бюджет контекста, а модель захлебнётся в деталях.
Поэтому я сделал отдельный узел. Скармливаю ему весь текст сценария и прошу: сделай краткий пересказ, уложись примерно в тысячу токенов. Он возвращает сжатую выжимку — вот её я и передаю дальше, в контекст следующей серии. По сути это сжатие контекста, оформленное как нода. И для меня это знакомая архитектурная задача: любая долгоживущая система не может тащить с собой всё, она хранит сжатое состояние и работает с ним.
Параллельный запуск: хочется творить, а не ждать
Хочется творить и не хочется ждать. Когда на графе шесть сцен, каждая сцена — это независимая цепочка «картинка → видео». Гонять их по очереди незачем. Так что запуск я сделал параллельным: жмёшь один раз, и все сцены уходят считаться разом.
И вот тут я поймал показательный баг. Графовая библиотека, на которой стоит холст (litegraph, та же, что под ComfyUI), умеет сама вычислять порядок выполнения. Но на графе с ветвлением — один сценарист кормит шесть сцен — она иногда выдавала порядок, который топологически неверен: третья цепочка пыталась стартовать раньше сценариста, от которого зависит. Гонка на ровном месте.
Чинил так: перестал доверять порядку от библиотеки и стал собирать расписание сам. Промис каждой ноды строится рекурсией по настоящим рёбрам зависимостей — по тому, кто откуда реально берёт вход. Нода физически не может стартовать, пока не готовы её входы, что бы там ни насоветовала библиотека. После этого восемь прогонов теста из восьми — зелёные, до фикса было ноль. Скучная инженерия, но именно она позволяет нажать «запуск» и уйти пить кофе.
Субтитры: с того, что реально сказано
Появилась нода субтитров. Она прослушивает звук готового ролика, находит промежутки речи и отдаёт SRT и VTT.
Неочевидное решение тут одно: субтитры строятся не из моего сценария. Видеомодель говорит по-своему — не слово в слово, она перефразирует. Если бы я вжёг в кадр свой сценарий, субтитры разъехались бы со звуком. Поэтому нода берёт реальную дорожку финального клипа, прогоняет через whisper с таймкодами и собирает субтитры из того, что действительно прозвучало. Дальше — проход перевода, с сохранением порядка реплик. На выходе SRT и VTT, выровненные по факту, а не по замыслу.
Оформление: дизайн-система из одного промпта
Дальше — оформление: хардсабы, аутро, титры, плашки. Вся упаковка ролика.
Тут самое забавное. Дизайн-систему для оформления я сгенерировал одним промптом — вбросил модели «сделай мне какую-нибудь дизайн-систему», и она сделала какую-то. И вот эта «какая-то» теперь и рулит упаковкой. Нода читает дизайн-систему — шрифты, цвета, градиенты — плюс те самые VTT, модель строит план вставок (где и когда показать плашку, с якорной цитатой из субтитра, чтобы плашка встала ровно в момент реплики), а рендерит всё Remotion в headless-хроме: субтитры, вау-плашки, титры глав, аутро. Рендер стоит ноль — он локальный, платишь только за план, пару центов.
И честная инженерная история, без неё картинка была бы глянцевой. Нода рендера меня покусала. Remotion в контейнере без лимита памяти хапал половину оперативки хоста, и его убивал OOM. А две тысячи кадров при одном потоке рендера вылетали за пятиминутный таймаут. Вылечил лимитом памяти, потолком кэша, тремя потоками и таймаутом на двадцать минут — и зафиксировал это константами в тестах, чтобы оно молча не отъехало обратно. Некрасиво, зато это и есть разница между «работает на демо» и «работает, когда жмёшь запуск в два часа ночи».
Открытка, теги — и во что это складывается
Сверху приятные мелочи. Стилизованная открытка с персонажами — по тому же принципу: системный промпт плюс элементы, и получилась красивая штука. Описание и теги для TikTok — тоже, причём теги ржачные вышли.
Полноценным блогером я себя не считаю, канал веду между делом. Но цифры сдвинулись: ролики стали доходить до восьмисот показов, а прошлая серия дала 22% полных досмотров — мой личный рекорд. Держат людей как раз вот эти мелкие фишки, которые я тут перечислил. И всё это не за двести долларов и не за миллион экспериментов. Двенадцать баксов за ролик — вот и вся смета.
А в планах у студии — превратить её в настоящую контент-фабрику. Если вам зашло бы собирать ролики в такой системе или интересно сотрудничество — напишите мне под видео. Наберётся интерес, договоримся.