diff --git a/public/app.js b/public/app.js index fb2d00f..62b0f85 100644 --- a/public/app.js +++ b/public/app.js @@ -1783,10 +1783,14 @@ renderCanvas.height = targetHeight; const renderCtx = renderCanvas.getContext('2d', { alpha: true, willReadFrequently: true }); - // Determine Bitrate based on Resolution - let videoBitrate = 25_000_000; // 25 Mbps default for 1080p - if (targetWidth >= 3840) videoBitrate = 65_000_000; // 65 Mbps for 4K - else if (targetWidth <= 1280) videoBitrate = 14_000_000; + // Determine Bitrate based on Resolution & Mode + let videoBitrate = 20_000_000; // 20 Mbps default + if (options && options.returnBlobOnly) { + videoBitrate = (targetWidth >= 3840) ? 35_000_000 : (targetWidth <= 1280 ? 8_000_000 : 14_000_000); + } else { + if (targetWidth >= 3840) videoBitrate = 50_000_000; + else if (targetWidth <= 1280) videoBitrate = 10_000_000; + } // Verify WebCodecs support const hasWebCodecs = (typeof VideoEncoder !== 'undefined' && typeof VideoFrame !== 'undefined'); @@ -2160,6 +2164,9 @@ } } else { let errMsg = `Server antwortete mit Status ${xhr.status}`; + if (xhr.status === 408) { + errMsg = 'Server Timeout (408): Die Verbindung zum Server wurde unterbrochen. Bitte stelle sicher, dass der Server mit den neuesten Updates läuft oder wähle "WebM VP9 Alpha" für direkten 120 FPS Export ohne Server-Upload.'; + } try { const errData = JSON.parse(xhr.responseText); if (errData.error) errMsg = errData.error; diff --git a/server.mjs b/server.mjs index 53e3622..39857eb 100644 --- a/server.mjs +++ b/server.mjs @@ -60,6 +60,14 @@ const upload = multer({ }); app.use(cors()); + +// Disable request timeouts for large media uploads and FFmpeg transcoding +app.use((req, res, next) => { + req.setTimeout(0); + res.setTimeout(0); + next(); +}); + app.use(express.json({ limit: '50mb' })); app.use(express.urlencoded({ extended: true, limit: '50mb' })); app.use(express.static(path.join(__dirname, 'public'))); @@ -468,8 +476,8 @@ app.post('/api/export/cancel/:id', (req, res) => { res.json({ status: 'cancelled' }); }); -// Start Server -app.listen(PORT, '0.0.0.0', () => { +// Start Server with infinite timeouts for large file uploads & transcoding +const server = app.listen(PORT, '0.0.0.0', () => { console.log(` ╔═══════════════════════════════════════════════════════════════╗ ║ ORFEL VIZ ║ @@ -479,3 +487,9 @@ app.listen(PORT, '0.0.0.0', () => { ╚═══════════════════════════════════════════════════════════════╝ `); }); + +// Configure Node.js HTTP Server timeouts (prevents HTTP 408 Request Timeout during uploads) +server.timeout = 0; // Disable socket inactivity timeout +server.keepAliveTimeout = 1800000; // 30 minutes +server.headersTimeout = 1860000; // 31 minutes (must exceed keepAliveTimeout) +server.requestTimeout = 0; // 0 disables request timeout in Node.js 18+