live/: every active stream opens as a dockable window (WHEP, HLS fallback), audio follows the focused window, per-window mute/volume, pinning. Caddy live.HOST block with forward-auth proxies /api /webrtc /hls to MediaMTX on loopback and serves /srv/live. WebRTC media on 8189 (firewall). configure.py asks the live hostname and an optional Discord webhook; MediaMTX -ffmpeg image runs the runOnReady hook. deployLive.sh builds and ships dist/. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
24 lines
900 B
JavaScript
24 lines
900 B
JavaScript
// MediaMTX control API, proxied by Caddy at /api (-> 127.0.0.1:9997). Returns active streams.
|
|
export async function fetchStreams() {
|
|
const r = await fetch('/api/v3/paths/list?itemsPerPage=200', { credentials: 'same-origin' })
|
|
if (!r.ok) throw new Error(`api ${r.status}`)
|
|
const data = await r.json()
|
|
return (data.items || [])
|
|
.filter(p => p.ready && (p.tracks || []).length > 0)
|
|
.map(p => {
|
|
const [user, ...rest] = p.name.split('/')
|
|
return {
|
|
id: p.name, // e.g. techy/VanguardTraining
|
|
user,
|
|
title: rest.join('/') || p.name,
|
|
viewers: (p.readers || []).length,
|
|
since: p.readyTime,
|
|
tracks: p.tracks || [],
|
|
}
|
|
})
|
|
.sort((a, b) => (a.since || '').localeCompare(b.since || ''))
|
|
}
|
|
|
|
export const whepUrl = id => `/webrtc/${id}/whep`
|
|
export const hlsUrl = id => `/hls/${id}/index.m3u8`
|