Голосовые системы

Проверка трёх версий Silero

Дополнение: ускоренные 20-секундные демо Fish Audio

После замечания о медленном темпе женский вариант пересобран с atempo=1.14 вместо 1.06, мужской — с 1.04 вместо 0.92. Исходные MP3 не менялись и новые API-запросы не выполнялись. Первоначальные MP4 сохранены в voice-variants/fish-audio-20s/original-tempo/.

build_demo.py заново вычислил WAV, четыре интервала субтитров и начало финальной заставки отдельно для каждого голоса: последний subtitle заканчивается на кадре 552/529, заставка начинается с кадра 558/535 (женский/мужской). Сгенерированы новые silent render и итоговые MP4. pnpm exec tsc --noEmit прошёл. ffprobe подтвердил у обоих H.264 1920×1080, 30 fps, AAC mono 48 кГц и ровно 20,000 с для видео, аудио и контейнера; оба файла полностью декодируются ffmpeg без ошибок.

Средний/максимальный уровень по volumedetect: женский −16,9/−1,1 dB, мужской −16,5/−1,5 dB. После последней реплики есть 1,7/2,6 с тишины под финальную заставку. Из конечных MP4 просмотрены кадры 120, 285, 480, 558, 582 каждого голоса; мужской кадр на 16-й секунде также просмотрен в полном разрешении. Файлы — в voice-variants/fish-audio-20s/qc-faster/. Обрезки значимого текста на них нет. Непрерывное человеческое прослушивание и независимая ASR-сверка в этой пересборке не проводились.

Дата: 2026-09-17. Все три MP4 созданы на одном содержании и модели Silero v5_5_ru.pt с разными голосами. Каждый вариант получил собственный измеренный WAV, таймлайн, SRT и полный рендер кадров.

Голос Длительность Кадры Размер MP4 Громкость после AAC True peak
Xenia 188.133 с 5644 26 825 544 байта −16.2 LUFS −1.4 dBFS
Aidar 224.433 с 6733 29 641 023 байта −16.6 LUFS −1.3 dBFS
Eugene 174.300 с 5229 25 548 683 байта −17.6 LUFS −1.3 dBFS

SHA-256: Xenia c71a46ddeb237eb15e823380a609f664bd06c13faa2ed990abf1dfcbe8ef7d50; Aidar 283f891711d02339da201b1bb4799e8342408b09d7b4134e433587c0fce293f3; Eugene 88f8081df5f3654f81308bc60042ddd202c229ae9f0dd7c806e1972c01dd001c. Модель у всех одна: 50081637b602126ee06cb3bc8a744d25651d2da149ee8864b9a379bfdd934437.

Для каждого MP4: 1920×1080, H.264, 30 fps; AAC mono 48 кГц. scripts/final_qc.py подтвердил отсутствие разрывов/пересечений сцен, точное совпадение master WAV с числом кадров, 50 блоков субтитров внутри сцен (не более двух строк), длительность аудиодорожки в пределах 0.05 с от видео и полное декодирование ffmpeg без ошибок. Численные результаты сохранены в voice-variants/<голос>/qc-result.json.

Из закодированного MP4 каждого голоса извлечены и просмотрены по контактным листам 57 кадров: ранний, средний и поздний кадр каждой из 19 сцен. На этих контрольных кадрах значимый текст не обрезан и не перекрывает субтитры. Файлы лежат в voice-variants/<голос>/qc/; основной output/final-qc/ относится к Xenia. Проверочный скрипт теперь принимает явный --timeline и отвергает несовпадение числа кадров MP4/таймлайна; этот отказ отдельно проверен.

Xenia — основной путь output/webrtc-komaroff-explainer.mp4, побайтно совпадает с output/webrtc-komaroff-explainer-xenia.mp4. Первые ~30 секунд каждого варианта сохранены рядом с его исходниками для быстрого сравнения. Предыдущий Piper MP4 и контрольные кадры перенесены в voice-variants/piper-original/ без потери исходной версии.

