"use strict"; var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { if (k2 === undefined) k2 = k; var desc = Object.getOwnPropertyDescriptor(m, k); if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { desc = { enumerable: true, get: function() { return m[k]; } }; } Object.defineProperty(o, k2, desc); }) : (function(o, m, k, k2) { if (k2 === undefined) k2 = k; o[k2] = m[k]; })); var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { Object.defineProperty(o, "default", { enumerable: true, value: v }); }) : function(o, v) { o["default"] = v; }); var __importStar = (this && this.__importStar) || function (mod) { if (mod && mod.__esModule) return mod; var result = {}; if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k); __setModuleDefault(result, mod); return result; }; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); require("dotenv/config"); const db_1 = __importDefault(require("./config/db")); const express_1 = __importStar(require("express")); const cors_1 = __importDefault(require("cors")); const os_1 = __importStar(require("os")); const util_1 = __importDefault(require("util")); const child_process_1 = require("child_process"); const tree_kill_1 = __importDefault(require("tree-kill")); const SessionServer_1 = __importDefault(require("./models/SessionServer")); const ActiveSession_1 = __importDefault(require("./models/ActiveSession")); (0, db_1.default)(); const app = (0, express_1.default)(); const port = process.env.PORT; app.use((0, express_1.json)()); app.use((0, cors_1.default)()); const serverLocation = process.env.SERVER_LOCATION; const serverName = process.env.SERVER_NAME; const serverType = process.env.SERVER_TYPE; const serverHostname = os_1.default.hostname(); const nets = (0, os_1.networkInterfaces)(); const localIP = Object.entries(nets) .find((net) => net[0] === "Ethernet")?.[1] ?.find((obj) => obj.family === "IPv4")?.address; async function updateSessionServerData(data) { try { await SessionServer_1.default.findOneAndUpdate({ hostname: serverHostname }, data); } catch (error) { if (error instanceof Error) { console.log("Error: ", error.message); } } } const execAsync = util_1.default.promisify(child_process_1.exec); async function getGpuMemoryFree() { try { const { stdout } = await execAsync("nvidia-smi --query-gpu=memory.free --format=csv,noheader,nounits", { windowsHide: true }); const gpuMemoryFree = stdout.trimEnd(); await updateSessionServerData({ gpuMemoryFree }); } catch (error) { if (error instanceof Error) { console.log("Error: ", error.message); } } setTimeout(async () => { await getGpuMemoryFree(); }, 1000); } async function getAvailablePorts() { const cirrusPorts = [14000, 14001, 14002]; for (const cirrusPort of cirrusPorts) { const activeSession = await ActiveSession_1.default.exists({ location: serverLocation, name: serverName, cirrusPort, }); if (activeSession) continue; const uePort = cirrusPort + 10; return { cirrusPort, uePort }; } } async function startSession(buildName, ownerIp, endAt) { const filePath = `C:/pixel-streaming/builds/${buildName}/${buildName}.exe`; const availablePorts = await getAvailablePorts(); if (!availablePorts) { console.log("No available ports"); return; } const { cirrusPort, uePort } = availablePorts; const cirrusProcess = (0, child_process_1.execFile)("node", [ `C:/pixel-streaming/signalling-server/cirrus.js`, `--StreamerPort`, `${uePort}`, `--HttpPort`, `${cirrusPort}`, ]); const cirrusProcessId = cirrusProcess.pid; if (!cirrusProcessId) { console.log("Cirrus server was not started"); return; } const ueProcess = (0, child_process_1.execFile)(filePath, [ "-PixelStreamingIP=127.0.0.1", `-PixelStreamingPort=${uePort}`, "-RenderOffScreen", "-ForceRes", "-ResX=1920", "-ResY=1080", "-Unattended", "-PixelStreamingWebRTCMinBitrate=5000000", "-PixelStreamingWebRTCMaxBitrate=20000000", "-PixelStreamingH264Profile=HIGH", "-PixelStreamingWebRTCDisableReceiveAudio=true", "-PixelStreamingEncoderRateControl=VBR", // "-PixelStreamingHudStats=true", // `-SessionID=${session.id}`, ]); const ueProcessId = ueProcess.pid; if (!ueProcessId) { console.log("UE application was not started"); return; } const type = serverType; try { const activeSession = await ActiveSession_1.default.create({ location: serverLocation, name: serverName, buildName, type, cirrusPort, uePort, cirrusProcessId, ueProcessId, ownerIp, endAt, localIP, }); return activeSession; } catch (error) { (0, tree_kill_1.default)(cirrusProcessId); (0, tree_kill_1.default)(ueProcessId); console.log(error.message); } } async function endSession(activeSessionId) { try { const activeSession = await ActiveSession_1.default.findByIdAndDelete(activeSessionId); if (!activeSession) { console.log("Session with this ID not found"); return; } (0, tree_kill_1.default)(activeSession.cirrusProcessId); (0, tree_kill_1.default)(activeSession.ueProcessId); console.log("Kill session"); } catch (error) { console.log(error.message); } } async function init() { try { await SessionServer_1.default.findOneAndUpdate({ hostname: serverHostname }, { location: serverLocation, name: serverName, type: serverType, hostname: serverHostname, localIP, }, { upsert: true, new: true }); getGpuMemoryFree(); } catch (error) { if (error instanceof Error) { console.log("Error: ", error.message); } } } app.post("/start", async (req, res) => { for (const [key, value] of Object.entries(req.body)) { if (value === "null") req.body[key] = undefined; } const { buildName, ownerIp, endAt } = req.body; console.log("req.body", req.body); if (!buildName || !ownerIp) { return res.json({ error: 1 }); } const activeSession = await startSession(buildName, ownerIp, endAt); res.json(activeSession); }); app.post("/end", async (req, res) => { const activeSessionId = req.body.activeSessionId; if (!activeSessionId) { return res.json({ error: 1 }); } await endSession(activeSessionId); res.json({ ok: 1 }); }); app.listen(port, () => { console.log(`Server is listening on port ${port}`); init(); });