Расскажу, как устроен пайплайн автонарезки выступлений с конференций (со спикером, субтитрами и его слайдами): где помогает 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/