Skip to content

OCR субтитров

media.process.ocr_subtitles

Sapsan преобразует растровые DVB-субтитры входного стрима в отдельные текстовые дорожки. Вещатель передаёт изображение реплики; OCR распознаёт символы и связывает полученный текст со временем показа. Зритель получает субтитры, которые можно выбрать в меню плеера, даже если плеер не умеет отображать исходные DVB-изображения.

Обработка выполняется на принимающем стримере во время работы live stream. Для запуска OCR запись архива не требуется. Если DVR включён, сформированная текстовая дорожка может записываться вместе со стримом.

Какие субтитры распознаются

Входом служит отдельный сервис графических DVB-субтитров EN 300 743. В MPEG-TS его описание передаётся в PMT: оттуда Sapsan узнаёт язык и идентификаторы страниц. Распознаётся растр субтитров, а не всё видеоизображение.

У разных источников текста свои способы обработки:

  • DVB bitmap subtitles — изображения с текстом; для них предназначена секция subtitles и описанный здесь OCR.
  • Телетекст — уже содержит коды символов; извлечение настраивается секцией teletext.
  • CEA-608/708 — скрытые субтитры внутри видео, управляемые секцией closed_captions.
  • Речь в звуковой дорожке — отдельная функция распознавания речи.

Надписи, уже вжжённые в изображение видео, этот тракт OCR не извлекает. Распознанный текст сохраняет язык исходного сервиса; автоматический перевод на другой язык здесь не выполняется.

Как изображение становится текстовой дорожкой

  1. Обнаружение сервиса. Sapsan читает описание входных дорожек и находит языки DVB-субтитров. Перечислять PID и страницы вручную в конфигурации не требуется.
  2. Сборка изображения. DVB-декодер восстанавливает страницу из переданных объектов и палитр. Регионы одной композиции собираются в изображение для распознавания.
  3. Распознавание. Изображение передаётся выбранному движку. Повторная передача неизменившейся композиции не требует повторного OCR.
  4. Подготовка реплики. Из результата удаляются пустые строки и часть артефактов распознавания. Текст получает время показа на шкале стрима. Изменение или очистка страницы завершает предыдущую реплику.
  5. Выдача. Реплики поступают в общую цепочку обработки текстовых дорожек и при выдаче преобразуются в WebVTT. Их воспроизведение доступно через HLS и DASH.

Распознавание выполняет фоновый обработчик. Очередь работы ограничена: при перегрузке часть заданий может быть отброшена, и соответствующий текст будет потерян. Поэтому при проверке производительности важно наблюдать не только видео, но и задержку субтитров, а также счётчик потерь очереди.

Текст выдаётся окнами, связанными с длительностью сегмента. Уже распознанная реплика может передаваться в последовательных окнах, пока она остаётся на экране: ждать её исчезновения для первой выдачи не нужно. Пустые интервалы также учитываются, чтобы субтитровая дорожка продолжала продвигаться по времени во время пауз.

Задержка зависит от времени OCR и сегментации, а также буферизации плеера. При появлении текстовой дорожки Sapsan отключает LL-HLS для всего стрима: HLS-выдача переходит на обычные сегменты без частей LL-HLS. Учитывайте это при выборе режима для вещания с низкой задержкой. Время появления текста нужно проверять на реальном выходном тракте.

Движки распознавания

Sapsan поддерживает два движка.

Tesseract распознаёт изображение с помощью языковой модели. На стримере должны быть доступны совместимая библиотека Tesseract и файлы языковых моделей traineddata для языков входного потока. Качество результата зависит от шрифта и исходного растра; наличие модели не гарантирует безошибочный текст.

glyphtable сопоставляет изображения символов с размеченной таблицей глифов. Таблица встроена в Sapsan, отдельная библиотека OCR для этого движка не нужна. Такой способ подходит для вещателей с известными начертаниями, представленными в таблице. Незнакомые глифы превращаются в символы подмены; новая гарнитура или другой способ отрисовки требуют проверки покрытия таблицы.

Если engine не задан, Sapsan сначала пытается запустить Tesseract для обнаруженного языка, затем — glyphtable, если Tesseract не удалось инициализировать. Это выбор при запуске обработчика. Низкое качество распознанной реплики само по себе не запускает повторное распознавание другим движком.

При явном engine: tesseract или engine: glyphtable используется только выбранный движок. Если он недоступен, Sapsan показывает причину в статистике и не подменяет его другим.

Настройка

Конфигурация передаётся через API central. Для включения OCR добавьте секцию subtitles к стриму:

streams:
  - name: tv1
    inputs:
      - udp:
          host: 239.0.0.1
          port: 5000
    subtitles:
      mode: extract

Здесь Sapsan обнаруживает языки во входном потоке и выбирает доступный движок автоматически. Для явного выбора таблицы глифов секция выглядит так:

subtitles:
  mode: extract
  engine: glyphtable

Доступны три режима:

  • passthrough — режим по умолчанию. Исходные растровые субтитры сохраняются в MPEG-TS, OCR не запускается и текстовые дорожки не создаются.
  • extract — распознавание создаёт текстовые дорожки, а исходные растровые субтитры сохраняются. Этот режим позволяет проверять OCR, продолжая обслуживать устройства с DVB-декодером.
  • replace — распознавание создаёт текстовые дорожки и исключает связанный с работающим обработчиком исходный PID субтитров из MPEG-TS-выдачи.

В режиме replace исключается весь PID, включая другие языковые сервисы на нём. Если часть языков не удалось распознать, их растровые субтитры тоже могут исчезнуть из выдачи. Проверяйте все языки до выбора этого режима.

