Download server.js from vsmdvic/live: direct link, hf CLI and curl.
- Browser
- Download file 3.09 kB
-
https://huggingface.co/spaces/vsmdvic/live/resolve/main/server.js
- Command line
-
hf download hf://spaces/vsmdvic/live/server.js
-
curl -L -o server.js https://huggingface.co/spaces/vsmdvic/live/resolve/main/server.js
3.09 kB
| const http = require("http"); | |
| const fs = require("fs"); | |
| const path = require("path"); | |
| const { WebSocketServer } = require("ws"); | |
| const PORT = process.env.PORT || 7860; | |
| const httpServer = http.createServer((req, res) => { | |
| let file = "index.html"; | |
| if (req.url === "/admin.html") file = "admin.html"; | |
| const filePath = path.join(__dirname, file); | |
| fs.readFile(filePath, (err, data) => { | |
| if (err) { res.writeHead(404); return res.end("Not found"); } | |
| res.writeHead(200, { "Content-Type": "text/html" }); | |
| res.end(data); | |
| }); | |
| }); | |
| const wss = new WebSocketServer({ server: httpServer }); | |
| let streamerWs = null; | |
| let isLive = false; | |
| const viewers = new Set(); | |
| function sendTo(ws, obj) { | |
| if (ws && ws.readyState === 1) ws.send(JSON.stringify(obj)); | |
| } | |
| wss.on("connection", (ws) => { | |
| ws.role = null; | |
| ws._vid = null; | |
| ws.on("message", (raw) => { | |
| let msg; try { msg = JSON.parse(raw); } catch { return; } | |
| switch (msg.type) { | |
| case "streamer_join": | |
| ws.role = "streamer"; streamerWs = ws; | |
| sendTo(ws, { type: "streamer_welcome", viewerCount: viewers.size }); | |
| break; | |
| case "viewer_join": | |
| ws.role = "viewer"; ws._vid = Math.random().toString(36).slice(2); | |
| viewers.add(ws); | |
| sendTo(ws, { type: "viewer_welcome", isLive, vid: ws._vid }); | |
| sendTo(streamerWs, { type: "viewer_count", count: viewers.size }); | |
| if (isLive) sendTo(streamerWs, { type: "new_viewer", vid: ws._vid }); | |
| break; | |
| case "go_live": | |
| if (ws.role !== "streamer") return; | |
| isLive = true; | |
| viewers.forEach(v => { sendTo(v, { type: "stream_started" }); }); | |
| viewers.forEach(v => sendTo(streamerWs, { type: "new_viewer", vid: v._vid })); | |
| break; | |
| case "end_live": | |
| if (ws.role !== "streamer") return; | |
| isLive = false; | |
| viewers.forEach(v => sendTo(v, { type: "stream_ended" })); | |
| break; | |
| case "offer": | |
| if (ws.role !== "streamer") return; | |
| viewers.forEach(v => { if (v._vid === msg.vid) sendTo(v, { type: "offer", sdp: msg.sdp }); }); | |
| break; | |
| case "answer": | |
| sendTo(streamerWs, { type: "answer", sdp: msg.sdp, vid: ws._vid }); | |
| break; | |
| case "candidate": | |
| if (ws.role === "streamer") { | |
| viewers.forEach(v => { if (v._vid === msg.vid) sendTo(v, { type: "candidate", candidate: msg.candidate }); }); | |
| } else { | |
| sendTo(streamerWs, { type: "candidate", candidate: msg.candidate, vid: ws._vid }); | |
| } | |
| break; | |
| case "viewer_ready": | |
| ws._vid = msg.vid || ws._vid; | |
| sendTo(streamerWs, { type: "new_viewer", vid: ws._vid }); | |
| break; | |
| } | |
| }); | |
| ws.on("close", () => { | |
| if (ws.role === "streamer") { | |
| streamerWs = null; isLive = false; | |
| viewers.forEach(v => sendTo(v, { type: "stream_ended" })); | |
| } else if (ws.role === "viewer") { | |
| viewers.delete(ws); | |
| sendTo(streamerWs, { type: "viewer_count", count: viewers.size }); | |
| } | |
| }); | |
| }); | |
| httpServer.listen(PORT, () => console.log(`Running on port ${PORT}`)); | |