Go Live: request window-scoped audio (windowAudio: window, Chrome 141+); keep the picker window-only
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
This commit is contained in:
@@ -205,7 +205,7 @@ asked by `configure.py --full`) can post when a stream starts.
|
||||
embedded outpost → group policy (e.g. everyone in the server, or `streamers`+`editors`+`admins`).
|
||||
3. Dev box: `./deployLive.sh` builds `live/` and copies `dist/` to `/srv/live` (Caddy serves it directly).
|
||||
|
||||
**Go Live** button: broadcast a window from the browser (no OBS) as `<user>/HelmetCam-<date>` — key comes
|
||||
**Go Live** button (Chrome/Edge 141+ for window audio): broadcast a window from the browser (no OBS) as `<user>/HelmetCam-<date>` — key comes
|
||||
from `/me/stream-key` (dumpd reads `/etc/vanguard/streamers.json`, identity from the Authentik header), so a
|
||||
streamer's Authentik username must equal their MediaMTX name.
|
||||
|
||||
|
||||
@@ -22,6 +22,6 @@ Toolbar → **Go Live**: closes all viewer windows, fetches the logged-in user's
|
||||
`/me/stream-key` (dumpd, identity from Authentik's header), opens Chrome's window picker (windows only,
|
||||
audio requested), and publishes over WebRTC/WHIP to `<user>/HelmetCam-<date>` at ≤12 Mbps, H.264, up to
|
||||
1440p60. Recording, the "is live" post, the sweep and Jellyfin follow exactly as for an OBS stream.
|
||||
Window audio: Chrome on Windows. Linux/Mac: pick a tab or the whole screen for sound.
|
||||
Window audio: Chrome/Edge 141+ (`windowAudio: "window"`); older browsers share the window without sound.
|
||||
Requires the Authentik username to equal the MediaMTX streamer name (configure.py keeps them in sync via
|
||||
`/etc/vanguard/streamers.json`).
|
||||
|
||||
@@ -66,8 +66,8 @@ export default function GoLive({ onExit }) {
|
||||
<input value={title} onChange={e => setTitle(e.target.value)} disabled={phase === 'capturing'} />
|
||||
<div className="hint">
|
||||
Click <b>Start</b>, then pick the <b>WarDogs</b> window in Chrome's dialog and tick <b>Share audio</b>.
|
||||
Window audio works in Chrome on Windows; on Linux/Mac pick a tab or the whole screen for sound.
|
||||
Capped at {MAX_KBPS / 1000} Mbps, up to 1440p60, H.264.
|
||||
Window audio needs <b>Chrome or Edge 141 or newer</b> (chrome://version). Older browsers capture the window
|
||||
without sound. Capped at {MAX_KBPS / 1000} Mbps, up to 1440p60, H.264.
|
||||
</div>
|
||||
{err && <div className="err">{err}</div>}
|
||||
<button className="primary" disabled={!key || phase === 'capturing'} onClick={start}>{phase === 'capturing' ? 'Waiting for the window picker…' : 'Start'}</button>
|
||||
|
||||
@@ -10,14 +10,15 @@ export function defaultTitle(now = new Date()) {
|
||||
export const cleanTitle = t => t.trim().replace(/\s+/g, '-').replace(/[^A-Za-z0-9_.-]/g, '')
|
||||
|
||||
export async function captureWindow() {
|
||||
// Window-only picker with audio. Chrome on Windows captures that window's audio; elsewhere the user
|
||||
// should pick a tab or the whole screen to get sound.
|
||||
// Window-only picker with that window's own audio. Chrome/Edge 141+ honour windowAudio: "window"
|
||||
// (only the shared window's sound); older Chrome offers no audio for a window at all.
|
||||
const constraints = {
|
||||
video: { displaySurface: 'window', frameRate: { ideal: 60, max: 60 }, width: { max: 2560 }, height: { max: 1440 } },
|
||||
audio: { echoCancellation: false, noiseSuppression: false, autoGainControl: false, sampleRate: 48000, channelCount: 2 },
|
||||
systemAudio: 'include',
|
||||
windowAudio: 'window', // capture the picked window's audio (Chrome 141+)
|
||||
systemAudio: 'exclude',
|
||||
selfBrowserSurface: 'exclude',
|
||||
monitorTypeSurfaces: 'exclude', // hide "Entire screen" so people pick the game window
|
||||
monitorTypeSurfaces: 'exclude', // hide "Entire screen": this is a single-window helmet cam
|
||||
surfaceSwitching: 'include',
|
||||
preferCurrentTab: false,
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user