Если движок не запустился, удаление его исходного PID не включается. При потере привязки к сервису или окончательном отказе обработчика исходный PID возвращается, если его не исключает другой работающий обработчик на том же PID. Отдельная ошибка OCR или переполнение очереди не обязательно останавливает обработчик, поэтому автоматическое восстановление растра для каждой пропущенной реплики не гарантируется.

Ресурсы на принимающем стримере

Библиотека и языковые данные Tesseract должны быть доступны процессу Sapsan на сервере, который принимает стрим. Установка этих ресурсов только на central не обеспечивает распознавание.

При нестандартном размещении ресурсов используются переменные окружения процесса:

Переменная Назначение
TESSERACT_LIB Явный путь к разделяемой библиотеке Tesseract. При заданном значении пробуется именно этот путь.
TESSDATA_PATH Каталог с файлами языковых моделей .traineddata.
DVB_GLYPHS_PATH Необязательный путь к собственной таблице глифов: TSV-файлу или каталогу с glyphs.tsv.

Собственная таблица полностью заменяет встроенную, а не дополняет её. Если файл недоступен или в нём нет нужного языка, встроенная таблица автоматически не подставляется.

После установки или замены библиотеки Tesseract и изменения окружения перезапустите процесс стримера: результат загрузки библиотеки кэшируется. Появление файлов модели само по себе также не означает, что уже недоступный обработчик автоматически попробует загрузить их снова; после устранения причины пересоздайте обработчик изменением самой секции subtitles либо перезапуском стримера.

Языки и смена источника

Sapsan создаёт одну OCR-дорожку на обнаруженный язык, до девяти дорожек на стрим. Язык определяется по описанию DVB-сервиса. Если вещатель неверно указал язык, это влияет на выбор данных для распознавания и на маркировку выходной дорожки.

При нескольких сервисах одного языка выбирается первый в порядке PMT. Обычные субтитры и вариант для слабослышащих одного языка не становятся двумя независимыми OCR-дорожками.

При изменении описания входа Sapsan пересматривает привязку к сервисам. Если язык временно исчез, его выходная дорожка сохраняется, а обработчик переходит в no_source_match. Сохранение дорожек поддерживает их идентичность для потребителей, но означает, что предел в девять дорожек учитывает уже созданные дорожки, а не только языки, присутствующие в текущий момент.

При резервировании источников проверяйте наличие и корректную маркировку DVB-сервисов на каждом входе. Успешное переключение видео само по себе не подтверждает, что субтитры сохранились.

Мониторинг

Состояние OCR доступно в массиве subtitles статистики стрима на принимающем стримере:

curl -fsS -u "$ADMIN_USER:$ADMIN_PASSWORD" \
  http://streamer:8080/streamer/api-v4/streams/stats/tv1 \
  | jq '{name, subtitles: [(.subtitles // [])[] | {
      track, producer, lang, state,
      source_pid, source_page_id, source_lang,
      coverage_lag_ms, error
    }]}'

Поля source_pid и source_page_id показывают, к какому DVB-сервису привязан обработчик. coverage_lag_ms — отставание границы обработанного субтитрового интервала от шкалы стрима в миллисекундах. До первой выдачи это поле может отсутствовать; отсутствие значения не означает нулевую задержку.

Основные состояния:

  • running — обработчик работает и привязан к источнику. Это не оценка точности распознавания.
  • no_source_match — обработчик существует, но соответствующего сервиса сейчас нет. Привязка пересматривается при изменении описания входа.
  • no_model — недоступны языковые данные либо автоматический выбор не смог запустить ни один движок. Подробности находятся в error.
  • feature_missing — выбранный движок недоступен. В частности, это может означать, что библиотека Tesseract не установлена или не загрузилась.
  • failed — фоновый обработчик остановлен из-за отказа. После устранения причины требуется его пересоздание.

Пустой массив subtitles сам по себе не доказывает отсутствие модели: при включённом extract он возможен и до обнаружения первого DVB-сервиса.

Для мониторинга ошибок обработки используются метрики /streamer/api-v4/live-metrics, если их экспорт доступен в поставке:

Метрика Что проверять
stream_subtitle_up Работоспособность обработчика. Значение 1 бывает и при no_source_match; учитывайте метку state.
stream_subtitle_coverage_lag_seconds Отставание субтитровой дорожки, в секундах.
stream_subtitle_decode_errors_total Рост числа ошибок разбора входных DVB-субтитров.
stream_subtitle_ocr_errors_total Рост числа ошибок распознавания.
stream_subtitle_queue_drops_total Потери заданий из-за переполнения очереди OCR.

Счётчики ошибок накопительные: для оценки текущей работы сравнивайте их изменение за интервал. Они не входят в массив subtitles приведённого API-запроса.

Проверка результата

  1. Включите extract и убедитесь, что во входном потоке действительно есть растровые DVB-субтитры.
  2. Проверьте обнаруженные языки и привязки к PID/страницам. Убедитесь, что обработчики перешли в running.
  3. Выберите текстовую дорожку в плеере. Сравните реплики с исходным изображением на разных передачах; проверьте символы и переносы строк, а также синхронизацию с видео.
  4. Проверьте задержку и рост счётчиков ошибок под рабочей нагрузкой. Отдельно оцените символы подмены при использовании glyphtable.
  5. Если нужен replace, проверьте последствия для всех языков на исходном PID. Если нужен архив, убедитесь, что записанный фрагмент воспроизводится с текстовой дорожкой.

Поддержано растровое кодирование DVB-объектов coding_method = 0; другие методы кодирования объектов этим декодером не обрабатываются. Повреждение входных данных и недостаточная производительность могут приводить к пропускам реплик. Проверка состояния running должна дополняться проверкой самого текста.