По длительности блоков Eugene — самый быстрый: максимум 20.6 символа/с, два блока выше 20; Xenia — максимум 18.8, Aidar — 15.8. Это вычисление по тексту и таймлайну, не субъективная оценка дикции. Непрерывное человеческое прослушивание всех трёх роликов не заявляется; окончательный выбор голоса лучше сделать после просмотра фрагментов. Xenia оставлена основной версией по умолчанию.

Skill anything2explainer-codex: quick_validate, scaffold smoke test, cw sync, cw validate, cw doctor — PASS. Source и установленный runtime skill побайтно совпадают по изменённым файлам. Код и runtime сервиса webrtc-komaroff не менялись; commit, push и публикация не выполнялись.

Архивная проверка предыдущей версии Piper

Дата: 2026-09-17. Результат: экспорт проверен технически; визуально просмотрены контрольные кадры всех 19 сцен. Проверка поведения работающего webrtc-komaroff не выполнялась.

Файл

voice-variants/piper-original/webrtc-komaroff-explainer.mp4

  • 1920×1080, H.264, yuv420p, 30 fps.
  • 5989 кадров, 199.633333 секунды видео.
  • AAC mono, 48000 Гц; длительность аудио 199.633000 секунды.
  • 26 685 512 байт, MP4 faststart.
  • SHA-256: 43346d30067b5b648b38e408762c170aa479e76b3bd50e83dd9b799e9c43f341.

Что проверено

Проверка Результат
TypeScript tsc --noEmit PASS
Python helpers compile / timing assertions PASS
Scaffold в новом каталоге PASS
Scaffold поверх существующего каталога Ожидаемый отказ, без перезаписи
Skill quick_validate PASS
cw sync / validate / doctor PASS; существующий dirty shared сохранён
Source skill и runtime SKILL.md / audio helper SHA совпадают
Timeline сцен Без разрывов и пересечений, сумма 5989 кадров
50 subtitle blocks В пределах своих сцен; максимум 2 строки по метрикам используемого шрифта
Master WAV Длительность точно равна timeline
ffprobe финального MP4 Размеры, кодеки, fps, число кадров и длительности соответствуют
Полное ffmpeg decode PASS, ошибок нет
Громкость закодированной дорожки −16.59 LUFS; true peak −1.35 dBTP; LRA 3.00 LU

Нормализация целилась примерно в −16 LUFS / −1.5 dBTP; значения выше измерены после AAC-кодирования, а не заявлены равными настройкам фильтра.

Визуальная проверка

До экспорта сгенерированы 57 кадров — ранний, средний и поздний для каждой сцены. Просмотрены монтажные листы со всеми 19 средними кадрами. Обнаружены и исправлены:

  1. Волна микрофона пересекалась с подписью: подпись и waveform разнесены.
  2. Условные графики пересекались с названиями метрик: заголовки перенесены выше.
  3. В сцене начальной загрузки карты порядок HTTP-запросов не совпадал с кодом: исправлено на аэропорты → позиция.

Собран 30-секундный pilot с голосом. После полной сборки извлечены кадры всех 19 сцен из конечного MP4, повторно просмотрены четыре монтажных листа в voice-variants/piper-original/final-qc/. У исправленных сцен проверены и отдельные кадры 1080p. В этих кадрах обрезки и пересечения значимого текста не обнаружены.

Полный render уже шёл во время последней содержательной правки. Поэтому сцена 13 была пересобрана отдельно и заменена через frame-exact trim/concat:

node scripts/codex_render.mjs scene-13
python3 scripts/mux.py --replace-scene 13
.venv/bin/python scripts/final_qc.py
.venv/bin/python scripts/encoded_samples.py

Сцена содержит 344 кадра. Финальный счётчик остался 5989. Исходный Film.tsx уже включает исправление: при новой полной сборке отдельная замена не требуется.

Границы проверки

Это визуальная проверка контрольных кадров, численная проверка тайминга и техническая проверка аудио/видео. Непрерывное человеческое прослушивание и оценка произношения не заявляются. Голос синтетический, локальный Piper Denis. Свойства production, фактические p95, масштабирование и качество распознавания этим роликом не подтверждаются.

Код сервисов не менялся. Коммиты, push, публикация и deployment не выполнялись. Upstream notices и условия toolkit сохранены.

Исходник

Скачать Markdown · К материалам исследования