Current Behavior:
I’m using FFmpeg on Vercel to concatenate multiple videos into one file, saving the output to the /tmp directory. After the concatenation, I attempt to upload the output file to my Amazon S3 bucket. However, the file does not appear to exist in /tmp when I try to fetch it for the upload.
Here’s the flow I’m using:
- Download Videos: Videos are downloaded to
/tmpusing custom utility functions. - Process Videos: The videos are processed (e.g., padding, adding silent audio).
- Concatenate Videos: FFmpeg concatenates the processed videos into a single output file, saved to
/tmp. - Upload File: I attempt to fetch the file from
/tmpand upload it to Amazon S3.
Problem:
The fetch call to retrieve the file from /tmp fails, stating that the file cannot be found. This issue only occurs on Vercel. Locally, the process works as expected.
Expected Behavior:
The file created by FFmpeg in /tmp should be accessible for further processing and uploading to Amazon S3.
Code and Configuration:
Here’s the relevant portion of my code:
API Route (/api/assemble-videos):
export async function POST(req: Request) { const TEMP_DIR = "/tmp"; const OUTPUT_DIR = "/tmp"; // Output directory is set to /tmp for Vercel. try { const { videos } = await req.json(); if (!videos || videos.length < 2) { return new Response(JSON.stringify({ error: "At least two videos are required." }), { status: 400 }); } // Step 1: Download videos const downloadedPaths = await Promise.all( videos.map((url, idx) => downloadFile(url, TEMP_DIR, `video-${idx}.mp4`)) ); // Step 2: Process videos (pad, add silent audio if necessary) const processedPaths = await Promise.all( downloadedPaths.map(async (file) => { // Processing logic return file; }) ); // Step 3: Concatenate videos const outputFileName = `output.mp4`; const outputFilePath = path.join(OUTPUT_DIR, outputFileName); await concatenateVideos(processedPaths, outputFilePath); // Step 4: Return file path return new Response(JSON.stringify({ path: outputFilePath }), { status: 200 }); } catch (error) { console.error("Error assembling videos:", error); return new Response(JSON.stringify({ error: "Failed to assemble videos." }), { status: 500 }); }}Client-Side Fetch Logic:
const response = await fetch("/api/assemble-videos", { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify({ videos: videoUrls }),});if (!response.ok) { console.error("API Error Response:", await response.text()); throw new Error("API Error");}const { path } = await response.json();const videoResponse = await fetch(path); // Fails here, unable to find the file.const blob = await videoResponse.blob();const file = new File([blob], "output.mp4", { type: "video/mp4" });Environment Details:
- Hosting Platform: Vercel
- Framework: Next.js
- Video Processing Library: FFmpeg (via
fluent-ffmpeg) - S3 Upload Tool: AWS SDK
Request for Help:
- Is there a specific limitation or configuration on Vercel that could prevent files from being written or read in
/tmp? - Are there alternative approaches for handling temporary files during video processing on Vercel?
- Any recommended way to directly stream FFmpeg output to S3 without relying on
/tmp?
Thank you in advance for your help!