### Quick Start: Create a Video Project with simple-ffmpegjs Source: https://www.simple-ffmpegjs.com/llms.txt A quick start guide showing how to initialize a SIMPLEFFMPEG project, load various media assets (video clips, text overlays, music), and define transitions and animations. It also includes exporting the final video with progress monitoring. ```javascript import SIMPLEFFMPEG from "simple-ffmpegjs"; // Use a platform preset — or set width/height/fps manually const project = new SIMPLEFFMPEG({ preset: "youtube" }); await project.load([ // Two video clips with a crossfade transition between them { type: "video", url: "./opening-shot.mp4", position: 0, end: 6 }, { type: "video", url: "./highlights.mp4", position: 5.5, end: 18, cutFrom: 3, // start 3s into the source file transition: { type: "fade", duration: 0.5 }, }, // Title card with a pop animation { type: "text", text: "Summer Highlights 2025", position: 0.5, end: 4, fontFile: "./fonts/Montserrat-Bold.ttf", fontSize: 72, fontColor: "#FFFFFF", borderColor: "#000000", borderWidth: 2, xPercent: 0.5, yPercent: 0.4, animation: { type: "pop", in: 0.3 }, }, // Background music — loops to fill the whole video { type: "music", url: "./chill-beat.mp3", volume: 0.2, loop: true }, ]); await project.export({ outputPath: "./summer-highlights.mp4", onProgress: ({ percent }) => console.log(`${percent}% complete`), }); ``` -------------------------------- ### Install FFmpeg Dependencies for Text Overlays Source: https://www.simple-ffmpegjs.com/llms.txt Instructions for installing necessary FFmpeg build components like libfreetype and fontconfig, essential for rendering text and emoji in video overlays. Includes package installation commands for Alpine and Debian/Ubuntu systems. ```bash # Alpine apk add --no-cache ffmpeg fontconfig ttf-dejavu # Debian/Ubuntu apt-get install -y ffmpeg fontconfig fonts-dejavu-core ``` -------------------------------- ### Load Project with Looping Music Source: https://www.simple-ffmpegjs.com/llms.txt Example of loading a project configuration that includes a video track and a looping background music track. ```typescript await project.load([ { type: "video", url: "./video.mp4", position: 0, end: 120 }, { type: "music", url: "./30s-track.mp3", volume: 0.3, loop: true }, ]); ``` -------------------------------- ### Configure Custom Instructions Source: https://www.simple-ffmpegjs.com/llms.txt Shows how to inject custom instructions into the schema at both the global and module-specific levels to guide the video generation process. ```javascript const schema = SIMPLEFFMPEG.getSchema({ include: ["video", "image", "music"], instructions: [ "You are creating short cooking tutorials for TikTok.", "Keep all videos under 30 seconds.", ], moduleInstructions: { video: [ "Always use fade transitions at 0.5s.", "Limit to 5 clips maximum.", ], music: "Always include background music at volume 0.15.", }, }); ``` -------------------------------- ### Configure Clips and Transitions Source: https://www.simple-ffmpegjs.com/llms.txt Examples of loading media clips into a project, including sequential placement, crossfade transitions, and image slideshows with Ken Burns effects. ```typescript await project.load([ { type: "video", url: "./a.mp4", position: 0, end: 5 }, { type: "video", url: "./b.mp4", position: 5, end: 10, transition: { type: "fade", duration: 0.5 }, }, ]); await project.load([ { type: "image", url: "./photo1.jpg", duration: 3, kenBurns: "zoom-in" }, { type: "image", url: "./photo2.jpg", duration: 3, kenBurns: "pan-right" }, { type: "image", url: "./photo3.jpg", duration: 3, kenBurns: "zoom-out" }, { type: "music", url: "./music.mp3", volume: 0.3 }, ]); await project.load([ { type: "image", url: "./portrait.jpg", duration: 5, kenBurns: { type: "smart", anchor: "bottom", startZoom: 1.05, endZoom: 1.2, easing: "ease-in-out", }, }, { type: "image", url: "./wide.jpg", duration: 4, kenBurns: { type: "custom", startX: 0.15, startY: 0.7, endX: 0.85, endY: 0.2, easing: "ease-in-out", }, }, ]); ``` -------------------------------- ### Compose Timeline with Transitions Source: https://www.simple-ffmpegjs.com/llms.txt Example of loading a project timeline with color clips, video clips, and text overlays using fade transitions. ```typescript await project.load([ { type: "color", color: "black", position: 0, end: 3 }, { type: "video", url: "./main.mp4", position: 3, end: 8, transition: { type: "fade", duration: 0.5 } }, { type: "color", color: { type: "radial-gradient", colors: ["#2c3e50", "#000000"] }, position: 8, end: 11, transition: { type: "fade", duration: 0.5 } }, { type: "text", text: "The End", position: 8.5, end: 10.5, fontSize: 64, fontColor: "white" } ]); ``` -------------------------------- ### AI Video Generation Pipeline Source: https://www.simple-ffmpegjs.com/llms.txt This example demonstrates how to build an AI-driven video generation pipeline. It includes setting up the AI schema, interacting with an LLM, and implementing a validation and retry loop for self-correction. ```APIDOC ## AI Video Generation Pipeline Example This example demonstrates a complete AI-driven video generation pipeline. It combines schema export, validation, and structured error codes to enable an AI model to generate and self-correct video clip configurations. ### Key Components 1. **Schema Definition**: Define the structure and constraints for the AI's output using `SIMPLEFFMPEG.getSchema()`. 2. **LLM Integration**: Send the schema and user prompt to a Large Language Model (LLM) to generate video clip data. 3. **Validation and Retry Loop**: Validate the AI's output against the schema. If validation fails, feed the errors back to the AI for self-correction. 4. **Media Path Verification**: Ensure the AI only uses provided media files. 5. **Project Build and Export**: Load the validated clips into a `simple-ffmpegjs` project and export the final video. ### Code Breakdown #### 1. Build the schema context for the AI ```javascript import SIMPLEFFMPEG from "simple-ffmpegjs"; const schema = SIMPLEFFMPEG.getSchema({ include: ["video", "image", "text", "music"], instructions: [ "You are composing a short-form video for TikTok.", "Keep total duration under 30 seconds.", "Return ONLY valid JSON — an array of clip objects.", ], moduleInstructions: { video: "Use fade transitions between clips. Keep each clip 3-6 seconds.", text: [ "Add a title in the first 2 seconds with fontSize 72.", "Use white text with a black border for readability.", ], music: "Always include looping background music at volume 0.15.", }, }); ``` **Description**: This section initializes the AI's working schema. It specifies the types of clips the AI can generate (`video`, `image`, `text`, `music`) and provides high-level instructions for video composition, duration, and output format. It also includes specific instructions for different module types like `video`, `text`, and `music`. #### 2. Send the schema + prompt to your LLM ```javascript async function askAI(systemPrompt, userPrompt) { // Replace with your LLM provider (OpenAI, Anthropic, etc.) const response = await llm.chat({ messages: [ { role: "system", content: systemPrompt }, { role: "user", content: userPrompt }, ], }); return JSON.parse(response.content); } ``` **Description**: This function abstracts the interaction with a generic LLM. It takes a system prompt (containing the schema and context) and a user prompt, then returns the parsed JSON response from the LLM. #### 3. Generate → Validate → Retry loop ```javascript async function generateVideo(userPrompt, media) { const mediaList = media .map((m) => ` - ${m.file} (${m.duration}s) — ${m.description}`) .join("\n"); const systemPrompt = [ "You are a video editor. Given the user's request and the available media,", "produce a clips array that follows this schema:\n", schema, "\nAvailable media (use these exact file paths):", mediaList, ].join("\n"); const knownPaths = media.map((m) => m.file); // First attempt let clips = await askAI(systemPrompt, userPrompt); let result = SIMPLEFFMPEG.validate(clips, { skipFileChecks: true }); let attempts = 1; // Self-correction loop: feed structured errors back to the AI while (!result.valid && attempts < 3) { const errorFeedback = result.errors .map((e) => `[${e.code}] ${e.path}: ${e.message}`) .join("\n"); clips = await askAI( systemPrompt, [ `Your previous output had validation errors:\n${errorFeedback}`, `\nOriginal request: ${userPrompt}`, "\nPlease fix the errors and return the corrected clips array.", ].join("\n"), ); result = SIMPLEFFMPEG.validate(clips, { skipFileChecks: true }); attempts++; } if (!result.valid) { throw new Error( `Failed to generate valid config after ${attempts} attempts:\n` + SIMPLEFFMPEG.formatValidationResult(result), ); } // 4. Verify the AI only used known media paths const usedPaths = clips.filter((c) => c.url).map((c) => c.url); const unknownPaths = usedPaths.filter((p) => !knownPaths.includes(p)); if (unknownPaths.length > 0) { throw new Error(`AI used unknown media paths: ${unknownPaths.join(", ")}`); } // 5. Build and export const project = new SIMPLEFFMPEG({ preset: "tiktok" }); await project.load(clips); return project.export({ outputPath: "./output.mp4", onProgress: ({ percent }) => console.log(`Rendering: ${percent}%`), }); } ``` **Description**: This function orchestrates the video generation process. It constructs a detailed system prompt including the schema and available media. It then enters a loop: first, it asks the AI for clips, validates the output using `SIMPLEFFMPEG.validate()`. If validation fails, it provides detailed error feedback to the AI and retries up to 3 times. Finally, it verifies that only known media paths were used before loading the clips into a `simple-ffmpegjs` project and exporting the video. #### Usage Example ```javascript await generateVideo("Make a hype travel montage with upbeat text overlays", [ { file: "clips/beach-drone.mp4", duration: 4, description: "Aerial drone shot of a tropical beach with people playing volleyball", }, { file: "clips/city-timelapse.mp4", duration: 8, description: "Timelapse of a city skyline transitioning from day to night", }, { file: "clips/sunset.mp4", duration: 6, description: "Golden hour sunset over the ocean with gentle waves", }, { file: "music/upbeat-track.mp3", duration: 120, description: "Upbeat electronic track with a strong beat, good for montages", }, ]); ``` **Description**: This is an example of how to call the `generateVideo` function. It provides a user prompt requesting a travel montage and a list of available media files, each with its duration and a descriptive text to help the AI understand its content. ``` -------------------------------- ### Get simple-ffmpegjs Schema for Clip Types Source: https://www.simple-ffmpegjs.com/llms.txt Demonstrates how to retrieve the full schema definition for all clip types supported by the `load()` method in simple-ffmpegjs. This schema can be used for documentation generation, code generation, or providing context to LLMs. ```javascript // Get the full schema (all clip types) const schema = SIMPLEFFMPEG.getSchema(); console.log(schema); ``` -------------------------------- ### Access simple-ffmpegjs Validation Codes Source: https://www.simple-ffmpegjs.com/llms.txt Provides an example of how to access and use the `ValidationCodes` object from simple-ffmpegjs to programmatically check for specific validation errors, enabling custom error handling logic. ```javascript const { ValidationCodes } = SIMPLEFFMPEG; // Available codes: // INVALID_TYPE, MISSING_REQUIRED, INVALID_VALUE, INVALID_RANGE, // INVALID_TIMELINE, TIMELINE_GAP, FILE_NOT_FOUND, INVALID_FORMAT, // INVALID_WORD_TIMING, OUTSIDE_BOUNDS if (result.errors.some((e) => e.code === ValidationCodes.TIMELINE_GAP)) { // Handle gap-specific logic } ``` -------------------------------- ### Implement Ken Burns Effect with Image Fitting in FFmpeg.js Source: https://www.simple-ffmpegjs.com/llms.txt Shows how to combine the Ken Burns effect with different `imageFit` modes. This example illustrates Ken Burns zoom with a blurred background and Ken Burns pan with black bars, highlighting the need for source dimensions in certain configurations. ```typescript // Ken Burns zoom on contained image with blurred background { type: "image", url: "./landscape.jpg", duration: 5, width: 1920, height: 1080, kenBurns: "zoom-in", imageFit: "blur-fill", } // Ken Burns pan with black bars { type: "image", url: "./landscape.jpg", duration: 5, width: 1920, height: 1080, kenBurns: "pan-right", imageFit: "contain", } ``` -------------------------------- ### Initialize Project with Custom Settings Source: https://www.simple-ffmpegjs.com/llms.txt Demonstrates initializing a new SIMPLEFFMPEG project with custom temporary directories and global font configurations. ```typescript const project = new SIMPLEFFMPEG({ preset: "youtube", tempDir: "/mnt/fast-nvme/tmp", }); const projectWithFont = new SIMPLEFFMPEG({ preset: "tiktok", fontFile: "./fonts/Montserrat-Bold.ttf", }); await projectWithFont.load([ { type: "video", url: "intro.mp4", position: 0, end: 10 }, { type: "text", text: "Hello!", position: 1, end: 4, fontSize: 72 }, { type: "text", text: "Special", position: 5, end: 8, fontFile: "./fonts/Italic.otf" }, ]); ``` -------------------------------- ### Constructor - new SIMPLEFFMPEG() Source: https://www.simple-ffmpegjs.com/llms.txt Initializes a new project instance with configuration options for output dimensions, frame rate, presets, and file handling. ```APIDOC ## Constructor ### Description Initializes a new SIMPLEFFMPEG project instance with specific output settings and environment configurations. ### Method Constructor ### Parameters #### Request Body - **width** (number) - Optional - Output width (default: 1920) - **height** (number) - Optional - Output height (default: 1080) - **fps** (number) - Optional - Frame rate (default: 30) - **validationMode** ('warn' | 'strict') - Optional - Validation behavior (default: 'warn') - **preset** (string) - Optional - Platform preset (e.g., 'tiktok', 'youtube') - **fontFile** (string) - Optional - Default font file path - **tempDir** (string) - Optional - Custom directory for temporary files ### Request Example const project = new SIMPLEFFMPEG({ preset: "youtube", tempDir: "/tmp/ffmpeg" }); ``` -------------------------------- ### Calculate Timeline Duration Source: https://www.simple-ffmpegjs.com/llms.txt A pure function example to calculate the total duration of a clip sequence, accounting for transitions and overlaps without performing file I/O. ```typescript const clips = [ { type: "video", url: "./a.mp4", duration: 5 }, { type: "video", url: "./b.mp4", duration: 10, transition: { type: "fade", duration: 0.5 }, }, ]; SIMPLEFFMPEG.getDuration(clips); ``` -------------------------------- ### Configure Video Presets Source: https://www.simple-ffmpegjs.com/llms.txt Initialize a project with a platform preset and override specific settings like frame rate. You can also query available presets programmatically. ```typescript const project = new SIMPLEFFMPEG({ preset: "tiktok" }); const customProject = new SIMPLEFFMPEG({ preset: "tiktok", fps: 60 }); const names = SIMPLEFFMPEG.getPresetNames(); const presets = SIMPLEFFMPEG.getPresets(); ``` -------------------------------- ### Configure Video Export Settings Source: https://www.simple-ffmpegjs.com/llms.txt Demonstrates various export configurations for simple-ffmpeg, including high-quality H.265 encoding, hardware acceleration, two-pass encoding, audio-only exports, and thumbnail generation. ```typescript await project.export({ outputPath: "./output.mp4", videoCodec: "libx265", crf: 18, preset: "slow", audioCodec: "libopus", audioBitrate: "256k", metadata: { title: "My Video", artist: "My Name", date: "2025" } }); await project.export({ outputPath: "./output.mp4", hwaccel: "videotoolbox", videoCodec: "h264_videotoolbox" }); await project.export({ outputPath: "./output.mp4", twoPass: true, videoBitrate: "5M", preset: "slow" }); await project.export({ outputPath: "./720p.mp4", outputResolution: "720p" }); await project.export({ outputPath: "./audio.mp3", audioOnly: true, audioCodec: "libmp3lame", audioBitrate: "320k" }); await project.export({ outputPath: "./output.mp4", thumbnail: { outputPath: "./thumb.jpg", time: 5, width: 640 } }); await project.export({ outputPath: "./output.mp4", verbose: true, saveCommand: "./ffmpeg-command.txt" }); ``` -------------------------------- ### Generate Property Tour Videos with simple-ffmpeg.js Source: https://www.simple-ffmpegjs.com/llms.txt This JavaScript code snippet utilizes simple-ffmpeg.js to generate a property tour video. It takes listing data, creates an image slideshow with transitions and Ken Burns effects, adds text overlays for price and address, and includes background music. The function can then be used to batch generate videos for multiple listings. ```javascript import SIMPLEFFMPEG from "simple-ffmpegjs"; const listings = await db.getActiveListings(); // your data source async function generateListingVideo(listing, outputPath) { const photos = listing.photos; // ['kitchen.jpg', 'living-room.jpg', ...] const slideDuration = 4; // Build an image slideshow from listing photos (auto-sequenced with crossfades) const transitionDuration = 0.5; const photoClips = photos.map((photo, i) => ({ type: "image", url: photo, duration: slideDuration, kenBurns: i % 2 === 0 ? "zoom-in" : "pan-right", ...(i > 0 && { transition: { type: "fade", duration: transitionDuration }, }), })); const totalDuration = SIMPLEFFMPEG.getDuration(photoClips); const clips = [ ...photoClips, // Price banner { type: "text", text: listing.price, position: 0.5, end: totalDuration - 0.5, fontSize: 36, fontColor: "#FFFFFF", backgroundColor: "#000000", backgroundOpacity: 0.6, padding: 12, xPercent: 0.5, yPercent: 0.1, }, // Address at the bottom { type: "text", text: listing.address, position: 0.5, end: totalDuration - 0.5, fontSize: 28, fontColor: "#FFFFFF", borderColor: "#000000", borderWidth: 2, xPercent: 0.5, yPercent: 0.9, }, { type: "music", url: "./assets/ambient.mp3", volume: 0.15, loop: true }, ]; const project = new SIMPLEFFMPEG({ preset: "instagram-reel" }); await project.load(clips); return project.export({ outputPath }); } // Batch generate videos for all listings for (const listing of listings) { await generateListingVideo(listing, `./output/${listing.id}.mp4`); } ``` -------------------------------- ### Validate Clip Configurations with simple-ffmpegjs Source: https://www.simple-ffmpegjs.com/llms.txt Shows how to use the `SIMPLEFFMPEG.validate()` method to check clip configurations before project creation. This is useful for catching errors early in dynamic workflows, with options to skip file checks and specify project dimensions. ```javascript import SIMPLEFFMPEG from "simple-ffmpegjs"; const clips = [ { type: "video", url: "./intro.mp4", position: 0, end: 5 }, { type: "text", text: "Hello", position: 1, end: 4 }, ]; // Validate without creating a project const result = SIMPLEFFMPEG.validate(clips, { skipFileChecks: true, // Skip file existence checks (useful when files aren't on disk yet) width: 1920, // Project dimensions (for Ken Burns size validation) height: 1080, strictKenBurns: false, // If true, undersized Ken Burns images error instead of warn (default: false) }); if (!result.valid) { // Structured errors for programmatic handling result.errors.forEach((err) => { console.log(`[${err.code}] ${err.path}: ${err.message}`); // e.g. [MISSING_REQUIRED] clips[0].url: URL is required for media clips }); } // Or get human-readable output console.log(SIMPLEFFMPEG.formatValidationResult(result)); ``` -------------------------------- ### project.export(options) Source: https://www.simple-ffmpegjs.com/llms.txt Builds and executes the FFmpeg command to render the final video file. ```APIDOC ## POST project.export ### Description Build and execute the FFmpeg command to render the final video based on provided export options. ### Method POST ### Endpoint project.export(options) ### Parameters #### Request Body (ExportOptions) - **outputPath** (string) - Optional - Output file path (default: './output.mp4') - **videoCodec** (string) - Optional - Video codec (default: 'libx264') - **crf** (number) - Optional - Quality level 0-51 (default: 23) - **preset** (string) - Optional - Encoding preset (default: 'medium') - **videoBitrate** (string) - Optional - Target bitrate - **audioCodec** (string) - Optional - Audio codec (default: 'aac') - **audioBitrate** (string) - Optional - Audio bitrate (default: '192k') - **hwaccel** (string) - Optional - Hardware acceleration type - **outputWidth/Height** (number) - Optional - Scale dimensions - **audioOnly** (boolean) - Optional - Export audio only - **twoPass** (boolean) - Optional - Two-pass encoding ### Request Example { "outputPath": "./video.mp4", "videoCodec": "libx264", "crf": 20 } ### Response #### Success Response (200) - **result** (string) - The path or status of the rendered video file. ``` -------------------------------- ### Execute Manual Demo Scripts Source: https://www.simple-ffmpegjs.com/llms.txt Commands to run the demo suite for visual verification. Users can execute all demos at once or target specific features by passing arguments to the runner script. ```bash node examples/run-examples.js node examples/run-examples.js transitions node examples/run-examples.js torture ken ``` -------------------------------- ### Text Overlays and Animations Source: https://www.simple-ffmpegjs.com/llms.txt Demonstrates how to add static text, position it using percentages or pixels, and apply various text animations like fade-in, typewriter, and pulse. ```APIDOC ## Text Overlays ### Description Add centered text overlays to your video. Positioning can be controlled using `xPercent`/`yPercent` for percentage-based placement, `x`/`y` for pixel-based placement, or `xOffset`/`yOffset` for adjustments relative to the center. ### Method `project.load()` ### Endpoint N/A (Client-side library) ### Parameters #### Request Body - **type** (string) - Required - Must be "text" - **text** (string) - Required - The content of the text overlay - **position** (number) - Required - Start time of the text overlay - **end** (number) - Required - End time of the text overlay - **fontSize** (number) - Optional - Size of the font - **fontColor** (string) - Optional - Color of the font (e.g., "white", "#FFFFFF") - **yOffset** (number) - Optional - Nudges text vertically from the center - **xPercent** (number) - Optional - Horizontal position as a percentage (0-1) - **yPercent** (number) - Optional - Vertical position as a percentage (0-1) - **animation** (object) - Optional - Animation properties - **type** (string) - Required - Type of animation (e.g., "fade-in", "typewriter", "pulse") - **speed** (number) - Optional - Speed of the animation - **intensity** (number) - Optional - Intensity of the animation (for pulse) - **in** (number) - Optional - Duration of fade-in - **out** (number) - Optional - Duration of fade-out ### Request Example ```json { "type": "text", "text": "Main Title", "position": 0, "end": 5, "fontSize": 72, "yOffset": -100 } ``` ### Response N/A (Modifies video project) ## Word-by-Word Replacement ### Description Applies text overlays with word-by-word timing and animations, suitable for dynamic content or effects. ### Method `project.load()` ### Endpoint N/A (Client-side library) ### Parameters #### Request Body - **type** (string) - Required - Must be "text" - **mode** (string) - Required - Set to "word-replace" - **text** (string) - Required - The full text content - **position** (number) - Required - Start time - **end** (number) - Required - End time - **wordTimestamps** (array) - Required - Array of timestamps for each word - **animation** (object) - Optional - Animation properties (e.g., "fade-in") - **fontSize** (number) - Optional - Font size - **fontColor** (string) - Optional - Font color ### Request Example ```json { "type": "text", "mode": "word-replace", "text": "One Two Three Four", "position": 2, "end": 6, "wordTimestamps": [2, 3, 4, 5, 6], "animation": { "type": "fade-in", "in": 0.2 }, "fontSize": 72, "fontColor": "white" } ``` ### Response N/A ## Typewriter and Pulse Animations ### Description Applies typewriter and pulse animations to text overlays. ### Method `project.load()` ### Endpoint N/A (Client-side library) ### Parameters #### Request Body (Typewriter) - **type** (string) - "text" - **text** (string) - Text content - **position** (number) - Start time - **end** (number) - End time - **animation** (object) - {"type": "typewriter", "speed": number} #### Request Body (Pulse) - **type** (string) - "text" - **text** (string) - Text content - **position** (number) - Start time - **end** (number) - End time - **animation** (object) - {"type": "pulse", "speed": number, "intensity": number} ### Request Example (Typewriter) ```json { "type": "text", "text": "Appearing letter by letter...", "position": 1, "end": 4, "animation": { "type": "typewriter", "speed": 15 } } ``` ### Request Example (Pulse) ```json { "type": "text", "text": "Pulsing...", "position": 0.5, "end": 4.5, "animation": { "type": "pulse", "speed": 2, "intensity": 0.2 } } ``` ### Response N/A ``` -------------------------------- ### POST /project/export Source: https://www.simple-ffmpegjs.com/llms.txt Exports the current project configuration to a video file. Supports cancellation via AbortController. ```APIDOC ## POST /project/export ### Description Exports the project to a specified output path. The operation can be cancelled using an AbortController signal. ### Method POST ### Endpoint /project/export ### Parameters #### Request Body - **outputPath** (string) - Required - The destination file path for the exported video. - **signal** (AbortSignal) - Optional - An AbortSignal to cancel the export process. ### Request Example { "outputPath": "./out.mp4" } ### Response #### Success Response (200) - **status** (string) - Indicates successful completion of the export. #### Error Handling - **ValidationError**: Thrown for invalid clip configurations. - **FFmpegError**: Thrown if the underlying FFmpeg command fails. - **MediaNotFoundError**: Thrown if a source file cannot be located. - **ExportCancelledError**: Thrown if the operation is aborted by the user. ``` -------------------------------- ### POST /project/load Source: https://www.simple-ffmpegjs.com/llms.txt Loads media clips and overlays into the project timeline, supporting transitions and automatic timing compensation. ```APIDOC ## POST /project/load ### Description Loads an array of media objects into the project. Handles clip positioning and transition logic automatically. ### Method POST ### Endpoint /project/load ### Parameters #### Request Body - **clips** (array) - Required - List of media objects (video, text, etc.) with position and end times. ### Request Example [ { "type": "video", "url": "./a.mp4", "position": 0, "end": 10 }, { "type": "text", "text": "Hello", "position": 15, "end": 18 } ] ### Response #### Success Response (200) - **status** (string) - Success message indicating project load completion. ``` -------------------------------- ### project.preview(options) Source: https://www.simple-ffmpegjs.com/llms.txt Generates the FFmpeg command string without executing it, useful for debugging. ```APIDOC ## GET project.preview ### Description Get the FFmpeg command without executing it. Useful for debugging or dry runs. ### Method GET ### Endpoint project.preview(options) ### Response #### Success Response (200) - **command** (string) - The full FFmpeg command string - **filterComplex** (string) - The generated filter graph - **totalDuration** (number) - Expected output duration in seconds ### Response Example { "command": "ffmpeg -i input.mp4 ...", "filterComplex": "[0:v]scale=1920:1080...", "totalDuration": 30.5 } ``` -------------------------------- ### Apply Image Fitting Modes in FFmpeg.js Source: https://www.simple-ffmpegjs.com/llms.txt Demonstrates how to use the `imageFit` property to control how an image's aspect ratio is handled when it differs from the output video's aspect ratio. Options include 'cover', 'contain', and 'blur-fill'. ```typescript // Landscape photo in a portrait video — blurred background fills the bars (default) { type: "image", url: "./landscape.jpg", duration: 5 } // Explicit cover — crops to fill the frame { type: "image", url: "./landscape.jpg", duration: 5, imageFit: "cover" } // Black bars (letterbox/pillarbox) { type: "image", url: "./landscape.jpg", duration: 5, imageFit: "contain" } // Stronger blur effect { type: "image", url: "./landscape.jpg", duration: 5, imageFit: "blur-fill", blurIntensity: 70 } ``` -------------------------------- ### Auto-Sequencing & Duration Shorthand Source: https://www.simple-ffmpegjs.com/llms.txt Demonstrates how to use `duration` instead of `end` and omit `position` for automatic clip sequencing, simplifying timeline creation. ```APIDOC ## Auto-Sequencing & Duration Shorthand For video, image, and audio clips, you can use shorthand to avoid specifying explicit `position` and `end` values: - **`duration`** — Use instead of `end`. The library computes `end = position + duration`. You cannot specify both `duration` and `end` on the same clip. - **Omit `position`** — The clip is placed immediately after the previous clip on its track. Video and image clips share the visual track; audio clips have their own track. The first clip defaults to `position: 0`. These can be combined: ```ts // Before: manual position/end for every clip await project.load([ { type: "video", url: "./a.mp4", position: 0, end: 5 }, { type: "video", url: "./b.mp4", position: 5, end: 10 }, { type: "video", url: "./c.mp4", position: 10, end: 18, cutFrom: 3 }, ]); // After: auto-sequencing + duration await project.load([ { type: "video", url: "./a.mp4", duration: 5 }, { type: "video", url: "./b.mp4", duration: 5 }, { type: "video", url: "./c.mp4", duration: 8, cutFrom: 3 }, ]); ``` You can mix explicit and implicit positioning freely. Clips with explicit `position` are placed there; subsequent auto-sequenced clips follow from the last clip's end: ```ts await project.load([ { type: "video", url: "./a.mp4", duration: 5 }, // position: 0, end: 5 { type: "video", url: "./b.mp4", position: 10, end: 15 }, // explicit gap { type: "video", url: "./c.mp4", duration: 5 }, // position: 15, end: 20 ]); ``` Text clips always require an explicit `position` (they're overlays on specific moments). Background music and subtitle clips already have optional `position`/`end` with their own defaults. ``` -------------------------------- ### POST /project/load Source: https://www.simple-ffmpegjs.com/llms.txt Loads a sequence of clips, transitions, and effects into the project timeline. ```APIDOC ## POST /project/load ### Description Loads an array of media clips (video, image, music) into the project. Supports transitions and Ken Burns effects. ### Method POST ### Endpoint /project/load ### Parameters #### Request Body - **clips** (array) - Required - A list of clip objects containing type, url, position, duration, and optional effects like transition or kenBurns. ### Request Example [ { "type": "image", "url": "./photo1.jpg", "duration": 3, "kenBurns": "zoom-in" }, { "type": "music", "url": "./music.mp3", "volume": 0.3 } ] ### Response #### Success Response (200) - **status** (string) - Confirms that the clips have been successfully loaded into the project timeline. ``` -------------------------------- ### Auto-Sequencing and Duration Shorthand Source: https://www.simple-ffmpegjs.com/llms.txt Demonstrates how to simplify clip loading by using duration instead of end times and allowing the library to auto-calculate positions based on the previous clip's end time. ```typescript // Before: manual position/end for every clip await project.load([ { type: "video", url: "./a.mp4", position: 0, end: 5 }, { type: "video", url: "./b.mp4", position: 5, end: 10 }, { type: "video", url: "./c.mp4", position: 10, end: 18, cutFrom: 3 }, ]); // After: auto-sequencing + duration await project.load([ { type: "video", url: "./a.mp4", duration: 5 }, { type: "video", url: "./b.mp4", duration: 5 }, { type: "video", url: "./c.mp4", duration: 8, cutFrom: 3 }, ]); ``` -------------------------------- ### Configure Emoji Font in simple-ffmpegjs Source: https://www.simple-ffmpegjs.com/llms.txt Demonstrates how to configure a custom emoji font path when initializing the SIMPLEFFMPEG project. This enables the rendering of emoji characters in text overlays by routing them through libass for per-glyph font switching. ```javascript const project = new SIMPLEFFMPEG({ width: 1920, height: 1080, emojiFont: '/path/to/NotoEmoji-Regular.ttf' }); ``` -------------------------------- ### Import External Subtitle Files (SRT, VTT, ASS) Source: https://www.simple-ffmpegjs.com/llms.txt Loads external subtitle files (SRT, VTT, ASS/SSA) into the video project. Allows customization of font size, color, and border color for SRT/VTT files. ASS/SSA files use their embedded styles. ```typescript await project.load([ { type: "video", url: "./video.mp4", position: 0, end: 60 }, { type: "subtitle", url: "./subtitles.srt", // or .vtt, .ass, .ssa fontSize: 24, fontColor: "#FFFFFF", borderColor: "#000000", }, ]); ``` -------------------------------- ### Filter Schema Modules Source: https://www.simple-ffmpegjs.com/llms.txt Demonstrates how to include or exclude specific media modules (like video, audio, or text) when generating a schema, and how to list all available modules. ```javascript const schema = SIMPLEFFMPEG.getSchema({ include: ["video", "image"] }); const schema = SIMPLEFFMPEG.getSchema({ exclude: ["text", "subtitle"] }); SIMPLEFFMPEG.getSchemaModules(); ``` -------------------------------- ### Method - project.load() Source: https://www.simple-ffmpegjs.com/llms.txt Loads an array of clip descriptors into the project, validating the timeline and metadata. ```APIDOC ## project.load(clips) ### Description Loads clip descriptors into the project. Validates the timeline and reads media metadata. ### Method async ### Parameters #### Request Body - **clips** (Array) - Required - An array of clip objects defining the timeline. ### Request Example await project.load([{ type: "video", url: "intro.mp4", position: 0 }]); ### Response #### Success Response (200) - **Promise** - Returns a promise that resolves when all clips are loaded. ``` -------------------------------- ### Manage Timeline Transitions Source: https://www.simple-ffmpegjs.com/llms.txt Shows how to define video clips and text overlays with transitions. The library automatically compensates for timeline compression caused by overlapping transitions. ```typescript await project.load([ { type: "video", url: "./a.mp4", position: 0, end: 10 }, { type: "video", url: "./b.mp4", position: 10, end: 20, transition: { type: "fade", duration: 1 } }, { type: "text", text: "Appears at 15s visual", position: 15, end: 18 } ]); ``` -------------------------------- ### Export Video with FFmpeg.js Project Source: https://www.simple-ffmpegjs.com/llms.txt Builds and executes an FFmpeg command to render a final video. It accepts various options to control video and audio codecs, quality, resolution, and more. The function returns a promise that resolves with the output file path. ```typescript await project.export(options?: ExportOptions): Promise ``` -------------------------------- ### Karaoke Text with Word Highlighting Source: https://www.simple-ffmpegjs.com/llms.txt Implements karaoke-style text overlays with word-by-word highlighting. Allows customization of highlight colors and timing. Supports 'instant' highlight style for immediate color changes. ```typescript await project.load([ { type: "video", url: "./music-video.mp4", position: 0, end: 10 }, { type: "text", mode: "karaoke", text: "Never gonna give you up", position: 0, end: 5, words: [ { text: "Never", start: 0, end: 0.8 }, { text: "gonna", start: 0.8, end: 1.4 }, { text: "give", start: 1.4, end: 2.0 }, { text: "you", start: 2.0, end: 2.5 }, { text: "up", start: 2.5, end: 3.5 }, ], fontColor: "#FFFFFF", highlightColor: "#00FF00", fontSize: 52, yPercent: 0.85, }, ]); ``` -------------------------------- ### Define Audio and Music Clip Configuration Source: https://www.simple-ffmpegjs.com/llms.txt Defines configurations for standard audio clips and background music. Background music supports looping and specific volume controls. ```typescript { type: "audio"; url: string; position?: number; end?: number; duration?: number; cutFrom?: number; volume?: number; } { type: "music"; url: string; position?: number; end?: number; cutFrom?: number; volume?: number; loop?: boolean; } ``` -------------------------------- ### Build AI Video Schema with simple-ffmpegjs Source: https://www.simple-ffmpegjs.com/llms.txt Generates a JSON schema for an AI model to use when composing video clips. It defines allowed clip types, overall instructions, and specific module instructions for video, text, and music, ensuring adherence to project requirements like duration and transitions. ```javascript import SIMPLEFFMPEG from "simple-ffmpegjs"; const schema = SIMPLEFFMPEG.getSchema({ include: ["video", "image", "text", "music"], instructions: [ "You are composing a short-form video for TikTok.", "Keep total duration under 30 seconds.", "Return ONLY valid JSON — an array of clip objects.", ], moduleInstructions: { video: "Use fade transitions between clips. Keep each clip 3-6 seconds.", text: [ "Add a title in the first 2 seconds with fontSize 72.", "Use white text with a black border for readability.", ], music: "Always include looping background music at volume 0.15.", }, }); ``` -------------------------------- ### Extract Keyframes from Video using SIMPLEFFMPEG (TypeScript) Source: https://www.simple-ffmpegjs.com/llms.txt Demonstrates extracting keyframes from a video file using the SIMPLEFFMPEG.extractKeyframes static method. Supports both scene-change detection and fixed interval extraction. Keyframes can be returned as in-memory Buffers or saved to a specified directory. Handles different output formats like JPEG and PNG, and allows for resizing and quality adjustments. ```typescript const frames = await SIMPLEFFMPEG.extractKeyframes("./video.mp4", { mode: "scene-change", sceneThreshold: 0.4, maxFrames: 8, format: "jpeg", }); const paths = await SIMPLEFFMPEG.extractKeyframes("./video.mp4", { mode: "interval", intervalSeconds: 5, outputDir: "./frames/", format: "png", }); const framesResized = await SIMPLEFFMPEG.extractKeyframes("./long-video.mp4", { sceneThreshold: 0.25, maxFrames: 12, width: 640, quality: 4, }); const pathsPng = await SIMPLEFFMPEG.extractKeyframes("./presentation.mp4", { mode: "interval", intervalSeconds: 10, outputDir: "./thumbnails/", format: "png", }); ``` -------------------------------- ### Run Automated Tests Source: https://www.simple-ffmpegjs.com/llms.txt Commands to execute the test suite using npm. These commands allow for running all tests, specific test categories, or enabling watch mode for development. ```bash npm test npm run test:unit npm run test:integration npm run test:watch ``` -------------------------------- ### Add Centered Text Overlays Source: https://www.simple-ffmpegjs.com/llms.txt Demonstrates adding centered text overlays to a video. Text can be positioned using percentage or pixel offsets. Supports basic text properties like fontSize and yOffset. ```typescript await project.load([ { type: "video", url: "./bg.mp4", position: 0, end: 10 }, // Title: centered, 100px above center { type: "text", text: "Main Title", position: 0, end: 5, fontSize: 72, yOffset: -100, }, // Subtitle: centered, 50px below center { type: "text", text: "Subtitle here", position: 0.5, end: 5, fontSize: 36, yOffset: 50, }, ]); ```