Перейти к основному содержимому

Медиа-звонки и запись на Jitsi — интеграционный гид (messenger)

Дом интеграции media-стека звонков контекста messenger с саморазмещённым Jitsi. Здесь описано, как абстрактные контракты домена и API (нейтральные «media-стек / SFU», MediaJoinModel) отображаются на конкретные компоненты Jitsi: prosody, jicofo, JVB (SFU), jibri (запись), coturn (TURN). Доменные и API-документы остаются нейтральными (ADR-0062) — конкретика Jitsi живёт только здесь и в api/internal/ (вебхуки от media-стека).

Назначение папки. Это не спецификация домена, а гид/раннбук интеграции: он называет компоненты и конфиг-ключи Jitsi, указывает пути в thirdparty/jitsi/* и объясняет, что PIN дорабатывает. Контракт (сущности, поля, статусы, события, ошибки) — в domain/, api/, events/; здесь — как это работает на Jitsi.

Обзор

Звонки и конференции PIN — это нативный клиент поверх lib-jitsi-meet (без веб-SPA jitsi-meet), подключённый к саморазмещённому Jitsi. Медиа (звук/видео/демонстрация экрана) идёт клиент ↔ SFU (JVB) — бэкенд messenger не в медиа-плоскости: он раздаёт вход в комнату (имя + короткоживущий JWT), принимает серверные вебхуки о жизненном цикле и финализирует записи.

  • SFU = JVB (jitsi-videobridge): маршрутизация медиа между участниками (SFU, не mesh). Для 1:1 включаем p2p.enabled (медиа напрямую, JVB подключается при escalation/3+).
  • Сигналинг/присутствие = prosody + jicofo: комнаты MUC, роли, admission. Авторитет состава — серверные hook-и prosody (вебхуки в messenger), не клиентские события (jitsi-rooms.md).
  • Запись = jibri (по политике RecordingPolicy.ShouldAutoRecord): захват → выгрузка в file storage (recording-pipeline.md). Файл записи хранит messenger как FileId + метаданные, бинарь — в file storage (ADR-0032, call-recording.md INV-REC-6).
  • NAT/TURN = coturn: обход NAT для клиентов за симметричным NAT.

Бэкенд messenger stateless относительно медиа: не подключается к XMPP, не хранит SDP/ICE/токены (INV-CALL-4/6, INV-CONF-7). Он только минтит JWT входа (jitsi-jwt.md) и принимает вебхуки (../api/internal/).

Feature-флаги

ФлагГейтитПоведение при false
CALLS_MEDIA_ENABLEDmedia 1:1-звонков (комната + токен)503 MSG_CALLS_DISABLED на media-операциях 1:1
CONFERENCE_CALLS_ENABLEDгрупповые конференции в чате сделки503 MSG_CONFERENCES_DISABLED
RECORDINGS_ENABLEDзапись сессий (jibri)запись не стартует; сессия/звонок работают без записи

Авто-запись — не булев флаг, а типизированное решение RecordingPolicy.ShouldAutoRecord(chatKind, sessionKind) (recording-pipeline.md). Исторический CALLS_SIGNALING_ENABLED (signaling-only стадия) поглощён CALLS_MEDIA_ENABLED.

Карта сущностей ↔ Jitsi

Сущность (дом)Роль в JitsiКомната
CallSessionEntity (1:1)MUC-комната на 2 участников (p2p предпочтителен)call-{CallSessionId}
ConferenceSessionEntityMUC-комната сделки, динамический ростерconf-{ConferenceSessionId}
CallParticipantEntityoccupant MUC; presence-вебхук — авторитет ростера
CallRecordingEntityсессия jibri (file mode) → file storage
MediaRoom (owned VO){ RoomName, Domain } — маршрутный id комнаты (не медиа/PII)

Имя комнаты детерминировано из id сессии, потому что reservation-вебхук prosody несёт только имя — по нему messenger находит сессию (jitsi-rooms.md).

Документы гида

Реализация и поставка (аналитик → разработчик)

Как это построить и в каком порядке, спека → код, предпосылки и приёмка.

ДокументО чём
session-lifecycle.mdЖизненный цикл сессии (1:1 и конференция): как создать/открыть, как подключить/добавить участников (join/invite/decline/remove), как закрыть — все пути, гонки, реконнект, sequence-диаграммы, матрица «действие → эндпоинт → переход → событие»
implementation-plan.mdМастер-план поставки: фазы Ф0–Ф6 (DoR/задачи/DoD/риски), дерево зависимостей, RACI, критический путь, порядок мержа, два master sequence-диаграммы, продакшн-чеклист
backend-implementation.mdСпека → код (.NET/SDK Talent.Common.*): раскладка проектов, агрегаты/EF (ConfigureOwnedTypes MediaRoom, XOR-CHECK, partial-индексы), DDL+миграции, CQRS-операции всех эндпоинтов, RecordingPolicy, JitsiTokenService, filestorage-адаптер, HMAC-фильтр internal, outbox→dispatch
filestorage-prerequisites.mdПошаговый чеклист изменений в talent.microservices.filestorage: категория CALL_RECORDINGS, видео content-types, сидеры, миграция, стриминг-загрузка
testing-and-acceptance.mdСквозная верификация: локальный dev-стек docker-jitsi-meet, пирамида тестов, e2e по UC-005/006/007, тесты безопасности, acceptance-чеклист, наблюдаемость

Компоненты и конфигурация Jitsi

Как контракт отображается на конкретные компоненты, конфиги и правки Jitsi.

ДокументО чём
jitsi-deployment.mdk8s-топология: prosody/jicofo/JVB/jibri/coturn, реплики, порты, env-матрица, prosody/jicofo config-скетчи, секреты/сеть/health; как stateless-бэкенд взаимодействует
jitsi-manifests.mdk8s/Helm YAML-скетчи всех компонентов (Deployment/Service/HPA/ConfigMap/Secret), UDP-hostPort JVB, /mnt/recordings jibri, TLS-ingress → /xmpp-websocket
jitsi-jwt.mdминтинг JWT входа в .NET (HS256 + app_secret); claim-структура + пример payload; ротация ключа; маппинг MediaJoinModel.AccessToken
jitsi-rooms.mdименование комнат, authoritative-lifecycle через mod_reservations (wire-формат), presence-вебхук через кастомный prosody-модуль, sequence-диаграмма
jitsi-client.mdнативный lib-jitsi-meet на Next.js 16: connect → join → tracks → события → мост в SignalR; FSD-раскладка
recording-pipeline.mdсквозная авто-запись: policy → jibri → finalize-скрипт → ingest → file storage → Available → Kafka
jitsi-modifications.mdинвентарь изменений в thirdparty/jitsi/*: полный текст pin_finalize.sh, скетч mod_pin_muc_presence.lua, per-component change list с путями
transcription-roadmap.mdбудущая фаза STT/конспект (шов, не блокирует)

Границы и предпосылки

  • Нейтральность именования. В domain/, api/{calls,conferences,recordings}/ и hub — только «media-стек / SFU» и MediaJoinModel; «Jitsi/jibri/prosody» допустимы лишь здесь и в api/internal/ (вебхуки — их предмет).
  • Right-sizing (ADR-0056). Целевая нагрузка низкая (1–10k активных, конференции редки) — минимальные реплики, один регион, без Octo (jitsi-deployment.md).
  • Config-reference vs IaC. Мета-репозиторий Jitsi поставляет Nomad-IaC (thirdparty/jitsi/infra-provisioning/nomad/*) как референс конфигурации; PIN пишет собственные Helm/k8s-манифесты, перенося оттуда env-переменные и параметры.
  • Блокирующие предпосылки file storage. Для записей нужны новая категория CALL_RECORDINGS и видео content-types (mp4/webm/mkv) на стороне file storage (recording-pipeline.md).

Связанные документы