astra-component-video — Видео в стиле Astra DS
Источник:
ds-internal/presentations/component-video-skill/SKILL.md— пакет скилла, готовый архивdist/astra-component-video.zip. README, вход для агентов без скиллов и справочники — вложенные страницы. В вики не выложены: шаблонtemplate/(кладётся в пакет при сборке изds-internal/presentations/component-video),tools/build.mjs,tools/selftest.mjs,tools/voice_check.py,pack.py,requirements.txt,examples/,dist/. Справочникreferences/infostyle.mdкладётся в пакет при сборке изds-internal/writing/infostyle.mdи отдельно не выложен.
Шапка скилла:
name: astra-component-video
description: Собирает видео в фирменном стиле Astra Design System — 4:3, 1440×1080, MP4 со звуком; интро Astra DS → обложка → сцены → финал «разработано дизайн-командой». Ролики о доработке компонента (новое свойство, Type Scale, матрица вариантов, экраны, касания), обучающие видео-презентации (переходы, токены) и объясняющие ролики с голосом диктора (процесс, формат, решение) — с раскадровкой на согласование, локальным синтезом речи и проверкой голоса распознаванием. Движок, фон, шрифт, хронометраж, музыка и голос зафиксированы в шаблоне скилла; под ролик пишутся только данные и кадры, поэтому результат одинаков у любой модели. Use for any request to make an Astra DS video — «сделай видео по доработке <компонент>», «ролик о доработке», «видео-презентация», «расскажи голосом», «ролик с озвучкой», «анимация для команды».
Один запрос — один готовый MP4. Например: «сделай видео по доработке Current Product AF, вот ссылки на Figma и описание» или «собери объясняющий ролик с голосом по этому сценарию».
Почему у всех выходит одинаково
Ролик = шаблон + данные + кадры.
- Шаблон лежит в
template/этого скилла: движок сцен, стили, фон, шрифт Inter, музыка, хронометраж. Он задаёт стиль и не меняется от ролика к ролику. - Данные — один файл
videos/<ролик>.js: тексты, порядок сцен, пути к картинкам, текст диктора. - Кадры — картинки компонента из Figma в
assets/<ролик>/. - Голос — локальная модель с утверждённым описанием голоса и темпом (
references/voice.md).
Исполнитель пишет только данные и кадры. Всё остальное делают скрипты: tools/build.mjs
собирает ролик одной командой, tools/selftest.mjs проверяет, что машина собирает образцы
так же, как эталон.
Чего не делать никогда
- Не править шаблон:
engine/,tools/,assets/fonts/,assets/vendor/, разметкуindex.html. Три строкиindex.html, которые меняются от ролика к ролику, правитbuild.mjs— руками их не трогать. Новый тип сцены или другой визуал — только по прямой просьбе пользователя: это меняет стиль всех роликов (references/engine.md). - Не выдумывать тексты и числа. Подписи сцен, теги, пункты списков, версия, текст диктора — из описания пользователя, его сценария или журнала изменений компонента (блок «История изменений» в Section компонента в Figma). У каждого числа — источник и дата в шапке файла данных. Нет текста или источника — спросить. Ролик уходит команде как факт.
- Не менять
brand(«Astra Design System») иcredit(«разработано дизайн-командой») — проверка их сверяет. - Не подменять крупный кадр PNG-скриншотом. Компонент крупным планом — только очищенный
SVG (
references/figma.md): у выгрузки PNG под компонентом остаётся фон страницы. - Не перезаписывать готовый рендер.
build.mjsсам кладёт новую версию рядом:<ролик>-2.mp4.
Требования
| Node.js 22+ | сборка, метки (встроенный WebSocket) | node -v |
Python 3.10+ с numpy, scipy; Pillow для нарезки | музыка, нарезка матрицы | pip install -r template/requirements.txt |
ffmpeg и ffprobe в PATH | рендер, сверка | ffprobe -version |
доступ к npm-пакету hyperframes | рендер; Chrome для него скачивается сам | npx --yes hyperframes@0.8.160 doctor |
| Figma MCP (официальный сервер Figma) с правами редактора на файл | геометрия и кадры | вызов get_metadata |
Для голоса: отдельный Python с моделью Qwen3-TTS (видеокарта NVIDIA) или Silero; faster-whisper для проверки | озвучка, проверка разборчивости | references/voice.md, раздел «Установка» |
Без Figma MCP ролик собирается из выгрузок, которые пришлёт пользователь, — их обработка
та же (references/figma.md). Без модели голоса собирается ролик, чьи фразы уже озвучены.
Какой ролик просят
| Доработка компонента: «сделай видео по доработке <компонент>» | шаги 1–8 |
| Видео-презентация без голоса: токены, переходы | шаги 1, 3, 5–8 |
| Объясняющий ролик с голосом: «расскажи голосом», «с озвучкой», сценарий или колода | references/storyboard.md: источник → раскадровка на согласование → ролик по блокам; затем шаги 5–8 и references/voice.md |
Короткий ролик (до минуты) с готовым текстом голоса можно собрать без раскадровки. Длинный (больше минуты) — только после раскадровки: переозвучить три минуты дороже, чем поправить слайд.
0. Рабочая папка — один раз
- Если в проекте уже есть папка роликов (в ней лежат
engine/astra-video.jsиtools/build.mjs) — работать в ней. - Иначе скопировать
template/скилла целиком вastra-video/в корне проекта или туда, куда скажет пользователь. В папке самого скилла ничего не собирать. - На новой машине первым делом:
node tools/selftest.mjs(около 4 минут). Должно кончиться строкой «Всё совпало с эталоном». Не совпало —references/pitfalls.md, раздел «Самопроверка», до начала работы.
Все команды дальше — из рабочей папки.
1. Что нужно от пользователя
| Ссылки на Figma: компонент и его варианты, матрица, экраны — что показывать | спросить: без кадров ролик не собрать |
| Что изменилось и в какой версии | взять из «Истории изменений» в Section компонента; нет и там — спросить |
Слова пользователя главнее журнала: что он назвал — то и в ролике, журнал нужен для того, чего в просьбе нет. Журнал не сверялся — так и сказать в отчёте.
Ролик о доработке на согласование не выносить: он собирается по одной просьбе. Выбранные сцены
и источник каждого текста называются в отчёте — пользователь поправит по готовому.
Объясняющий ролик с голосом длиннее минуты — наоборот: сначала раскадровка
(references/storyboard.md).
2. Разобрать ссылки Figma
fileKey и nodeId — из ссылки: figma.com/design/<fileKey>/…?node-id=40016871-145809 →
nodeId 40016871:145809.
get_metadata(fileKey, nodeId)на каждую ссылку — типы узлов, размеры, координаты детей. Главный источник геометрии: высоты вариантов, сетка матрицы, позиции экранов. Числа берутся отсюда без пересчёта, а не со скриншота.get_screenshot(fileKey, nodeId)— понять, что на узле. В ролик не идёт.
Пример: матрица 2178×1995, у инстансов x="0" y="53" width="343" height="88",
x="367" y="53" … height="88", x="734" y="53" … height="122" → в данных colX: [0, 367, 734, …],
cellW: 343, строка { y: 53, h: [88, 88, 122, …] }.
3. Выбрать сцены
Сцена выбирается по сути показа, не по вкусу. Полный справочник полей — references/scenes.md.
Ролик о доработке компонента (kind: "Доработка", 2–4 сцены, обычно 25–35 с):
Свойство компонента и его значения: Type Scale = Base ↔ Scale, Size = S ↔ M | variants | SVG на каждое значение |
Шаги множителя шрифта Typo Scale x1 … x1.5 и как от них растёт высота | scaleSteps | SVG на каждый шаг + высоты |
| Вся матрица «вариант × значение» | grid | PNG матрицы 1x и нарезка; при 2×2–3×3 — SVG ячеек |
| Как выглядит в интерфейсе, сравнение экранов | phones | PNG экранов 2x, до трёх |
| Касание, нажатие, отклик на экране | device | PNG экрана 2x + координаты касаний |
| Перечень правок | changes | только тексты |
Порядок — от общего к частному: что появилось (variants) → как работает (scaleSteps,
device) → вся картина (grid) → где видно (phones). Перечень правок changes — первой
сценой, если правок много и они разные, иначе не нужен.
Пользователь назвал сцены — делать ровно их, в его порядке, даже если ролик выйдет короче 25 с. Не назвал — выбрать по таблице, 2–4 сцены.
Видео-презентация (обучающий ролик, 5–9 сцен, 45–60 с; kind — тема, например
«Токены анимации»):
| Тезисы «тег · текст»: зачем, как применять | changes |
| Переход между страницами на телефоне: касание, реальная скорость, повтор в 4 раза медленнее | flow |
| Таблица «токен · примитив · значение» по платформам | tokens |
| Два уровня: примитивы → композитные | tiers |
| Длительности полосами, точки пробегают их за реальное время | durations |
| Кривые анимации на одной длительности | curves |
| Масштаб и непрозрачность | values |
| Дистанции ±100vw / ±100vh | distances |
| Компонентные токены на живом компоненте | composite |
Объясняющий ролик с голосом (процесс, формат, решение; 1–4 минуты; обложка — title):
| Шаги процесса слева направо; «где ломается» — выделить стрелку | chain |
| Весь процесс: общий путь и ветки к платформам | pipeline |
| Два подхода рядом и вывод | versus |
| Фрагмент файла и то же прозой | code |
| Команда и её вывод | terminal |
| «Откуда → куда»: поле → место в коде | mapping |
| Крупные числа | stats |
| Тезисы, роли, правила | changes |
| Итоговая фраза | quote |
Элементы этих сцен встают под голос: beat: k — на k-й фразе сцены.
Ни одна сцена не подходит — сказать пользователю, какой показ нужен, и спросить, заводить ли
новый тип (references/engine.md). Самому движок не менять.
4. Подготовить кадры
Подробно, с командами — references/figma.md. Коротко:
Компонент крупно (variants, scaleSteps, composite) | download_assets(…, defaultFormat: "svg"), скачать export, python -I tools/clean_figma_svg.py <сырой.svg> assets/<ролик>/svg/<имя>.svg |
Матрица (grid) | download_assets(…, "png", scale 1) и нарезка по координатам из get_metadata |
Экран (phones, device, flow) | download_assets(…, "png", scale 2) → 750×1624 |
Раскладка папки: assets/<ролик>/_raw/ — сырые выгрузки, svg/, grid/, screens/ — готовое.
Имя ролика — <компонент>-<суть> латиницей через дефис, например toolbar-af-scale.
Имена образцов (current-product-af-scale, toolbar-af-scale, flow-motion, motion-tokens,
design-contract-short, design-contract-v3) заняты: их файлы сверяет самопроверка,
перезаписывать нельзя. Совпало — добавить версию: current-product-af-scale-v3.
После чистки размер SVG обязан совпасть с размером узла из get_metadata — скрипт его печатает,
build.mjs сверяет ещё раз.
5. Написать данные
Скопировать ближайший образец из videos/ в videos/<ролик>.js и заменить содержимое:
current-product-af-scale.js | доработка: variants → scaleSteps → grid из PNG 11×6 → phones |
toolbar-af-scale.js | доработка: то же, grid 2×2 из SVG (clip: false), линейка height |
flow-motion.js | презентация: changes, шесть flow, tokens |
motion-tokens.js | презентация: changes, tiers, durations, curves, values, distances, composite |
design-contract-short.js | голос Qwen3: обложка title, chain с выделенной стрелкой, итог quote; фразы уже озвучены, собирается без модели |
design-contract-v3.js | объясняющий ролик целиком, 13 кадров, 3 мин 17 с: все сцены с голосом и beat; голосовых файлов в пакете нет — собрать можно только с моделью |
В шапке файла — комментарий с источниками: файл Figma и id узлов, сценарий, раскадровка, откуда каждое число.
brand, credit | не трогать |
kind | «Доработка» для ролика о доработке; тема — для презентации |
component | имя компонента дословно из Figma; у презентации — тема латиницей, как в Figma |
version | v 3.0.0 из журнала изменений; у презентации — короткая подпись («React · Flutter») |
title, titleSize, header | у объясняющего ролика: заголовок обложки одной строкой, его кегль, подпись шапки |
narrator, voice, outroVoice | голос: движок и описание голоса, фраза на обложке, на финале — references/voice.md |
fog | не ставить: туман — визуал прежней версии |
slides | сцены по порядку, у каждой type, caption; с голосом — voice (фразы) и beat у элементов |
Тексты на экране и в голосе пишутся инфостилем — references/infostyle.md: главное
в начале, одна мысль — одна фраза, глагол вместо отглагольного существительного, факт и число
вместо оценки, без командного жаргона для широкого зрителя. Неразрывные пробелы в кадре ставит
движок (nb()), в данных их писать не нужно. Голос — правила references/voice.md, раздел
«Как писать текст для голоса».
caption— до 40 знаков, без точки в конце, с заглавной буквы: «Новое свойство Type Scale»;- имена свойств, значений и токенов — дословно из панели свойств Figma, латиницей как есть:
Type Scale,Base,motion-page-duration; - множители Typo Scale — латинская
xи точка:x1,x1.1…x1.5, даже если в подписях на холсте Figma «х1,1» с русской «х» и запятой; - кавычки «ёлочки», тире —, числа с пробелом перед единицей: «300 мс»;
- стрелку
→не писать: её нет в шрифте Inter, она возьмётся из системного шрифта и на другой машине будет выглядеть иначе.
Числовые поля (display, top, fit, push) — значения по умолчанию и формулы из
references/scenes.md, менять только если снимок на шаге 6 показал проблему. Числа в образцах
подогнаны под их кадры (у variants образца top 490, а не 470) — в новый ролик их не переносить.
6. Собрать без рендера и посмотреть
node tools/build.mjs <ролик> --no-render
Около 20 секунд, ролик с голосом на три минуты — около минуты плюс озвучка изменённых фраз. Скрипт:
- проверяет данные: поля сцен, тексты,
brandиcredit, что все картинки на месте и размеры SVG совпадают с данными; у голоса — фразы под выбранную модель и номераbeat; - переключает
index.htmlна ролик и ставит длительность; - с голосом — озвучивает только изменённые фразы (
ASTRA_TTS_PYTHON,references/voice.md); - снимает метки событий и синтезирует музыку под них; с голосом — сводит голос с музыкой;
- прогоняет
hyperframes lint; - делает снимки в
renders/<ролик>.snapshots/: обложка, по два кадра на сцену — в начале, когда сцена въехала, и в конце, когда всё показано, — и финал.
С голосом — ещё проверка разборчивости: <python с faster-whisper> -I -X utf8 tools/voice_check.py <ролик>.
Фразы с ✗ прослушать; слово пропало или слилось — перестроить фразу и собрать снова.
Ошибка — строка «Стоп: …» с причиной; исправить данные и запустить снова.
Открыть renders/<ролик>.snapshots/contact-sheet.jpg и каждый кадр. Проверить:
- компонент целиком, без серой подложки и обрезанных углов;
- подписи не обрезаны и не налезают на шапку (имя компонента, счётчик) и подвал (подпись сцены, «Astra Design System»);
- матрица целиком в кадре, подписи колонок читаются;
- тексты — те, что дал пользователь, без опечаток;
- с голосом — на экране то же, что звучит, и элементы встают на своих фразах.
Нашлось — поправить данные (top, display, fit, push, headSize) и собрать снова.
Нужен другой момент — снимок вручную:
HYPERFRAMES_SKIP_SKILLS=1 npx --yes hyperframes@0.8.160 snapshot --at <секунды> --output renders/<ролик>.extra
(в PowerShell переменную задать отдельно: $env:HYPERFRAMES_SKIP_SKILLS = "1").
7. Отрендерить
node tools/build.mjs <ролик>
Повторяет шаг 6 и рендерит renders/<ролик>.mp4 в качестве delivery. Ролик на 30 с —
около минуты, на три минуты — около 10 минут; запускать в фоне, если среда позволяет. В конце строка «Готово: …» с длиной,
размером кадра, звуком и весом файла; расхождение — «Стоп: …».
8. Отчитаться
- путь к MP4, длина, вес;
- сцены по порядку с подписями;
- откуда каждый текст: описание пользователя или журнал изменений (с id узла); у каждого числа — источник, числа без источника — отдельным списком;
- с голосом — модель и её лицензия (Qwen3-TTS — Apache 2.0, Silero — CC BY-NC 4.0, только
внутренние ролики), итог проверки
voice_check.py; - что решено без пользователя и что не проверено.
Ничего не коммитить и не публиковать без отдельной просьбы.
Справочники
references/scenes.md | на шаге 5 — поля и значения по умолчанию всех сцен, длительности |
references/storyboard.md | объясняющий ролик: источник, раскадровка на согласование, ролик по блокам |
references/voice.md | голос: движки, установка, описание голоса, темп, beat и hold, проверка, лицензии |
references/infostyle.md | перед любым текстом на экране и в голосе |
references/figma.md | на шаге 4 — выгрузка, чистка SVG, нарезка, запасные пути без MCP |
references/pitfalls.md | когда что-то пошло не так; Windows, PowerShell, кодировки |
references/engine.md | только по просьбе пользователя: новый тип сцены, смена визуала |