Files
vidconf/frontend/src/lib/screenShareOptions.ts
Max Ronzhin f89bf1ad64 feat(room): кнопка демонстрации экрана в мини-окне
В Document PiP (Chrome/Edge) своего тулбара нет, и начать демонстрацию,
не свернув мини-окно, было нельзя. Кнопка сделана по образцу кнопки
микрофона, добавленной в 0.0.15: тот же `useTrackToggle` через
`RoomContext`, поэтому она и кнопка основного тулбара — два вида одного
состояния и рассинхрону взяться неоткуда.

Главный вопрос задачи — пустит ли платформа `getDisplayMedia()`, вызванный
из кода основного окна по клику в ДРУГОМ окне. Замер в Chrome 150: после
клика в PiP `navigator.userActivation.isActive === true` в обоих окнах,
активация доезжает до опенера, вызов проходит, системный пикер выбора
экрана открывается отдельным окном поверх всего, а не прячется за
заглушкой основного окна.

Опции захвата (`SCREEN_SHARE_CAPTURE_OPTIONS`) вынесены из `RoomToolbar` в
`lib/screenShareOptions.ts`: кнопок демонстрации теперь две, и разойдись
они хотя бы в `audio`, демонстрация получалась бы разной в зависимости от
того, откуда её запустили.

Фокус в мини-окне не менялся: своя демонстрация показывается по тем же
правилам `pickStageFocus`, что и в основном окне.

В Safari мини-окно — нативный video-PiP без собственного DOM, кнопке там
негде жить; в Firefox мини-окна нет вовсе. Это ограничение платформы.
2026-08-04 21:13:27 +03:00

30 lines
2.0 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import type { ScreenShareCaptureOptions } from 'livekit-client'
/**
* Опции захвата демонстрации экрана: `audio: true` — звук
* вкладки/экрана там, где браузер его отдаёт (Chrome/Edge — вкладка почти
* всегда, целый экран — только Windows); `selfBrowserSurface: 'exclude'`
* — не предлагать в списке
* источников собственную вкладку (зеркальный туннель самой конференции);
* `surfaceSwitching: 'include'` — разрешить переключать источник прямо во
* время демонстрации, не останавливая её; `systemAudio: 'include'` — не
* запрещать захват системного звука при выборе «весь экран».
*
* Вынесено в модульную константу — `useTrackToggle` держит
* `JSON.stringify(captureOptions)` в зависимостях внутреннего `useMemo`,
* инлайновый литерал был бы безвреден, но константа явнее фиксирует
* неизменность опций.
*
* Живёт в `lib/`, а не рядом с тулбаром, потому что кнопок демонстрации теперь
* ДВЕ: в основном тулбаре (`RoomToolbar`) и в мини-окне (`RoomStage`,
* `PipScreenShareToggle`). Опции у них обязаны совпадать: обе кнопки управляют
* одной и той же публикацией, и разойдись они хотя бы в `audio`, демонстрация
* получалась бы разной в зависимости от того, откуда её запустили.
*/
export const SCREEN_SHARE_CAPTURE_OPTIONS: ScreenShareCaptureOptions = {
audio: true,
selfBrowserSurface: 'exclude',
surfaceSwitching: 'include',
systemAudio: 'include',
}