В 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 мини-окна нет вовсе. Это ограничение платформы.
30 lines
2.0 KiB
TypeScript
30 lines
2.0 KiB
TypeScript
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',
|
||
}
|