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 мини-окна нет вовсе. Это ограничение платформы.
This commit is contained in:
29
frontend/src/lib/screenShareOptions.ts
Normal file
29
frontend/src/lib/screenShareOptions.ts
Normal file
@@ -0,0 +1,29 @@
|
||||
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',
|
||||
}
|
||||
Reference in New Issue
Block a user