@remotion/renderer
Version:
Render Remotion videos using Node.js or Bun
142 lines (141 loc) • 5.45 kB
JavaScript
;
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;