Разработка live captions на базе ИИ: от идеи до внедрения

Система live captions реального времени: архитектура, задержка, интеграция Субтитры в реальном времени (live captions) — техническое средство реабилитации по [ГОСТ Р 52872-2019](https://www.w3.org/TR/WCAG21/) и международному стандарту WCAG 2.1 (критерий 1.2.4). Мы разрабатываем системы субтитрир

Направления AI-разработки

Часто задаваемые вопросы

Последние работы

  • image_website-b2b-advance_0.webp
    Разработка сайта компании B2B ADVANCE
    1441
  • image_web-applications_feedme_466_0.webp
    Разработка веб-приложения для компании FEEDME
    1301
  • image_websites_belfingroup_462_0.webp
    Разработка веб-сайта для компании БЕЛФИНГРУПП
    998
  • image_ecommerce_furnoro_435_0.webp
    Разработка интернет магазина для компании FURNORO
    1267
  • image_logo-advance_0.webp
    Разработка логотипа компании B2B Advance
    713
  • image_crm_enviok_479_0.webp
    Разработка веб-приложения для компании Enviok
    1003

Система live captions реального времени: архитектура, задержка, интеграция

Субтитры в реальном времени (live captions) — техническое средство реабилитации по ГОСТ Р 52872-2019 и международному стандарту WCAG 2.1 (критерий 1.2.4). Мы разрабатываем системы субтитрирования, которые работают с задержкой менее 2 секунд. Это критично для трансляций, конференций, телевидения и образовательных платформ. Наша команда — 12 инженеров с суммарным опытом более 25 лет в области STT и NLP. Мы реализовали 10+ инсталляций для событий с аудиторией до 5000 человек и обеспечили доступ к информации для тысяч слабослышащих. Внедрение AI-субтитров позволяет сэкономить до 40% бюджета по сравнению с ручным субтитрированием, а окупаемость наступает в течение 2–3 месяцев при регулярных трансляциях. Для оценки вашего проекта свяжитесь с нами — мы предложим решение под ключ.

Проблемы, которые решаем

Стандартные субтитры часто отстают от речи на 5–10 секунд — это неприемлемо для слабослышащих. Типичные сложности:

  • Синхронизация текста и звука страдает при использовании batch-обработки аудио.
  • Облачные STT-сервисы не всегда справляются с доменной лексикой (медицинская, юридическая терминология).
  • Интеграция с платформами вроде Zoom и Teams требует отдельного бота и настройки API.

Мы решаем эти проблемы через выбор streaming-модели, оптимизацию буферизации и кастомизацию словаря. Например, в одном проекте для конференции по телемедицине мы дообучили Whisper на корпусе медицинских терминов — точность распознавания выросла с 82% до 95%.

Как обеспечить задержку менее 2 секунд?

Ключ — выбор streaming-модели и архитектура передачи аудио. Deepgram Nova-2 выдаёт partial results каждые 200 мс, что даёт задержку end-to-end около 1 секунды — в 2–3 раза быстрее, чем faster-whisper large-v3 в batch-режиме. Для локальных сценариев мы используем faster-whisper с VAD-фильтром и буфером 3 секунды, что даёт 2.5–4 секунды. Но если нужна < 2 сек — только облачный streaming.

Real-time STT стек

Для субтитров с задержкой < 2 секунд от момента речи используем локальный faster-whisper или облачный Deepgram Nova-2. Пример ядра на Python:

import asyncio import websockets from faster_whisper import WhisperModel import numpy as np import sounddevice as sd class RealTimeCaptioner: def __init__(self): self.model = WhisperModel( "large-v3", device="cuda", compute_type="float16" ) self.buffer = [] self.chunk_duration = 3.0 # секунды буферизации self.sample_rate = 16000 async def stream_captions(self, websocket, audio_queue: asyncio.Queue): """Стриминг субтитров через WebSocket""" while True: chunk = await audio_queue.get() self.buffer.append(chunk) buffer_duration = len(self.buffer) * len(chunk) / self.sample_rate if buffer_duration >= self.chunk_duration: audio_data = np.concatenate(self.buffer) self.buffer = [] segments, _ = self.model.transcribe( audio_data, language="ru", vad_filter=True, vad_parameters={"min_silence_duration_ms": 500} ) for segment in segments: caption = { "text": segment.text.strip(), "start": segment.start, "end": segment.end, "confidence": segment.avg_logprob } await websocket.send(json.dumps(caption, ensure_ascii=False)) 

WebRTC интеграция для браузера

Клиентская часть на JavaScript захватывает аудио с микрофона и передаёт на сервер через WebSocket. Сервер возвращает субтитры, которые отображаются с rolling-окном.

// Клиентская часть: захват аудио и стриминг на сервер class LiveCaptionClient { constructor(wsUrl) { this.ws = new WebSocket(wsUrl); this.captionDiv = document.getElementById('captions'); } async startCapturing() { const stream = await navigator.mediaDevices.getUserMedia({ audio: { sampleRate: 16000, channelCount: 1, echoCancellation: true } }); const audioContext = new AudioContext({ sampleRate: 16000 }); const processor = audioContext.createScriptProcessor(4096, 1, 1); processor.onaudioprocess = (event) => { const pcmData = event.inputBuffer.getChannelData(0); const int16Array = new Int16Array(pcmData.length); for (let i = 0; i < pcmData.length; i++) { int16Array[i] = Math.max(-32768, Math.min(32767, pcmData[i] * 32768)); } if (this.ws.readyState === WebSocket.OPEN) { this.ws.send(int16Array.buffer); } }; this.ws.onmessage = (event) => { const caption = JSON.parse(event.data); this.displayCaption(caption.text); }; const source = audioContext.createMediaStreamSource(stream); source.connect(processor); processor.connect(audioContext.destination); } displayCaption(text) { // Отображение с rolling-window (последние 2-3 строки) const line = document.createElement('p'); line.textContent = text; line.className = 'caption-line'; this.captionDiv.appendChild(line); // Убираем старые строки while (this.captionDiv.children.length > 3) { this.captionDiv.removeChild(this.captionDiv.firstChild); } // Auto-scroll this.captionDiv.scrollTop = this.captionDiv.scrollHeight; } } 

Как выбрать STT-модель для субтитров?

Выбор между локальным и облачным решением:

Параметр faster-whisper (локально) Deepgram Nova-2 (облако)
Задержка 0.3–0.8 сек (инференс) 0.1–0.3 сек (streaming)
Качество высокое (large-v3) высокое (специализированная)
Конфиденциальность полная данные уходят в облако
Стоимость один GPU (~$0.5/час) $0.004/мин аудио
Поддержка языков 99+ 30+

Для задач, где нужна полная изоляция данных (медицинские, государственные) — локальный faster-whisper с Triton Inference Server. Для типовых трансляций — облачный Deepgram или AssemblyAI. Мы оценим проект и предложим оптимальный вариант. Закажите предварительный аудит — он бесплатен и займёт 30 минут.

Требования к отображению (WCAG 2.1)

/* Субтитры для слабослышащих — WCAG 2.1 критерий 1.4.3 */ .caption-container { background-color: rgba(0, 0, 0, 0.85); color: #FFFFFF; font-size: 1.5rem; /* минимум 24px */ line-height: 1.6; padding: 12px 20px; border-radius: 4px; max-width: 80%; font-family: Arial, sans-serif; /* высокая разборчивость */ } /* Высокий контраст (коэффициент 7:1 для AA+) */ .caption-line { color: #FFFFFF; text-shadow: 1px 1px 2px #000; } 

Интеграция с Zoom/Teams через Bot

# Zoom использует RTMP для стриминга субтитров import httpx async def push_zoom_captions(meeting_id: str, caption_text: str, seq: int): """Отправляем субтитры в Zoom через Closed Caption API""" async with httpx.AsyncClient() as client: await client.post( f"https://api.zoom.us/v2/meetings/{meeting_id}/live_streaming/captions", json={"text": caption_text, "seq": seq, "lang": "ru-RU"}, headers={"Authorization": f"Bearer {ZOOM_JWT_TOKEN}"} ) 

Что такое streaming transcription?

Streaming transcription — это технология, при которой модель распознаёт речь по мере поступления аудиофрагментов, выдавая промежуточные результаты (partial results) каждые 100-200 мс. Это позволяет обновлять субтитры плавно, без пауз на ожидание полной фразы. Используем WebSocket для передачи аудиофрагментов и получения текста с временными метками.

Чек-лист для внедрения

  • [ ] Аудит текущих каналов звука и платформы
  • [ ] Выбор STT-модели (локальная/облачная)
  • [ ] Калибровка под доменную лексику
  • [ ] Разработка WebRTC/WebSocket-сервера
  • [ ] Интеграция с Zoom, Teams, YouTube Live, RTMP
  • [ ] Интерфейс управления и ручной коррекции
  • [ ] Документация и обучение операторов
  • [ ] Гарантия 6 месяцев

Ориентировочные сроки

Веб-компонент субтитрирования — 1–2 недели. Полная интеграция с платформами — 2–3 недели. Для оценки вашего проекта свяжитесь с нами — опишите сценарий, и мы рассчитаем решение. Экономия бюджета может достигать 40% по сравнению с ручным субтитрированием, а окупаемость — за 2–3 месяца. Получите консультацию прямо сейчас!