4 мин чтения#build-log#ии#whisper#ffmpeg#семья

Записал концерт дочки — за выходные получился пайплайн

В пятницу младшая дочка впервые играла на сцене. Всероссийский фестиваль-конкурс «Гуслей перезвон чудесный», ЧДМШ №1 в Чебоксарах. 33 выступления, три часа.

Снимал с iPhone на Insta360, как родитель — не как продюсер. На выходе — 3 часа 5 минут одного непрерывного файла. 8,8 гигабайта.

В субботу утром я смотрел на этот файл и думал: десятки семей не получат свой кусок, если я не сделаю.

Решил собрать пайплайн — нарезать запись на индивидуальные портфолио каждого выступающего, с брендированной шапкой школы.

К субботнему вечеру 33 файла были на Google Drive, готовые к раздаче. Между этими точками — 30 часов и довольно много граблей.

Что должно было быть просто

Идея простая: ИИ слушает аудио, находит объявления ведущей, между ними = выступление, ffmpeg режет.

Реальность простая: ничего не работает с первого раза.

→ Gemini 3.1 Pro слушает 3 часа аудио плюс 5 страниц программы. Возвращает тайминги. На слот моей дочки он промахнулся на 15 минут — увидел в 1:49, а на самом деле в 1:26. Не сработало.

→ Groq Whisper API — обрезал по тарифу. Бесплатно дают 7200 секунд аудио в час. У меня 11 084 секунды. Не сработало.

→ OpenRouter Whisper — 500 на их стороне. Не сработало.

→ Локальный Whisper.cpp без VAD — транскрибировал «Субтитры создавал DimaTorzok» 370 раз подряд на всю запись. Whisper галлюцинирует на музыке, когда нет явной речи. Не сработало.

→ Whisper.cpp с silero VAD — поймал 195 секунд речи из 11 000. Слишком строгий порог. Не сработало.

→ Тот же Whisper.cpp с порогом 0,2 плюс предварительное усиление громкости через ffmpeg — поймал 532 секунды. Заработало.

(на пятой попытке я уже начал получать удовольствие от того, как именно ломается каждый следующий уровень)

Два бага в whisper-cpp, которые отняли пару часов

Первый: при включённом VAD таймстампы в JSON-выводе относительные к концатенированной речи, не к оригинальному времени. То есть Whisper нарезал 11 000 секунд аудио на 532 секунды речи, и таймстампы шли от 0 до 532. У меня все сегменты собрались в один кластер. Полтора часа разбирался, пока не нашёл SRT-выход — там таймстампы оригинальные.

Второй: SRT-писатель whisper-cpp растягивает end time каждого сегмента до start time следующего. Между фразой «Сергей Маков» (две секунды речи) и фразой «Областной колледж» (через четыре минуты музыки) SRT записал один сегмент длительностью четыре минуты. Опять всё в одном кластере.

Починил оценкой реальной длительности из количества слов: русская речь ≈ 2,5 слова в секунду, значит фраза «Сергей Маков» — это 0,8 секунды, а не четыре минуты. Кластеризация по реальным паузам — заработала.

А потом стало интересно

После починок автоматическая нарезка попала по 22 из 33 выступлений. Остальные 11 — ансамбль моей дочки «Янрав», татарский «Хэзинэ», марийский «Чинчывий» — оказались в неправильных кластерах из-за искажений в распознавании имён.

Можно было ещё тюнить алгоритм. Но я понял: ИИ ловит 60-80% случаев, последние 20-40% — это вопрос интерфейса для ручной проверки, не лучшего ИИ.

За два часа собрал локальный веб-редактор на Python + HTML. Слева — транскрипт Whisper по сегментам. В центре — видео плеер. Справа — список нарезок. На каждой строке кнопка «⬅» записывает текущее время плеера в start или end. Кнопка «+ Add from unmatched» добавляет недостающего выступающего из исходного списка программы.

За 25 минут проверил все 33 строки, поправил рассинхроны, добавил пропущенных. Сохранил.

Дальше — ffmpeg нарезал по таймстампам, Python с Pillow собрал брендированные шапки для каждой нарезки, ffmpeg склеил шапка + кусочек + закрывающая шапка.

10 минут — 33 файла в папке final/.

Чего я не ожидал

Этот пайплайн — это не разовый подарок к фестивалю.

Те же скрипты прогоняются на любой следующий концерт этой школы или нашего летнего проекта с ней (Лига Залива — академия для местных школьников, музыкальный трек включён). Школа сама записывает на iPhone — я обрабатываю.

Веб-редактор, который собирал в спешке за два часа — это интерфейс администратора для платформы, которую я как раз собираюсь делать для школ искусств в следующие два месяца.

Один файл на 8,8 гигабайта в субботу утром — к вечеру оказалось, что это был запуск трёх вещей одновременно. Подарок десяткам семей. Переиспользуемый пайплайн. Шаблон для нового продукта.

И ещё дочка теперь имеет первое концертное видео, аккуратно нарезанное и подписанное. С брендом ЛИИ × ЧДМШ №1 в правом нижнем углу.

Дальше — по мере поступления.