extract_frames
Extract frames from a video into sequential image files, allowing precise control over frame rate, start time, duration, and output format for efficient video analysis or processing.
Instructions
Extract frames from a video as sequential image files
Input Schema
TableJSON Schema
| Name | Required | Description | Default |
|---|---|---|---|
| duration | No | Duration to extract frames (format: HH:MM:SS.mmm or seconds) | |
| format | No | Output image format (jpg, png, etc., default: jpg) | |
| frameRate | No | Frame extraction rate (e.g., '1' for every frame, '0.5' for every 2nd frame, '1/30' for 1 frame per 30 seconds) | |
| inputPath | Yes | Path to the input video file | |
| outputDir | No | Directory to save the extracted frames (default: 'output') | |
| quality | No | Image quality for jpg format (1-100, default: 95) | |
| startTime | No | Start time to begin extraction (format: HH:MM:SS.mmm or seconds) |
Implementation Reference
- src/tools/handlers.ts:188-240 (handler)The main handler function for the 'extract_frames' tool. It validates inputs, constructs an FFmpeg command to extract frames at specified rate and quality into a directory, and returns the result.case "extract_frames": { const inputPath = validatePath(String(args?.inputPath), true); const outputDir = String(args?.outputDir || "output"); const frameRate = String(args?.frameRate || "1"); const format = String(args?.format || "jpg"); const quality = Number(args?.quality || 95); const startTime = args?.startTime ? String(args?.startTime) : ""; const duration = args?.duration ? String(args?.duration) : ""; // Create output directory if it doesn't exist await ensureDirectoryExists(join(outputDir, "dummy.txt")); // Build the FFmpeg command let command = `-i "${inputPath}"`; // Add start time if provided if (startTime) { command += ` -ss ${startTime}`; } // Add duration if provided if (duration) { command += ` -t ${duration}`; } // Set frame extraction rate command += ` -vf "fps=${frameRate}"`; // Set quality based on format if (format.toLowerCase() === "jpg" || format.toLowerCase() === "jpeg") { // For JPEG, use a better quality setting (lower values = higher quality in FFmpeg's scale) // Convert 1-100 scale to FFmpeg's 1-31 scale (inverted, where 1 is best quality) const ffmpegQuality = Math.max(1, Math.min(31, Math.round(31 - ((quality / 100) * 30)))); command += ` -q:v ${ffmpegQuality}`; } else if (format.toLowerCase() === "png") { // For PNG, use compression level (0-9, where 0 is no compression) const compressionLevel = Math.min(9, Math.max(0, Math.round(9 - ((quality / 100) * 9)))); command += ` -compression_level ${compressionLevel}`; } // Set output pattern with 5-digit numbering const outputPattern = join(outputDir, `%05d.${format}`); command += ` "${outputPattern}" -y`; const result = await runFFmpegCommand(command); return { content: [{ type: "text", text: `Frames extracted from video: ${inputPath} → ${outputDir}/*.${format}\n\n${result}` }] }; }
- src/tools/definitions.ts:192-229 (schema)The input schema definition for the 'extract_frames' tool, including parameters for input video path, output directory, frame rate, format, quality, start time, and duration.{ name: "extract_frames", description: "Extract frames from a video as sequential image files", inputSchema: { type: "object", properties: { inputPath: { type: "string", description: "Path to the input video file" }, outputDir: { type: "string", description: "Directory to save the extracted frames (default: 'output')" }, frameRate: { type: "string", description: "Frame extraction rate (e.g., '1' for every frame, '0.5' for every 2nd frame, '1/30' for 1 frame per 30 seconds)" }, format: { type: "string", description: "Output image format (jpg, png, etc., default: jpg)" }, quality: { type: "number", description: "Image quality for jpg format (1-100, default: 95)" }, startTime: { type: "string", description: "Start time to begin extraction (format: HH:MM:SS.mmm or seconds)" }, duration: { type: "string", description: "Duration to extract frames (format: HH:MM:SS.mmm or seconds)" } }, required: ["inputPath"] } }