# webrtc-komaroff: от голоса к действию

Основная серия — три версии одного объясняющего ролика: 1080p, 30 кадров/с, встроенные субтитры, 19 анимированных сцен. В этих трёх версиях нет музыки и записей голоса человека; голос — локальная Silero v5.5 RU:

| Голос | Длительность по таймлайну | Полное видео | Первые 30 секунд |
|---|---:|---|---|
| Xenia | 3:08.133 | [MP4](#archive-availability) | [Фрагмент](#archive-availability) |
| Aidar | 3:44.433 | [MP4](#archive-availability) | [Фрагмент](#archive-availability) |
| Eugene | 2:54.300 | [MP4](#archive-availability) | [Фрагмент](#archive-availability) |

[Основной MP4](#archive-availability) совпадает с вариантом Xenia. Предыдущая версия Piper сохранена в [архиве](#archive-availability) для сравнения, но не входит в три новых варианта.

Отдельно подготовлены [два 20-секундных демо с Fish Audio](</experiments/voice-ai/archive/c/videos/webrtc-explainer-2026-09-17/voice-variants/fish-audio-20s/README.md>): один и тот же фрагмент с женским и мужским русскоязычными голосами через бесплатную API-модель `s2.1-pro-free`.

После подтверждения пользователем прав на использование записи и голоса создана [новая полная версия с синтетической имитацией голоса Владимира Путина](</experiments/voice-ai/archive/c/videos/webrtc-explainer-2026-09-17/voice-variants/fish-pupkin/README.md>): [MP4, 3:44.900](#archive-availability). Её образец и текст передавались Fish Audio; постоянная пометка в кадре поясняет, что это не реальное выступление и не поддержка проекта. У версии собственные таймлайн, SRT и отчёт проверки.

- [Текст диктора](</experiments/voice-ai/archive/c/videos/webrtc-explainer-2026-09-17/narration.md>), [SRT](</experiments/voice-ai/archive/c/videos/webrtc-explainer-2026-09-17/subtitles.srt>), [план сцен](</experiments/voice-ai/archive/c/videos/webrtc-explainer-2026-09-17/story.json>).
- [Точные интервалы и параметры голоса](</experiments/voice-ai/archive/c/videos/webrtc-explainer-2026-09-17/src/film-timeline.json>).
- [Установка, размер зависимостей и требования](</experiments/voice-ai/archive/c/videos/webrtc-explainer-2026-09-17/VOICE_SETUP.md>); исходные WAV, SRT и таймлайны каждой версии лежат в `voice-variants/<голос>/`.
- [Анимация](#archive-availability), [контроль качества](</experiments/voice-ai/archive/c/videos/webrtc-explainer-2026-09-17/QC.md>).
- [Архитектурный разбор](</experiments/voice-ai/archive/c/DOCS/architecture-2026-09-16/README.md>), [реестр доказательств](</experiments/voice-ai/archive/c/DOCS/architecture-2026-09-16/evidence.md>).
- [Предложения изменений](</experiments/voice-ai/archive/c/DOCS/architecture-2026-09-16/improvements/README.md>).

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

## О чём ролик

Реплика «Покажи ближайшие аэропорты» связывает объяснение в одну историю: WebRTC → Core → NATS → Whisper bridge → LinTO → Agent → workflow → инструменты → событие браузеру.

Схемы объясняют взаимодействие, но не воспроизводят настоящий экран приложения. Карта и графики условные. Сцены 13–18 помечены «Предложение»: они не показывают уже внедрённую архитектуру.

Основной снимок: [webrtc-komaroff, 772de4a](<https://git.giscloud.ru/voice-chat/webrtc-komaroff/-/tree/772de4a714ae6c5abea91946e85a1953ee919ec3>), 16.09.2026. ASR bridge проверен по [py_faster_whisper, 21c85b0](<https://git.giscloud.ru/voice-chat/pyfasterwhisper/-/tree/21c85b0c7bc7a96497ce78ec2ead44b113f18db6>). Текущее состояние кластера не проверялось. Наличие трёх движков в исходниках не означает, что все три используются в production.

## Источники сцен

| Сцены | Основание | Граница |
|---|---|---|
| 01–04 | handle_track.py, whisper_stream_node.py, handle_transcription.py | 20 мс — параметр аудиокадра, не задержка ответа |
| 05 | py_faster_whisper/src/stt_whisper_to_nats.py | VAD + внешний LinTO; не локальный Whisper inference |
| 06–08 | src_agent/agent.py, runtime/engine.rb | Восстановление диалога из БД; не доказательство crash recovery каждого внешнего шага |
| 09 | find_nearest_airport_spec.rb: routing_decision + tool_params | Два LLM-вызова для нового запроса в Ruby node сценарии; не для любого turn |
| 10–12 | src_api_gateway/main.py, src_agent/service.py | Демо-позиция, погода и рейсы; отдельные HTTP-ответ и UI-event |
| 13 | handle_init_map.py | В коде сначала airports/list, затем pilot/location. Параллелизм допустим после решения требований к согласованности snapshot |
| 14 | src_llm/utils/base_service.py: create_task до semaphore | Риск роста ожидающих задач; overload benchmark не выполнялся |
| 15 | runtime_state.py, utils/db.py, src_agent/agent.py | Отдельные записи; повторное выполнение при сбое — вывод, не воспроизведённый инцидент |
| 16 | stack/webrtc.drs + три src_langgraph* | Выбор одного движка требует проверки паритета и потребителей |
| 17 | src_agent/agent.py и вызов workflow | Объединение — вариант, не готовое решение; экономия latency не измерена |
| 18–19 | Реестр доказательств и восемь отдельных предложений | Нет выдуманного baseline, процентов ускорения и утверждений о production |

Точные файлы каждой сцены указаны в story.json. На схемах часть вспомогательных хопов опущена ради объяснения ответственности, а не протокольной спецификации.

## Воспроизведение

Node и pnpm, Python 3.12, ffmpeg/ffprobe, Chrome. В этой сборке: Remotion 4.0.507, React 19.2.8, TypeScript 5.9.3, CPU PyTorch 2.8.0 и NumPy 2.5.3. JS-зависимости зафиксированы `pnpm-lock.yaml`; детали Python-установки и веса — в [VOICE_SETUP.md](</experiments/voice-ai/archive/c/videos/webrtc-explainer-2026-09-17/VOICE_SETUP.md>).

```bash
pnpm install --ignore-scripts
python3.12 -m venv .venv
.venv/bin/pip install numpy==2.5.3
.venv/bin/pip install torch==2.8.0 --index-url https://download.pytorch.org/whl/cpu
# Загрузить и проверить официальный v5_5_ru.pt (URL и SHA в VOICE_SETUP.md).
.venv/bin/python scripts/codex_audio.py --project . --model /absolute/v5_5_ru.pt --speaker xenia --threads 4
env -u NODE_OPTIONS pnpm exec tsc --noEmit
env -u NODE_OPTIONS node scripts/codex_render.mjs stills
env -u NODE_OPTIONS node scripts/codex_render.mjs pilot
env -u NODE_OPTIONS node scripts/codex_render.mjs full
python3 scripts/mux.py
# Повторить синтез + render + mux отдельно для aidar и eugene.
```

Готовый master WAV включён: для повторного render без изменения текста модель не нужна. Укажи `REMOTION_BROWSER_EXECUTABLE`, если Chrome расположен не в `/usr/bin/google-chrome`. На машине сборки `NODE_OPTIONS` снимался только для дочернего процесса Node, глобальная конфигурация не менялась.

Аудио сначала измеряется, затем округляется до кадров; при 48000 Гц и 30 fps это ровно 1600 отсчётов на кадр. SRT и картинки используют один timeline. Нормализация громкости выполнена при mux; исходная озвучка остаётся отдельно.

## Toolkit, голос и авторство

Required Notice: Copyright (c) 2026 Vincent Wei (https://github.com/Vincentwei1021/anything2explainer)

Использован [anything2explainer](<https://github.com/Vincentwei1021/anything2explainer/tree/5b57239578284385c72ebfb2d1fce3ab61a3950a>): шаблон проекта, структура производства, DotFieldBg и библиотека компонентов. Сценарий, русская типографика, предметные схемы, локальная озвучка и Codex helpers добавлены отдельно. Условия toolkit сохранены в [LICENSE.anything2explainer](#archive-availability); исходный автор указывает, что готовые видео принадлежат их создателям.

Шрифты исходного шаблона имеют отдельный OFL notice. В ролике используется DejaVu Sans: [условия](</experiments/voice-ai/archive/c/videos/webrtc-explainer-2026-09-17/public/fonts/DejaVu-LICENSE.txt>). [Remotion имеет собственные условия](<https://www.remotion.dev/license>).

Основные полные версии озвучены локально: Silero `v5_5_ru.pt`, голоса Xenia, Aidar и Eugene. [Модель и список голосов](<https://github.com/snakers4/silero-models/blob/master/README.md>), [лицензия CC BY-NC-SA 4.0](<https://github.com/snakers4/silero-models/blob/master/LICENSE>). Исключение MIT для CIS base не распространяется на `v5_5_ru`. SHA модели записан в каждом `film-timeline.json`. Для отдельного [20-секундного демо Fish Audio](</experiments/voice-ai/archive/c/videos/webrtc-explainer-2026-09-17/voice-variants/fish-audio-20s/README.md>) текст четырёх фраз передавался облачному TTS; в [новой полной версии Fish](</experiments/voice-ai/archive/c/videos/webrtc-explainer-2026-09-17/voice-variants/fish-pupkin/README.md>) передавались текст и разрешённый пользователем голосовой образец. Это не относится к локальным версиям. Старая [карточка Piper](</experiments/voice-ai/archive/c/videos/webrtc-explainer-2026-09-17/voice-variants/piper-original/VOICE_MODEL_CARD.txt>) относится только к архивной версии.

API сборки проверен по Context7 (/remotion-dev/remotion) и установленным type declarations: bundle, selectComposition, openBrowser, renderStill, renderMedia. См. [официальный server-side rendering](<https://www.remotion.dev/docs/ssr>).
