import { promises as fs, existsSync } from "node:fs"; import os from "node:os"; import path from "node:path"; import ffmpeg from "fluent-ffmpeg"; import { v4 as uuidv4 } from "uuid"; type AddImageToVideoParams = { inputVideoPath: string; inputImagePath: string; outputVideoPath?: string; }; export async function addImageToVideo({ inputVideoPath, inputImagePath, outputVideoPath, }: AddImageToVideoParams): Promise { // Verify that the input files exist if (!existsSync(inputVideoPath)) { throw new Error(`Input video file does not exist: ${inputVideoPath}`); } if (!existsSync(inputImagePath)) { throw new Error(`Input image file does not exist: ${inputImagePath}`); } // If no output path is provided, create a temporary file for output if (!outputVideoPath) { const tempDir = await fs.mkdtemp(path.join(os.tmpdir(), uuidv4())); outputVideoPath = path.join(tempDir, `${uuidv4()}.mp4`); } // Return a promise that resolves with the path to the output video return new Promise((resolve, reject) => { ffmpeg(inputVideoPath) .input(inputImagePath) .complexFilter([ { filter: "overlay", options: { x: "0", y: "0" }, // Overlay on the entire video frame } ]) .on("error", (err) => { reject(new Error(`Error processing video: ${err.message}`)); }) .on("end", () => { resolve(outputVideoPath); }) .save(outputVideoPath); }); }