MP4 on Hetz
Deploy / deploy (push) Successful in 2m42s

This commit is contained in:
twotalesanimation
2026-07-16 23:26:12 +02:00
parent 96c0f2b84f
commit 3494c9a2b3
+21 -7
View File
@@ -45,17 +45,31 @@ export async function GET(
return new NextResponse("Forbidden", { status: 403 }); return new NextResponse("Forbidden", { status: 403 });
} }
// ── Local disk first, Hetzner fallback ─────────────────────────────────── // ── Storage routing ───────────────────────────────────────────────────────
// Serve from local disk if the file exists there (covers unmigrated files). // Videos: check Hetzner first — bypasses ISP throttling for large streams.
// If not found locally, redirect to Hetzner object storage. // Fallback to local disk if the file hasn't been migrated yet.
// Note: "Hetzner first" was attempted but caused 400s from Hetzner on // Images / other assets: local disk only — avoids presigned-URL 400 errors
// presigned URLs — likely a bucket policy/CORS issue to investigate // seen on Hetzner for non-video content.
// separately before re-enabling that path. const videoExts = new Set([".mp4", ".mov", ".avi", ".mxf", ".webm"]);
const isVideo = videoExts.has(path.extname(relativePath).toLowerCase());
if (isVideo) {
try {
if (await hetznerKeyExists(relativePath)) {
const hetznerUrl = await generateHetznerStreamUrl(relativePath, 3600);
return NextResponse.redirect(hetznerUrl, 302);
}
} catch {
// Hetzner unavailable — fall through to local disk
}
}
// Local disk (all non-video files, and video files not yet on Hetzner)
let stat: fs.Stats; let stat: fs.Stats;
try { try {
stat = fs.statSync(filePath); stat = fs.statSync(filePath);
} catch { } catch {
// Not on local disk — try Hetzner // Not on local disk and not a video served above — try Hetzner as last resort
try { try {
const hetznerUrl = await generateHetznerStreamUrl(relativePath, 3600); const hetznerUrl = await generateHetznerStreamUrl(relativePath, 3600);
return NextResponse.redirect(hetznerUrl, 302); return NextResponse.redirect(hetznerUrl, 302);