Compare commits
2 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 6554fa242b | |||
| 1089d874af |
@@ -128,7 +128,7 @@ SMTP_TIMEOUT_S=30
|
|||||||
# --- Версия инстанса (релиз v0.0.1) ---
|
# --- Версия инстанса (релиз v0.0.1) ---
|
||||||
# install.sh копирует значение из корневого файла VERSION при каждой
|
# install.sh копирует значение из корневого файла VERSION при каждой
|
||||||
# установке/обновлении — руками менять не нужно.
|
# установке/обновлении — руками менять не нужно.
|
||||||
VIDCONF_VERSION=0.0.35
|
VIDCONF_VERSION=0.0.36
|
||||||
|
|
||||||
# --- Профили compose. Дефолт ниже (`media,monitoring`) — только для ручного
|
# --- Профили compose. Дефолт ниже (`media,monitoring`) — только для ручного
|
||||||
# `docker compose up` БЕЗ install.sh: медиа (LiveKit+coturn) + мониторинг,
|
# `docker compose up` БЕЗ install.sh: медиа (LiveKit+coturn) + мониторинг,
|
||||||
|
|||||||
1
.gitignore
vendored
1
.gitignore
vendored
@@ -61,3 +61,4 @@ frontend/public/mediapipe/wasm/
|
|||||||
|
|
||||||
# Рабочая страница замера CPU (сессия 35), в репозиторий не идёт.
|
# Рабочая страница замера CPU (сессия 35), в репозиторий не идёт.
|
||||||
frontend/bg-bench.html
|
frontend/bg-bench.html
|
||||||
|
frontend/bg-support.html
|
||||||
|
|||||||
12
CHANGELOG.md
12
CHANGELOG.md
@@ -3,6 +3,18 @@
|
|||||||
Формат основан на [Keep a Changelog](https://keepachangelog.com/ru/1.1.0/),
|
Формат основан на [Keep a Changelog](https://keepachangelog.com/ru/1.1.0/),
|
||||||
проект придерживается [семантического версионирования](https://semver.org/lang/ru/).
|
проект придерживается [семантического версионирования](https://semver.org/lang/ru/).
|
||||||
|
|
||||||
|
## [0.0.36] — 2026-08-10
|
||||||
|
|
||||||
|
Исправление к 0.0.35: замена фона не появлялась в Safari и Firefox.
|
||||||
|
|
||||||
|
### Исправлено
|
||||||
|
- Проверка поддержки замены фона была строже, чем требует библиотека, и
|
||||||
|
молча отрезала два браузера — кнопки выбора фона не было ни в превью, ни
|
||||||
|
в комнате. У библиотеки два конвейера обработки кадров: современный
|
||||||
|
(только Chrome и производные) и запасной через `canvas.captureStream()`,
|
||||||
|
который работает и в Safari, и в Firefox; проверка требовала именно
|
||||||
|
современный. Теперь условие буквально повторяет проверку самой библиотеки.
|
||||||
|
|
||||||
## [0.0.35] — 2026-08-10
|
## [0.0.35] — 2026-08-10
|
||||||
|
|
||||||
Замена фона видео на картинку — отключаемый модуль (по умолчанию выключен).
|
Замена фона видео на картинку — отключаемый модуль (по умолчанию выключен).
|
||||||
|
|||||||
@@ -89,7 +89,7 @@ services:
|
|||||||
MEDIA_ROOT: ${MEDIA_ROOT:-/app/media}
|
MEDIA_ROOT: ${MEDIA_ROOT:-/app/media}
|
||||||
# Версия инстанса (релиз v0.0.1) — install.sh копирует значение
|
# Версия инстанса (релиз v0.0.1) — install.sh копирует значение
|
||||||
# из файла VERSION (корень репозитория) в .env; отдаётся в GET /api/health.
|
# из файла VERSION (корень репозитория) в .env; отдаётся в GET /api/health.
|
||||||
VIDCONF_VERSION: ${VIDCONF_VERSION:-0.0.35}
|
VIDCONF_VERSION: ${VIDCONF_VERSION:-0.0.36}
|
||||||
# Число процессов uvicorn (см. backend/Dockerfile). Дефолт 2 рассчитан
|
# Число процессов uvicorn (см. backend/Dockerfile). Дефолт 2 рассчитан
|
||||||
# на 4-ядерный сервер, где ядра делятся с LiveKit. Поднимая значение,
|
# на 4-ядерный сервер, где ядра делятся с LiveKit. Поднимая значение,
|
||||||
# проверьте бюджет соединений с БД: каждый воркер держит свой пул
|
# проверьте бюджет соединений с БД: каждый воркер держит свой пул
|
||||||
|
|||||||
@@ -98,21 +98,60 @@ export function resolveBackgroundUrl(
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Поддерживает ли браузер сегментацию вообще.
|
* Поддерживает ли браузер замену фона.
|
||||||
*
|
*
|
||||||
* Проверяется по наличию API конвейера обработки кадров (Insertable Streams /
|
* Проверка СИНХРОННАЯ и намеренно не трогает саму библиотеку: решение нужно
|
||||||
* `MediaStreamTrackProcessor`) — их нет, например, в Firefox. Проверка
|
* ДО её загрузки, чтобы не показывать кнопку, которая не сработает, и не
|
||||||
* СИНХРОННАЯ и намеренно не трогает саму библиотеку: она нужна до её загрузки,
|
* тянуть мегабайты впустую. Поэтому здесь буквально повторено условие
|
||||||
* чтобы не показывать кнопку, которая всё равно не сработает, и не тянуть
|
* `supportsBackgroundProcessors()` из `@livekit/track-processors` — при
|
||||||
* мегабайты впустую.
|
* обновлении пакета сверять с ним.
|
||||||
|
*
|
||||||
|
* ⚠️ Конвейеров у библиотеки ДВА, и требовать современный нельзя:
|
||||||
|
* - современный (`MediaStreamTrackProcessor`/`Generator`, Insertable Streams)
|
||||||
|
* есть только в Chrome и производных;
|
||||||
|
* - запасной рисует кадры в canvas и отдаёт `canvas.captureStream()` — он
|
||||||
|
* работает в Safari и Firefox.
|
||||||
|
*
|
||||||
|
* Первая версия (0.0.35) требовала именно современный конвейер — и фича
|
||||||
|
* молча отсутствовала в Safari и Firefox, хотя запасной путь там доступен.
|
||||||
|
* Условие ниже — «умеет считать сегментацию» И «есть хоть какой-то конвейер».
|
||||||
*/
|
*/
|
||||||
export function isVirtualBackgroundSupported(): boolean {
|
export function isVirtualBackgroundSupported(): boolean {
|
||||||
if (typeof window === 'undefined') return false
|
if (typeof window === 'undefined') return false
|
||||||
return (
|
return canRunSegmentation() && hasAnyFramePipeline()
|
||||||
'MediaStreamTrackProcessor' in window &&
|
}
|
||||||
'MediaStreamTrackGenerator' in window &&
|
|
||||||
typeof OffscreenCanvas !== 'undefined'
|
/**
|
||||||
)
|
* Условие `BackgroundTransformer.isSupported`: чем библиотека считает маску и
|
||||||
|
* собирает кадр. WebGL2 проверяется созданием пробного контекста — иначе никак,
|
||||||
|
* но результат кэшируется на всю жизнь страницы: браузеры держат ограниченное
|
||||||
|
* число живых WebGL-контекстов, и создавать новый на каждый рендер нельзя.
|
||||||
|
*/
|
||||||
|
let segmentationSupport: boolean | null = null
|
||||||
|
function canRunSegmentation(): boolean {
|
||||||
|
if (segmentationSupport !== null) return segmentationSupport
|
||||||
|
const hasApis =
|
||||||
|
typeof OffscreenCanvas !== 'undefined' &&
|
||||||
|
typeof VideoFrame !== 'undefined' &&
|
||||||
|
typeof createImageBitmap !== 'undefined'
|
||||||
|
if (!hasApis) {
|
||||||
|
segmentationSupport = false
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
const probe = document.createElement('canvas').getContext('webgl2')
|
||||||
|
// Пробный контекст сразу отпускаем — он больше не нужен, а слот в лимите
|
||||||
|
// браузера занимал бы до сборки мусора.
|
||||||
|
probe?.getExtension('WEBGL_lose_context')?.loseContext()
|
||||||
|
segmentationSupport = Boolean(probe)
|
||||||
|
return segmentationSupport
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Условие `ProcessorWrapper.isSupported`: современный конвейер ЛИБО запасной на canvas. */
|
||||||
|
function hasAnyFramePipeline(): boolean {
|
||||||
|
const modern = 'MediaStreamTrackProcessor' in window && 'MediaStreamTrackGenerator' in window
|
||||||
|
const fallback =
|
||||||
|
typeof HTMLCanvasElement !== 'undefined' && 'captureStream' in HTMLCanvasElement.prototype
|
||||||
|
return modern || fallback
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
Reference in New Issue
Block a user