Что случилось на r/LocalLLaMA: видео на чистом JS вместо Remotion
19 сентября 2026 года в r/LocalLLaMA появился пост, автор которого повторил своё предыдущее видео на чистом JavaScript вместо Remotion. Повод простой: пользователь попросил сделать то же самое без фреймворка. Формулировка в заголовке звучит так: «A person asked me to create my previous video with JS intead of remotion, so here you go». Опечатку в слове instead оставил как в исходнике.
В треде выделились две линии. Первая: что такое видеокодинг на JS, в обсуждении есть ссылка с подписью «Whats JS video coding?». Вторая: сравнение подходов, где Remotion описывает сцены декларативно через React-компоненты, а чистый JavaScript заставляет вручную управлять кадрами и рендерингом. Главное, что цитируют из треда, касается модели: «Glm 5.3F is not usable now for complex JS videos, but it is pretty good with remotion».
Оговорка, важная для всего дальнейшего текста: это опыт одного автора в одном посте. Воспроизводимых тестов, замеров времени рендера и сравнения на наборе задач в обсуждении нет. Поэтому дальше речь пойдёт о логике двух подходов и о том, как её читать тому, кто собирается генерировать видео кодом с помощью LLM. Если планируете публиковать собственный видеокейс в этом сообществе, пригодится разбор требований Project Showcase в r/LocalLLaMA.
Исходное обсуждение: пост «A person asked me to create my previous video with JS intead of remotion».
Что такое видеокодинг на JavaScript и зачем он нужен
Видеокодинг - это способ собирать видео программно: каждый кадр описывается кодом, а не рисуется руками в монтажной программе. Программа проходит по временной шкале, для каждой отметки времени вычисляет, что должно быть на экране, и сохраняет результат. Затем кадры склеиваются в файл.
Технически вариантов немного:
- покадровый рендер в offscreen canvas или в headless-браузере и сборка изображений в видео;
- отрисовка сцены на canvas или через WebGL с захватом потока (MediaRecorder, WebCodecs);
- сохранение последовательности PNG и кодирование внешним инструментом, например ffmpeg.
Практических задач у подхода много: титры и субтитры для серии роликов, графики, которые пересобираются из свежих данных, персонализированные видео с подстановкой имени и цифр, анимации для презентаций и лендингов, десятки однотипных клипов, которые дорого монтировать вручную. Общий признак таких задач: содержание меняется, структура остаётся. Поменялась цифра в отчёте - видео пересобирается одной командой.
Второй сценарий, который сейчас становится основным: код пишет LLM. И тут критично, насколько предсказуемую структуру модель должна породить.
Remotion: декларативный подход через React-компоненты
Remotion - фреймворк для создания видео на React. Сцена описывается как компонент, а кадр как функция от текущего времени. Разработчик не перебирает кадры вручную, он пишет: на 30-м кадре заголовок появляется, к 60-му уезжает влево. Что произойдёт между этими точками, фреймворк интерполирует сам.
Типовой код выглядит так:
const frame = useCurrentFrame();
const x = interpolate(frame, [0, 90], [100, 300]);
return <Box left={x} />;
Здесь видны три идеи Remotion. Кадр детерминирован: при одном и том же номере кадра и одних пропсах результат совпадает, скрытого состояния между запусками нет. Композиция собирается из переиспользуемых компонентов, как интерфейс в React. Временная шкала описана декларативно: Sequence задаёт, когда сцена появляется и сколько длится, interpolate и spring превращают номер кадра в значения анимации.
Рендеринг фреймворк берёт на себя: кадры отрисовываются в headless-браузере и собираются в видеофайл. Разработчику не нужно думать про кодировщик, fps и склейку, он отвечает за содержание кадра.
Аналогия с React для интерфейсов работает буквально. В обычном React вы описываете, как выглядит экран при данном состоянии, а библиотека решает, что перерисовать. В Remotion вы описываете, как выглядит кадр при данном времени, а рендерер сам обходит всю шкалу.
Для генерации кода LLM это удобно: у сцены есть явная структура (композиция, последовательности, пропсы), есть небольшой набор функций, которые нужно знать, и почти нет скрытого состояния. Ошибка в таком коде обычно локальна: не тот диапазон кадров, не тот пропс, забытая обёртка Sequence. Логика простая: чем меньше степеней свободы, тем выше шанс, что модель соберёт рабочий вариант с первого прохода.
Чистый JavaScript: императивный контроль над каждым кадром
Без фреймворка всё лежит на разработчике. Нужно самим организовать цикл по кадрам, посчитать состояние для каждого момента времени и записать результат:
const fps = 30;
const seconds = 3;
for (let frame = 0; frame < fps * seconds; frame++) {
const t = frame / fps;
const x = 100 + t * 200;
drawFrame(ctx, x);
await saveFrame(frame);
}
Позицию объекта, прозрачность, поворот, порядок отрисовки, момент появления текста считаете вручную. Тут же решается вопрос кодирования: через MediaRecorder, WebCodecs, ffmpeg.wasm или отдельным проходом по сохранённым кадрам.
Плюс подхода в свободе. Если нужен нестандартный эффект на canvas, шейдер на WebGL, интеграция с существующим рендер-кодом или вывод кадров не в видеофайл, а в другой пайплайн, чистый JS даст то, что фреймворк не предусматривает. Минус очевиден: больше кода, больше ручной работы и больше мест, где что-то незаметно разъедется.
Типичные грабли такого кода: сдвиг на один кадр (frame < total против frame <= total), дрейф длительности при дробном fps, забытый await при записи кадра, лишнее состояние между итерациями, из-за которого второй рендер отличается от первого, неверный кодек или битрейт, чёрные кадры в начале файла. Каждая мелочь ломает результат целиком, потому что промежуточное состояние тут никто не проверяет автоматически.
Из-за отсутствия декларативных абстракций этот путь хуже подходит для генерации LLM: модель должна написать анимацию, придумать архитектуру рендера и не ошибиться в тайминге, состоянии и кодировании одновременно.
Почему LLM лучше справляются с Remotion, чем с чистым JS
Разница в результатах объясняется структурой задачи. Модель не «понимает» видео, она генерирует код по паттернам, и от количества этих паттернов зависит итог.
- В Remotion код кадра - чистая функция от номера кадра. Модели не нужно изобретать конечный автомат, достаточно связать время и значения.
- Набор сущностей ограничен: композиция, Sequence, useCurrentFrame, interpolate, spring. Вариаций их использования немного.
- Ошибки локализованы. Неверный диапазон в interpolate даёт неправильную анимацию, но не роняет рендер целиком.
- Кодирование и склейка скрыты внутри фреймворка, поэтому ошибиться в этих частях модель просто не может.
В чистом JS решений приходится принимать больше: как организовать цикл, где хранить состояние, чем кодировать, как не потерять кадр при асинхронной записи. Чем больше таких решений, тем выше вероятность, что хотя бы одно окажется неверным, и ролик получится со сбитым таймингом или без части сцен.
Автор поста описывает ровно этот разрыв: «Glm 5.3F is not usable now for complex JS videos, but it is pretty good with remotion» (источник). Формулировку стоит читать буквально: речь про сложные сцены на голом JS, а не про видеокодинг в целом. Ни списка задач, ни времени генерации, ни числа попыток в посте нет, так что это личное наблюдение автора, а не независимое тестирование.
Что уже под силу LLM в генерации видео кодом, а где нужна ручная доработка
Границу удобно провести по типу задачи. Таблица ниже - рабочая ориентировка, собранная из устройства двух подходов и наблюдения автора поста; опубликованных бенчмарков за ней нет.
| Задача | Remotion | Чистый JS |
|---|---|---|
| Титры, подписи, появление текста | Обычно получается с первой или второй попытки | Реально, но тайминг приходится проверять вручную |
| Таймлайн из нескольких сцен | Композиции и Sequence дают предсказуемую структуру | Нужен свой планировщик кадров |
| Графики и анимация по данным | Удобно: данные в пропсах, анимация через interpolate | Работает, но много ручной математики |
| Переходы, затемнения, сдвиги | Типовые приёмы, модели их знают | Требует аккуратного расчёта прогресса |
| Синхронизация с аудиодорожкой | Возможна, но нужна покадровая проверка | Почти всегда ручная доводка |
| 3D, шейдеры, эффекты на canvas | Ограничено возможностями фреймворка | Максимальный контроль, высокий риск ошибок у LLM |
Вывод из таблицы простой. Всё, что сводится к «текст и фигуры, меняющиеся во времени», LLM делает уверенно, особенно в Remotion. Всё, что требует собственного движка рендеринга или точной синхронизации с медиа, упирается в ручную доработку: посмотреть кадры, поправить диапазоны, проверить длительность и только потом запускать финальный рендер.
Отсутствие бенчмарков не мешает проверять результат самостоятельно. Дешёвый способ - рендерить черновик в низком разрешении и смотреть не весь ролик, а конкретные кадры на стыках сцен: там ошибки видны сразу.
Как выбрать между Remotion и чистым JS для своей задачи
Ориентиры, по которым решение принимается быстрее всего:
- Задача типовая. Титры, слайд-шоу, графики, промо с текстом и переходами. Берите Remotion: меньше кода, предсказуемый рендер, выше шанс, что LLM выдаст рабочую версию.
- Нужен нестандартный рендеринг. Свои шейдеры, работа с canvas-движком, покадровая обработка пикселей, вывод не в mp4, а в другой пайплайн. Тут чистый JS, потому что фреймворк придётся обходить.
- Есть React-опыт. Remotion осваивается почти сразу: компоненты, пропсы и хуки те же. Без опыта в React порог входа выше, но всё равно ниже, чем у собственного рендер-цикла.
- Рендер нужно автоматизировать. Remotion рассчитан на запуск из командной строки и сборку в CI, что удобно для серийных роликов. В чистом JS автоматизацию придётся строить самому.
- Планируете активнее использовать LLM. Чем больше структуры в коде, тем полезнее модель. Декларативные сцены дают ей каркас, императивный цикл заставляет угадывать архитектуру.
Компромисс, который часто оказывается лучшим: сцены и анимацию делать в Remotion, а нестандартные куски рисовать на canvas и встраивать внутрь композиции отдельным компонентом. Таймлайн остаётся предсказуемым, и место для ручного контроля там, где он реально нужен, тоже сохраняется.
Если решение уже принято и есть что показать сообществу, полезно заранее пройти по чек-листу публикации проекта в r/LocalLLaMA: там разобрано, как описать проект и подтвердить, что код открыт.
Итоги: что важно запомнить о генерации видео кодом и LLM
Короткая сводка. Remotion описывает сцены декларативно через React-компоненты, чистый JavaScript требует императивного управления кадрами, состоянием и кодированием. Декларативная схема даёт LLM предсказуемую структуру, поэтому модели ошибаются в ней реже. По наблюдению автора поста на r/LocalLLaMA, GLM 5.3F сейчас не годится для сложных JS-видео, но показывает хорошие результаты с Remotion.
Что делать с этим на практике. Возьмите одну простую сцену: заголовок, подзаголовок и плавное появление блока. Попросите модель сгенерировать её в Remotion, отрендерите пару секунд и проверьте кадры на стыках анимации. Если результат устроил, добавляйте сцены по одной, а не все сразу. На чистый JS переходите тогда, когда фреймворк перестал давать нужный контроль: так вы получите рабочий ролик раньше, чем напишете свой рендерер.