const fs = require("fs"); const http = require("http"); const config = fs.readFileSync(process.argv[2], "utf8"); const portFor = (key) => Number(new RegExp(`^${key}:\\s*"127\\.0\\.0\\.1:(\\d+)"`, "m").exec(config)?.[1]); const pathName = /^paths:\s*\n\s+"([^"]+)":/m.exec(config)?.[1] || null; const apiPort = portFor("apiAddress"); const metricsPort = portFor("metricsAddress"); const hlsPort = portFor("hlsAddress"); const servers = []; function listen(port, handler) { const server = http.createServer(handler); server.listen(port, "127.0.0.1"); servers.push(server); } listen(apiPort, (req, res) => { if (req.url !== "/v3/paths/list") return res.writeHead(404).end(); res.setHeader("Content-Type", "application/json"); res.end(JSON.stringify({ itemCount: pathName ? 1 : 0, pageCount: 1, items: pathName ? [{ name: pathName, ready: false, tracks: [], bytesReceived: 0, bytesSent: 0, readers: [] }] : [] })); }); listen(metricsPort, (_req, res) => { res.setHeader("Content-Type", "text/plain"); res.end(pathName ? `paths{name=${JSON.stringify(pathName)}} 1\npaths_readers{name=${JSON.stringify(pathName)}} 0\npaths_inbound_bytes{name=${JSON.stringify(pathName)}} 0\npaths_outbound_bytes{name=${JSON.stringify(pathName)}} 0\nhls_sessions 0\n` : "paths 0\nhls_sessions 0\n"); }); listen(hlsPort, (req, res) => { if (!pathName || !req.url.startsWith(`/${pathName}/`)) return res.writeHead(404).end(); if (req.url.includes("index.m3u8")) { res.setHeader("Content-Type", "application/vnd.apple.mpegurl"); return res.end("#EXTM3U\n#EXT-X-MAP:URI=\"init.mp4\"\n#EXTINF:1,\nsegment0.mp4\n"); } res.setHeader("Content-Type", "video/mp4"); res.end(Buffer.from("fake-media")); }); function close() { let pending = servers.length; if (!pending) return process.exit(0); for (const server of servers) server.close(() => { pending -= 1; if (!pending) process.exit(0); }); setTimeout(() => process.exit(0), 500).unref(); } process.on("SIGINT", close); process.on("SIGTERM", close);