const grid = document.getElementById("grid"); async function fetchStreams() { try { const res = await fetch("/stat"); // You may need a JSON stat endpoint const text = await res.text(); // Simple parsing to get stream keys from the rtmp_stat XML const parser = new DOMParser(); const xml = parser.parseFromString(text, "text/xml"); const streams = Array.from(xml.getElementsByTagName("stream")).map(s => s.getAttribute("name")); renderStreams(streams); } catch (e) { console.error(e); } } function renderStreams(streams) { grid.innerHTML = ""; const columns = Math.ceil(Math.sqrt(streams.length)); grid.style.gridTemplateColumns = `repeat(${columns}, 1fr)`; streams.forEach(stream => { const container = document.createElement("div"); const video = document.createElement("video"); video.src = `/live/${stream}.flv`; // Use HLS/FLV player if needed video.controls = true; video.autoplay = true; video.muted = false; const btn = document.createElement("button"); btn.textContent = "Play/Pause"; btn.onclick = () => video.paused ? video.play() : video.pause(); container.appendChild(video); container.appendChild(btn); grid.appendChild(container); }); } // Refresh every 5 seconds setInterval(fetchStreams, 5000); fetchStreams();