Проверка поддержки была строже, чем требует библиотека, и молча отрезала два
браузера: кнопки выбора фона не было ни в превью, ни в комнате.
У `@livekit/track-processors` ДВА конвейера обработки кадров: современный
(`MediaStreamTrackProcessor`/`Generator`, только Chrome и производные) и
запасной — рисует кадры в canvas и отдаёт `canvas.captureStream()`. Проверка
требовала именно современный, хотя запасной путь доступен и в Safari, и в
Firefox. Заодно она проверяла `OffscreenCanvas`, но пропускала `VideoFrame`,
`createImageBitmap` и WebGL2, которые библиотеке реально нужны.
Теперь условие буквально повторяет `supportsBackgroundProcessors()` из самой
библиотеки: «умеет считать сегментацию» И «есть хоть какой-то конвейер».
При обновлении пакета сверять с ним.
Пробный WebGL2-контекст (иначе поддержку не определить) создаётся один раз на
жизнь страницы и сразу отпускается через `WEBGL_lose_context`: браузеры
держат ограниченное число живых контекстов.
Проверено: в Firefox 153 детект возвращает «поддерживается» (современного
конвейера нет, запасной есть), в Chrome регрессии нет — процессор
поднимается, трек живой.
Кнопка «Фон» в тулбаре комнаты и выбор фона в превью на входе: три готовые
сцены и свои картинки из профиля. Фон применяется процессором к самому
публикуемому треку (`LocalVideoTrack.setProcessor`), а НЕ пересозданием
`RoomOptions` — ссылка на них обязана оставаться стабильной, иначе
`LiveKitRoom` переподключается к комнате.
Фича только для ДЕСКТОПА, и «десктоп» определяется по возможностям устройства
(`pointer: fine` + `hover: hover` + `maxTouchPoints`), а НЕ по ширине окна:
узкое окно на десктопе — всё ещё десктоп, а широкий планшет — всё ещё планшет,
который сегментация греет. На мобильном кнопки нет вовсе, а не задизейбленной.
Ассеты сегментации отдаются СО СВОЕГО домена: библиотека по умолчанию тянет
wasm с jsdelivr, а модель с storage.googleapis.com, и в закрытом контуре фича
молча не работала бы. Модель (Apache 2.0, см. NOTICE.txt) лежит в репозитории,
wasm-рантайм (~19 МБ) копируется из node_modules плагином сборки. Сама
библиотека и модель грузятся ЛЕНИВО — только когда фон реально включают, вход
в конференцию не стал медленнее.
Три дефолтные сцены — собственные векторные рисунки (`design/backgrounds/`),
а не фотографии из интернета: у нарисованной сцены нет чужой лицензии, а
продукт расходится по инсталляциям, и проверять права на каждую копию некому.
Свои картинки — в профиле, до 10 штук, с уменьшением до 1280px и переводом в
WebP прямо в браузере перед отправкой. Удаление применённого сейчас фона
сбрасывает выбор на «без фона»: хранится ключ записи, а не URL картинки.
Смена камеры фон не теряет (`restartTrack` перезапускает процессор сам),
выключение и включение камеры — навешивает его на новый трек заново.
⚠️ Прокси dev-сервера для `/media/` — обязательно со слэшем: ключ `/media`
Vite матчит префиксом и перехватывает заодно `/mediapipe/...`, из-за чего
модель получала 404 и фон молча не включался.
Redis without a password was the root cause of the security incident
(cron miner via unauthenticated replication RCE, see
.forcc/deploy/SESSION2-FINDINGS.md). Loopback binding alone doesn't
protect against a compromised container inside the same compose
network, so wire REDIS_PASSWORD as a required secret everywhere redis
is used: backend/worker/worker-transcriber(-gpu), redis-exporter,
livekit and egress (via rendered templates). docker compose now
refuses to start without it instead of silently running unauthenticated.
Переносит рабочие правки продакшен-сервера в репозиторий воспроизводимо:
- nginx: HTTPS-блок на 443 (TLS1.2/1.3, http->https redirect, ACME
webroot, X-Forwarded-Proto) добавлен в nginx.conf.template. Список
доменов и имя каталога сертификата — параметры (NGINX_SERVER_NAMES,
NGINX_CERT_NAME), не хардкод. Рендерится штатным entrypoint'ом образа
nginx (envsubst-on-templates).
- Самоподписанный dev-сертификат генерируется на старте контейнера
(docker-entrypoint-certs.sh), если реальный Let's Encrypt не смонтирован
— иначе `docker compose up` без профиля ломался бы локально без
реальных сертификатов.
- healthcheck nginx переключён на /healthz (без TLS-редиректа), иначе
http://127.0.0.1:80/ после добавления 443-редиректа всегда unhealthy.
- coturn/turnserver.conf и livekit/livekit.yaml переведены в *.template —
оба образа не читают env для статических полей (static-auth-secret,
use_external_ip/node_ip, webhook.api_key), поэтому реальные файлы
генерируются перед стартом стека скриптом deploy/render-templates.sh
(вызывается install.sh). Секреты/IP — только в .env, не в git.
- docker-compose.yml: LIVEKIT_API_KEY/SECRET везде (backend, livekit,
egress) через ${VAR:?} без небезопасных дефолтов; порт 443 + монтирование
/etc/letsencrypt (ro) и certbot-webroot у nginx; build-args
VITE_LIVEKIT_URL/NEXT_PUBLIC_LIVEKIT_URL для frontend (сейчас не
используются кодом, оставлены про запас).