Вы получаете запись вебинара длительностью 2 часа, а STT-модель выдаёт 40% WER — текст невозможно использовать для субтитров или аналитики. Чаще всего проблема не в модели, а в исходном аудио: Zoom/Teams сжимают битрейт до 32 кбит/с, добавляют шум от кодеков, а спикеры говорят одновременно. Типичный сценарий — многодорожечная запись конференции, где каждый участник на отдельной дорожке, но без правильного извлечения и нормализации получить чистый текст нереально.
Мы решаем это на этапе извлечения дорожки, используя FFmpeg с фильтрами нормализации и подавления шума. После этого даже Whisper large-v3 показывает WER ~3% на чистых записях (OpenAI Whisper), а на зашумлённых — до 20%, если не обработать аудио. Фильтрация FFmpeg улучшает WER в 3–5 раз по сравнению с сырым аудио. Ниже — полный pipeline: от извлечения аудио до генерации субтитров с таймкодами.
STT из видео: как извлечь аудио для распознавания речи?
Ключевой инструмент — FFmpeg с правильным набором фильтров. Мы используем loudnorm для нормализации громкости и опционально highpass=f=200 для подавления низкочастотного гула. Пример извлечения в 16 кГц моно:
import subprocess
import tempfile
from pathlib import Path
from faster_whisper import WhisperModel
def extract_audio_from_video(video_path: str) -> str:
"""Извлекаем аудио из видео через FFmpeg"""
output_path = tempfile.mktemp(suffix='.wav')
cmd = [
'ffmpeg', '-i', video_path,
'-vn', # отключаем видео
'-ar', '16000', # 16kHz для ASR
'-ac', '1', # моно
'-acodec', 'pcm_s16le', # PCM 16-bit
'-af', 'loudnorm', # нормализация громкости
output_path,
'-y', '-loglevel', 'error'
]
subprocess.run(cmd, check=True)
return output_path
def transcribe_video(video_path: str, model: WhisperModel) -> dict:
audio_path = extract_audio_from_video(video_path)
try:
segments, info = model.transcribe(
audio_path,
vad_filter=True,
word_timestamps=True,
language="ru"
)
return {
"language": info.language,
"segments": [
{
"start": seg.start,
"end": seg.end,
"text": seg.text
}
for seg in segments
]
}
finally:
Path(audio_path).unlink(missing_ok=True)
Почему качество аудиодорожки важнее модели?
Даже самая точная модель Whisper large-v3, показывающая WER ~3% на чистых записях, падает до 20% WER на зашумлённом аудио. Сравните:
| Тип записи | WER без предобработки | WER после фильтров FFmpeg |
|---|---|---|
| Вебинар Zoom (32 кбит/с) | 15% | 5% |
| Уличная съёмка (камера GoPro) | 35% | 12% |
| Конференция Teams (несколько дорожек) | 25% | 8% |
Поэтому мы всегда начинаем с анализа спектрограммы аудио — это позволяет подобрать фильтры под конкретный источник.
Пример анализа спектрограммы
Мы используем `specread` из FFmpeg для визуализации частотного состава. На основе этого выбираем фильтры: `highpass`, `lowpass`, `afftdn`.Как обрабатывать многодорожечные записи?
В видеоконференциях каждый участник может быть на отдельной аудиодорожке. Мы извлекаем каждую дорожку отдельно, транскрибируем их параллельно, а затем с помощью PyAnnote выполняем диаризацию для разделения спикеров. Это значительно улучшает читаемость субтитров при нескольких голосах.
# Получаем информацию о дорожках
probe = ffmpeg.probe(video_path)
audio_streams = [s for s in probe['streams'] if s['codec_type'] == 'audio']
# Обрабатываем каждую дорожку отдельно для диаризации
Что даёт коммерческая реализация STT?
Внедрение такого пайплайна сокращает время на расшифровку в десятки раз: вместо ручного набора субтитров к вебинару длительностью 1 час вы получаете готовый файл через 10 минут. Экономия человеко-часов на каждом видео — от 2 до 8 часов в зависимости от формата. Для контент-студий и образовательных платформ это снижение операционных затрат на 80%. Экономия на фрилансерских услугах — до 40 000 рублей в месяц при объёме от 20 видео.
Как быстро окупается внедрение?
На объёме от 20 видео в месяц интеграция окупается за 2–3 месяца. Вы перестаёте платить фрилансерам за транскрибацию и получаете готовые временные метки для монтажа. Мы предоставляем Docker-образ, который вы запускаете на своём сервере — никаких ежемесячных платежей за API.
Генерация субтитров
Из результата транскрибации автоматически генерируем SRT/VTT:
def to_srt(segments) -> str:
lines = []
for i, seg in enumerate(segments, 1):
start = format_timestamp(seg['start'])
end = format_timestamp(seg['end'])
lines.append(f"{i}\n{start} --> {end}\n{seg['text'].strip()}\n")
return "\n".join(lines)
Типичные ошибки при внедрении STT
- Игнорирование шума: без фильтров WER растет на 15–20%.
- Выбор неподходящей модели: для русского языка Whisper large-v3 показывает лучшие результаты.
- Отсутствие таймкодов: без
word_timestampsсубтитры не синхронизированы. - Плохая настройка VAD: пропускает части речи или вырезает паузы.
Что входит в реализацию?
| Компонент | Результат |
|---|---|
| Извлечение аудио | Скрипт на Python/FFmpeg с настройкой фильтров под ваш тип записей |
| Транскрибация | Интеграция Whisper (faster-whisper) с VAD, word_timestamps |
| Диаризация (опционально) | Разделение по дорожкам или с помощью PyAnnote |
| Субтитры | Экспорт в SRT/VTT/ASS, кастомизация стилей |
| Интеграция | Docker-образ, HTTP API, CLI-утилита, примеры для CI/CD |
| Документация | README, примеры использования, видеоинструкция |
Процесс работы
- Аналитика — вы присылаете 2–3 типовых видео, мы оцениваем качество и подбираем пайплайн.
- Проектирование — фиксируем архитектуру: стек (Whisper, NVIDIA NeMo), векторная база (опционально), формат субтитров.
- Реализация — пишем код с модульными тестами.
- Тестирование — прогон на ваших данных, замер WER, настройка порогов VAD.
- Деплой — передаём Docker-образ, доступ к Git-репозиторию, CI/CD-пайплайн.
Сроки и стоимость — stt из видео
- Базовый скрипт для одного типа видео — 1–2 дня.
- Batch-система с очередью и мониторингом — 3–5 дней.
- Стоимость рассчитывается индивидуально, зависит от сложности предобработки и необходимости диаризации.
Опыт нашей команды — 10+ лет в STT, 50+ внедрений для видеоаналитики и субтитрирования. Закажите интеграцию STT у нас — получите бесплатную консультацию и тестовую обработку ваших видео. Свяжитесь для оценки вашего проекта — пришлём демо-версию на ваших файлах.







