UNPKG

@remotion/renderer

Version:

Render Remotion videos using Node.js or Bun

142 lines (141 loc) 5.45 kB
"use strict"; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.serveStatic = void 0; const node_http_1 = __importDefault(require("node:http")); const get_port_1 = require("./get-port"); const offthread_video_server_1 = require("./offthread-video-server"); const port_config_1 = require("./port-config"); const serve_handler_1 = require("./serve-handler"); const serveStatic = async (path, options) => { const { listener: offthreadRequest, close: closeCompositor, compositor, } = (0, offthread_video_server_1.startOffthreadVideoServer)({ downloadMap: options.downloadMap, offthreadVideoThreads: options.offthreadVideoThreads, logLevel: options.logLevel, indent: options.indent, offthreadVideoCacheSizeInBytes: options.offthreadVideoCacheSizeInBytes, binariesDirectory: options.binariesDirectory, }); const connections = {}; const server = node_http_1.default.createServer((request, response) => { var _a; if ((_a = request.url) === null || _a === void 0 ? void 0 : _a.startsWith('/proxy')) { return offthreadRequest(request, response); } if (path === null) { response.writeHead(404); response.end('Server only supports /proxy'); return; } (0, serve_handler_1.serveHandler)(request, response, { public: path, }).catch(() => { if (!response.headersSent) { response.writeHead(500); } response.end('Error serving file'); }); }); server.on('connection', (conn) => { let key; // Bun 1.0.43 fails on this try { key = conn.remoteAddress + ':' + conn.remotePort; } catch (_a) { key = ':'; } connections[key] = conn; conn.on('close', () => { delete connections[key]; }); }); let selectedPort = null; const maxTries = 10; const portConfig = (0, port_config_1.getPortConfig)(options.forceIPv4); for (let i = 0; i < maxTries; i++) { let unlock = () => { }; try { selectedPort = await new Promise((resolve, reject) => { var _a; (0, get_port_1.getDesiredPort)({ desiredPort: (_a = options === null || options === void 0 ? void 0 : options.port) !== null && _a !== void 0 ? _a : undefined, from: 3000, to: 3100, hostsToTry: portConfig.hostsToTry, }) .then(({ port, unlockPort }) => { unlock = unlockPort; server.listen({ port, host: portConfig.host }); server.on('listening', () => { resolve(port); return unlock(); }); server.on('error', (err) => { unlock(); reject(err); }); }) .catch((err) => { unlock(); return reject(err); }); }); const destroyConnections = function () { for (const key in connections) connections[key].destroy(); }; const close = async () => { await Promise.all([ new Promise((resolve, reject) => { // compositor may have already quit before, // this is okay as we are in cleanup phase closeCompositor() .catch((err) => { if (err.message.includes('Compositor quit')) { resolve(); return; } reject(err); }) .finally(() => { resolve(); }); }), new Promise((resolve, reject) => { destroyConnections(); server.close((err) => { if (err) { if (err.code === 'ERR_SERVER_NOT_RUNNING') { return resolve(); } reject(err); } else { resolve(); } }); }), ]); }; return { port: selectedPort, close, compositor }; } catch (err) { if (!(err instanceof Error)) { throw err; } const codedError = err; if (codedError.code === 'EADDRINUSE') { // Already in use, try another port } else { throw err; } } } throw new Error(`Tried ${maxTries} times to find a free port. Giving up.`); }; exports.serveStatic = serveStatic;