Skip to main content
Glama

Scenario Word

by HyunJuHwan
BuildvideoTool.ts2.57 kB
import { MCPTool } from "mcp-framework"; import { z } from "zod"; import { exec } from "child_process"; import fs from "fs/promises"; import path from "path"; import { fileURLToPath } from "url"; import util from "util"; import { v4 as uuidv4 } from "uuid"; const execAsync = util.promisify(exec); const __filename = fileURLToPath(import.meta.url); const __dirname = path.dirname(__filename); interface BuildvideoInput { frame_folder: string; } class BuildVideoTool extends MCPTool<BuildvideoInput> { name = "buildVideo"; description = "Create an .mp4 video with 2 seconds per scene image using ffmpeg concat mode."; schema = { frame_folder: { type: z.string(), description: "Folder containing PNG scene images (e.g. scene-*.png)" } }; async execute({ frame_folder }: BuildvideoInput) { const folderPath = path.isAbsolute(frame_folder) ? frame_folder : path.resolve(__dirname, frame_folder); const sceneFiles = (await fs.readdir(folderPath)) .filter(f => f.endsWith(".png")) .sort(); // 정렬 중요 if (sceneFiles.length === 0) { throw new Error("No PNG images found in the folder."); } // Step 1: Generate file list with durations const listPath = path.join(__dirname, `filelist-${Date.now()}.txt`); let fileListContent = sceneFiles .map(f => `file '${path.join(folderPath, f).replace(/\\/g, "/")}'\nduration 2`) .join("\n"); // 마지막 컷은 duration 없이 한 번 더 삽입해야 정상 종료됨 const lastScene = sceneFiles[sceneFiles.length - 1]; fileListContent += `\nfile '${path.join(folderPath, lastScene).replace(/\\/g, "/")}'`; await fs.writeFile(listPath, fileListContent); // Step 2: ffmpeg 명령어 실행 const outputName = `video-${Date.now()}.mp4`; const outputPath = path.join(__dirname, "video", outputName); await fs.mkdir(path.dirname(outputPath), { recursive: true }); const command = `ffmpeg -y -f concat -safe 0 -i "${listPath}" -vsync vfr -pix_fmt yuv420p "${outputPath}"`; try { const { stderr } = await execAsync(command); if (stderr) console.warn("[ffmpeg warning]", stderr); } catch (err: any) { throw new Error(`ffmpeg execution failed: ${err.message}`); } // Step 3: Clean up and return result await fs.unlink(listPath); return { video_url: outputPath, frame_count: sceneFiles.length, duration_per_frame: 2, total_duration: sceneFiles.length * 2, format: "mp4" }; } } export default BuildVideoTool;

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/HyunJuHwan/mcp-server'

If you have feedback or need assistance with the MCP directory API, please join our Discord server