Как я собрал бота, который превращает доклады в вертикальные ролики: Whisper, поиск хайлайтов через LLM и проход ffmpeg

от автора

Расскажу, как устроен пайплайн автонарезки выступлений с конференций (со спикером, субтитрами и его слайдами): где помогает LLM, почему субтитры рисуются через drawtext, а не .ass, и как собрать композицию «спикер + субтитры + слайд» одним проходом ffmpeg. С конкретным решением и граблями, на которые я сам наступил

Задача

Дано: запись доклада 40+ минут (спикер + презентация). И нужно из нее родить 5-6 самодостаточных вертикальных клипов с точными субтитрами и слайдами из презентации доклада.

Ограничения: работает на обычном CPU-сервере, себестоимость прогона — копейки.

Шаг 1. Речь в текст

Whisper (medium) даёт слова с таймкодами. На CPU узкое место – скорость, поэтому распознавание распараллелено по ядрам. Сегменты Whisper я склеиваю обратно в предложения — это критично для следующего шага: нарезать по словам нельзя, иначе мысль в видео будет рваться.

Шаг 2. Поиск хайлайтов через LLM

Самая нетривиальная часть. Наивный промпт формата «найди вирусные моменты» даёт мусор: модель стартует фрагмент с середины фразы или со связки «Но…».

Что помогло с этим справиться:

  • запрашивать диапазон по предложениям [from, to], а не по секундам;

  • жёсткий промпт с критериями (история / факт / мнение / юмор) и запретом стартовать со связок;

  • доснэппинг границ к реальным границам предложений уже после ответа модели;

  • ретраи на кривой JSON и 503 — модель периодически флапает, а второй запрос помогает добить.

Шаг 3. Слайды

Какой слайд показать в момент t — определяется по кадру через vision-модель (detail=high, иначе текст слайда не читается). Раньше пробовал image-hash — но, по итогу, отказался от этого, поскольку vision работает точнее.

Шаг 4. Композиция одним проходом ffmpeg

Для хорошего видео мне нужно четкое деление на три зоны: спикер, субтитры и слайды — и чтобы все это собиралось воедино за один проход.

По пути к решению наступил на несколько граблей:

  • субтитры — через drawtext, а не .ass. Контроль над переносом строк (по ширине карточки слайда), кеглем и таймингом получился чище;

  • наложение чанков субтитров. Лечится enable через полуинтервал [a, b) (gte + lt) вместо between — иначе на стыке два чанка рисуются одновременно;

  • динамическая раскладка. Когда спикера не видно (общий план, перебивки и тд), карточка спикера уезжает за кадр, слайд переезжает в центр — через плавную функцию P(t) и кросс-фейд субтитров, чтобы текст не наезжал на слайд.

Шаг 5. Центровка на спикере

В полноэкранном режиме активный спикер всегда должен быть по центру: с этим мне помог трекинг лиц + поиск того, у кого больше движения губ в окне ~1.2с (иначе при появлении мемов или картинок с людьми на слайдах бот путается), а также сегментация по склейкам монтажа.

Экономика

Себестоимость прогона – 15–25 ₽ (LLM), STT на своём сервере бесплатно. Это и сделало возможным отдавать первую нарезку бесплатно.

Итог

Получился Telegram-бот, куда можно просто закинуть файл или ссылку (YouTube/Drive/Яндекс) — а забрать готовые вертикалки.

Если интересно пощупать пайплайн на своём докладе — https://t.me/reels_akimov_bot. Буду рад фидбеку по качеству выбора хайлайтов, это самое сложное место.

ссылка на оригинал статьи https://habr.com/ru/articles/1049918/