### Run FFmpeg.wasm Next.js Development Server Source: https://github.com/ffmpegwasm/ffmpeg.wasm/blob/main/apps/nextjs-app/README.md Commands to start the development server for the FFmpeg.wasm Next.js project. Assumes Node.js and npm/yarn/pnpm are installed. Opens the application in a browser at http://localhost:3000. ```bash npm run dev # or yarn dev # or pnpm dev ``` -------------------------------- ### Develop Svelte Project Source: https://github.com/ffmpegwasm/ffmpeg.wasm/blob/main/apps/sveltekit-app/README.md Commands to start the development server for a Svelte project. After installing dependencies, you can run the development server and optionally open the app in a browser. ```bash npm run dev # or start the server and open the app in a new browser tab npm run dev -- --open ``` -------------------------------- ### Start Local Development Server with npm Source: https://github.com/ffmpegwasm/ffmpeg.wasm/blob/main/apps/website/README.md Starts a local development server for the Docusaurus 2 website. Changes are typically reflected live without requiring a server restart. Opens the site in a browser window. ```bash npm start ``` -------------------------------- ### Install Project Dependencies with npm Source: https://github.com/ffmpegwasm/ffmpeg.wasm/blob/main/apps/website/README.md Installs the necessary dependencies for the project using npm. Ensure git-lfs is installed and run 'git lfs pull' if dependencies were cloned before installing git-lfs. ```bash npm install ``` -------------------------------- ### Analyze Media Files with ffprobe (TypeScript) Source: https://context7.com/ffmpegwasm/ffmpeg.wasm/llms.txt Demonstrates how to use the ffprobe() method to extract metadata from media files. Examples include getting video duration and retrieving comprehensive stream and format information in JSON format. Requires @ffmpeg/ffmpeg and @ffmpeg/util. ```typescript import { FFmpeg } from "@ffmpeg/ffmpeg"; import { fetchFile } from "@ffmpeg/util"; const ffmpeg = new FFmpeg(); await ffmpeg.load(); // Load video file await ffmpeg.writeFile("video.mp4", await fetchFile("https://example.com/video.mp4")); // Get video duration await ffmpeg.ffprobe([ "-v", "error", "-show_entries", "format=duration", "-of", "default=noprint_wrappers=1:nokey=1", "video.mp4", "-o", "duration.txt" ]); const durationData = await ffmpeg.readFile("duration.txt", "utf8"); console.log(`Duration: ${durationData} seconds`); // Get comprehensive video information (JSON format) await ffmpeg.ffprobe([ "-v", "quiet", "-print_format", "json", "-show_format", "-show_streams", "video.mp4", "-o", "info.json" ]); const info = await ffmpeg.readFile("info.json", "utf8"); const metadata = JSON.parse(info); console.log(`Resolution: ${metadata.streams[0].width}x${metadata.streams[0].height}`); console.log(`Codec: ${metadata.streams[0].codec_name}`); ``` -------------------------------- ### FFmpeg Class Constructor and Initialization (TypeScript) Source: https://context7.com/ffmpegwasm/ffmpeg.wasm/llms.txt Demonstrates how to create a new FFmpeg instance and load the FFmpeg core module. It shows both single-threaded and multi-threaded core loading, along with checking the loaded status. Requires @ffmpeg/ffmpeg and @ffmpeg/util. ```typescript import { FFmpeg } from "@ffmpeg/ffmpeg"; import { toBlobURL } from "@ffmpeg/util"; const ffmpeg = new FFmpeg(); // Check if ffmpeg-core is loaded console.log(ffmpeg.loaded); // false initially // Single-threaded version (recommended for simple tasks) const baseURL = "https://cdn.jsdelivr.net/npm/@ffmpeg/core@0.12.10/dist/umd"; await ffmpeg.load({ coreURL: await toBlobURL(`${baseURL}/ffmpeg-core.js`, "text/javascript"), wasmURL: await toBlobURL(`${baseURL}/ffmpeg-core.wasm`, "application/wasm"), }); // Multi-threaded version (recommended for complex operations) const baseMT = "https://cdn.jsdelivr.net/npm/@ffmpeg/core-mt@0.12.10/dist/esm"; await ffmpeg.load({ coreURL: await toBlobURL(`${baseMT}/ffmpeg-core.js`, "text/javascript"), wasmURL: await toBlobURL(`${baseMT}/ffmpeg-core.wasm`, "application/wasm"), workerURL: await toBlobURL(`${baseMT}/ffmpeg-core.worker.js`, "text/javascript"), }); console.log(ffmpeg.loaded); // true after successful load ``` -------------------------------- ### Migrate FFmpeg Imports and Instantiation (JavaScript) Source: https://github.com/ffmpegwasm/ffmpeg.wasm/blob/main/apps/website/docs/migration.md This snippet shows how to update the import statement for creating an FFmpeg instance and how to instantiate it. In version 0.12+, `createFFmpeg` is replaced by `FFmpeg`, and arguments passed to `createFFmpeg` in 0.11.x are now handled by `ffmpeg.load()`. ```javascript import { createFFmpeg } from '@ffmpeg/ffmpeg'; // 0.11.x import { FFmpeg } from '@ffmpeg/ffmpeg'; // 0.12+ ``` ```javascript createFFmpeg(); // 0.11.x new FFmpeg(); // 0.12+ ``` -------------------------------- ### React ffmpeg.wasm Video Conversion Example Source: https://context7.com/ffmpegwasm/ffmpeg.wasm/llms.txt This TypeScript React component demonstrates a full workflow for video conversion using ffmpeg.wasm. It handles FFmpeg loading with blob URLs, event listeners for logs and progress, file input, video transcoding using FFmpeg commands, and output display. Dependencies include '@ffmpeg/ffmpeg' and '@ffmpeg/util'. ```typescript import { useState, useRef, useEffect } from "react"; import { FFmpeg } from "@ffmpeg/ffmpeg"; import { toBlobURL, fetchFile } from "@ffmpeg/util"; function VideoConverter() { const [loaded, setLoaded] = useState(false); const [progress, setProgress] = useState(0); const [message, setMessage] = useState(""); const [outputURL, setOutputURL] = useState(""); const ffmpegRef = useRef(new FFmpeg()); const fileInputRef = useRef(null); useEffect(() => { // Load ffmpeg on component mount const load = async () => { const baseURL = "https://cdn.jsdelivr.net/npm/@ffmpeg/core-mt@0.12.10/dist/esm"; const ffmpeg = ffmpegRef.current; // Setup event listeners ffmpeg.on("log", ({ message }) => { setMessage(message); console.log(message); }); ffmpeg.on("progress", ({ progress }) => { setProgress(Math.round(progress * 100)); }); // Load with blob URLs to bypass CORS try { await ffmpeg.load({ coreURL: await toBlobURL(`${baseURL}/ffmpeg-core.js`, "text/javascript"), wasmURL: await toBlobURL(`${baseURL}/ffmpeg-core.wasm`, "application/wasm"), workerURL: await toBlobURL(`${baseURL}/ffmpeg-core.worker.js`, "text/javascript"), }); setLoaded(true); setMessage("FFmpeg loaded successfully!"); } catch (error) { setMessage(`Error loading FFmpeg: ${error.message}`); } }; load(); // Cleanup on unmount return () => { ffmpegRef.current.terminate(); }; }, []); const convertVideo = async () => { const file = fileInputRef.current?.files[0]; if (!file) { setMessage("Please select a file"); return; } const ffmpeg = ffmpegRef.current; setProgress(0); setMessage("Converting..."); try { // Write input file await ffmpeg.writeFile("input.mp4", await fetchFile(file)); // Convert to different format with compression const exitCode = await ffmpeg.exec([ "-i", "input.mp4", "-c:v", "libx264", // Video codec "-preset", "medium", // Encoding preset "-crf", "23", // Quality (lower = better) "-c:a", "aac", // Audio codec "-b:a", "128k", // Audio bitrate "output.mp4" ]); if (exitCode === 0) { // Read output file const data = await ffmpeg.readFile("output.mp4"); const blob = new Blob([data], { type: "video/mp4" }); const url = URL.createObjectURL(blob); setOutputURL(url); setMessage("Conversion complete!"); // Cleanup temporary files await ffmpeg.deleteFile("input.mp4"); await ffmpeg.deleteFile("output.mp4"); } else { setMessage(`Conversion failed with exit code ${exitCode}`); } } catch (error) { setMessage(`Error: ${error.message}`); } }; if (!loaded) { return (

Loading FFmpeg...

{message}

); } return (

Video Converter

setOutputURL("")} /> {progress > 0 && (
{progress}%
)}

{message}

{outputURL && (

Output:

)}
); } export default VideoConverter; ``` -------------------------------- ### Split Video into Segments with ffmpeg.wasm Source: https://github.com/ffmpegwasm/ffmpeg.wasm/blob/main/apps/website/docs/getting-started/usage.md This snippet demonstrates how to split a video file into segments of equal duration using ffmpeg.wasm. It requires the FFmpeg library and fetchFile utility. The function takes a video file as input and outputs segmented video files. The example plays the second segment after processing. ```jsx function() { const [loaded, setLoaded] = useState(false); const ffmpegRef = useRef(new FFmpeg()); const videoRef = useRef(null); const messageRef = useRef(null); const load = async () => { const baseURL = 'https://cdn.jsdelivr.net/npm/@ffmpeg/core@0.12.10/dist/umd' const ffmpeg = ffmpegRef.current; ffmpeg.on('log', ({ message }) => { messageRef.current.innerHTML = message; console.log(message); }); // toBlobURL is used to bypass CORS issue, urls with the same // domain can be used directly. await ffmpeg.load({ coreURL: await toBlobURL(`${baseURL}/ffmpeg-core.js`, 'text/javascript'), wasmURL: await toBlobURL(`${baseURL}/ffmpeg-core.wasm`, 'application/wasm'), }); setLoaded(true); } const transcode = async () => { const ffmpeg = ffmpegRef.current; await ffmpeg.writeFile('input.webm', await fetchFile('https://raw.githubusercontent.com/ffmpegwasm/testdata/master/Big_Buck_Bunny_180_10s.webm')); await ffmpeg.exec([ '-i', 'input.webm', '-f', 'segment', '-segment_time', '3', '-g', '9', '-sc_threshold', '0', '-force_key_frames', 'expr:gte(t,n_forced*9)', '-reset_timestamps', '1', '-map', '0', 'output_%d.mp4' ]); const data = await ffmpeg.readFile('output_1.mp4'); videoRef.current.src = URL.createObjectURL(new Blob([data.buffer], {type: 'video/mp4'})); } return (loaded ? ( <>

Open Developer Tools (Ctrl+Shift+I) to View Logs

) : ( ) ); } ``` -------------------------------- ### Minimal Build Strategy Example Source: https://github.com/ffmpegwasm/ffmpeg.wasm/blob/main/apps/website/docs/contribution/core.md This outlines a strategy for creating a minimal ffmpeg.wasm build by disabling all features and then selectively enabling only the necessary components. This approach, often used for specific use cases like image sequence to video conversion, significantly reduces build size. ```bash # Example flags (actual implementation within Dockerfile): # --disable-everything \ # --enable-encoder=libx264 \ # --enable-decoder=png \ # --enable-muxer=mp4 \ # --enable-protocol=file \ # ... and so on for required components ``` -------------------------------- ### Create Directory with ffmpeg.wasm Source: https://context7.com/ffmpegwasm/ffmpeg.wasm/llms.txt Creates a new directory in the virtual filesystem using FFmpeg. Supports creating single or nested directories and storing files within them. Requires an FFmpeg instance and loaded worker. ```typescript import { FFmpeg } from "@ffmpeg/ffmpeg"; const ffmpeg = new FFmpeg(); await ffmpeg.load(); // Create single directory await ffmpeg.createDir("/videos"); // Create nested directories await ffmpeg.createDir("/media"); await ffmpeg.createDir("/media/videos"); await ffmpeg.createDir("/media/videos/processed"); // Store files in directory await ffmpeg.writeFile("/videos/input.mp4", videoData); await ffmpeg.exec(["-i", "/videos/input.mp4", "/videos/output.mp4"]); // List contents const files = await ffmpeg.listDir("/videos"); console.log(files); // [{ name: "input.mp4", ... }, { name: "output.mp4", ... }] ``` -------------------------------- ### Migrate fetchFile Import (JavaScript) Source: https://github.com/ffmpegwasm/ffmpeg.wasm/blob/main/apps/website/docs/migration.md This snippet details the change in the import path for the `fetchFile` utility. In version 0.12+, `fetchFile` is moved from '@ffmpeg/ffmpeg' to '@ffmpeg/util'. ```javascript import { fetchFile } from '@ffmpeg/ffmpeg'; // 0.11.x import { fetchFile } from '@ffmpeg/util'; // 0.12+ ``` -------------------------------- ### Initialize Editor Component for ffmpeg Commands (JavaScript/React) Source: https://github.com/ffmpegwasm/ffmpeg.wasm/blob/main/apps/website/src/pages/playground.md This snippet shows the initialization of the Editor component, used for inputting ffmpeg commands within the playground. It utilizes BrowserOnly for client-side rendering and MuiThemeProvider for styling. The component is pre-configured with example arguments for converting an AVI file to MP4. ```jsx import BrowserOnly from '@docusaurus/BrowserOnly'; import MuiThemeProvider from "@site/src/components/common/MuiThemeProvider"; // ... other imports
{() => { const Editor = require('@site/src/components/Playground/Workspace/Editor').default; return ( ); }}
``` -------------------------------- ### Interlace 2 Videos with ffmpeg.wasm (React JSX) Source: https://github.com/ffmpegwasm/ffmpeg.wasm/blob/main/apps/website/docs/getting-started/usage.md This example demonstrates how to interlace two WebM videos into an MP4 file using ffmpeg.wasm within a React component. It includes loading the ffmpeg core, handling video transcoding, and displaying the output. Dependencies include '@ffmpeg/ffmpeg' and '@ffmpeg/util'. ```jsx function() { const [loaded, setLoaded] = useState(false); const ffmpegRef = useRef(new FFmpeg()); const videoRef = useRef(null); const messageRef = useRef(null); const load = async () => { const baseURL = 'https://cdn.jsdelivr.net/npm/@ffmpeg/core@0.12.10/dist/umd' const ffmpeg = ffmpegRef.current; ffmpeg.on('log', ({ message }) => { messageRef.current.innerHTML = message; console.log(message); }); // toBlobURL is used to bypass CORS issue, urls with the same // domain can be used directly. await ffmpeg.load({ coreURL: await toBlobURL(`${baseURL}/ffmpeg-core.js`, 'text/javascript'), wasmURL: await toBlobURL(`${baseURL}/ffmpeg-core.wasm`, 'application/wasm'), }); setLoaded(true); } const transcode = async () => { const ffmpeg = ffmpegRef.current; await ffmpeg.writeFile('input.webm', await fetchFile('https://raw.githubusercontent.com/ffmpegwasm/testdata/master/Big_Buck_Bunny_180_10s.webm')); await ffmpeg.writeFile('reversed.webm', await fetchFile('https://raw.githubusercontent.com/ffmpegwasm/testdata/master/Big_Buck_Bunny_180_10s_reversed.webm')); await ffmpeg.exec([ '-i', 'input.webm', '-i', 'reversed.webm', '-filter_complex', '[0:v][1:v]blend=all_expr=\'A*(if(eq(0,N/2),1,T))+B*(if(eq(0,N/2),T,1))\'', 'output.mp4', ]); const data = await ffmpeg.readFile('output.mp4'); videoRef.current.src = URL.createObjectURL(new Blob([data.buffer], {type: 'video/mp4'})); } return (loaded ? ( <>

Open Developer Tools (Ctrl+Shift+I) to View Logs

) : ( ) ); } ``` -------------------------------- ### Transcode webm to mp4 using ffmpeg.wasm (Multi-thread, JavaScript) Source: https://github.com/ffmpegwasm/ffmpeg.wasm/blob/main/apps/website/docs/getting-started/usage.md This snippet shows how to transcode webm to mp4 using ffmpeg.wasm in a multi-threaded environment. It requires fulfilling specific security requirements for SharedArrayBuffer. The setup is similar to the single-threaded version but includes loading a worker file. ```jsx function() { const [loaded, setLoaded] = useState(false); const ffmpegRef = useRef(new FFmpeg()); const videoRef = useRef(null); const messageRef = useRef(null); const load = async () => { const baseURL = 'https://cdn.jsdelivr.net/npm/@ffmpeg/core-mt@0.12.10/dist/umd' const ffmpeg = ffmpegRef.current; ffmpeg.on('log', ({ message }) => { messageRef.current.innerHTML = message; console.log(message); }); // toBlobURL is used to bypass CORS issue, urls with the same // domain can be used directly. await ffmpeg.load({ coreURL: await toBlobURL(`${baseURL}/ffmpeg-core.js`, 'text/javascript'), wasmURL: await toBlobURL(`${baseURL}/ffmpeg-core.wasm`, 'application/wasm'), workerURL: await toBlobURL(`${baseURL}/ffmpeg-core.worker.js`, 'text/javascript'), }); setLoaded(true); } const transcode = async () => { const ffmpeg = ffmpegRef.current; await ffmpeg.writeFile('input.webm', await fetchFile('https://raw.githubusercontent.com/ffmpegwasm/testdata/master/Big_Buck_Bunny_180_10s.webm')); await ffmpeg.exec(['-i', 'input.webm', 'output.mp4']); const data = await ffmpeg.readFile('output.mp4'); videoRef.current.src = URL.createObjectURL(new Blob([data.buffer], {type: 'video/mp4'})); } return (loaded ? ( <>

Open Developer Tools (Ctrl+Shift+I) to View Logs

) : ( ) ); } ``` -------------------------------- ### Execute FFmpeg Commands (TypeScript) Source: https://context7.com/ffmpegwasm/ffmpeg.wasm/llms.txt Shows how to execute FFmpeg commands using the exec() method. This includes writing input files, converting formats (AVI to MP4), applying specific codec settings, extracting audio, and setting a timeout. Requires @ffmpeg/ffmpeg and @ffmpeg/util. ```typescript import { FFmpeg } from "@ffmpeg/ffmpeg"; import { fetchFile } from "@ffmpeg/util"; const ffmpeg = new FFmpeg(); await ffmpeg.load(); // Write input file to virtual filesystem await ffmpeg.writeFile("input.avi", await fetchFile("https://example.com/video.avi")); // Convert AVI to MP4 const exitCode = await ffmpeg.exec(["-i", "input.avi", "output.mp4"]); if (exitCode === 0) { console.log("Conversion successful!"); const data = await ffmpeg.readFile("output.mp4"); } // Convert with specific codec settings await ffmpeg.exec([ "-i", "input.mp4", "-c:v", "libx264", // H.264 video codec "-preset", "fast", // Encoding speed "-crf", "22", // Quality (0-51, lower is better) "-c:a", "aac", // AAC audio codec "-b:a", "128k", // Audio bitrate "output.mp4" ]); // Extract audio from video await ffmpeg.exec(["-i", "video.mp4", "-vn", "-acodec", "copy", "audio.mp3"]); // With timeout (10 seconds) const result = await ffmpeg.exec(["-i", "input.avi", "output.mp4"], 10000); ``` -------------------------------- ### Migrate FFmpeg Execution and Termination (JavaScript) Source: https://github.com/ffmpegwasm/ffmpeg.wasm/blob/main/apps/website/docs/migration.md This snippet illustrates the updated method for running FFmpeg commands and terminating the FFmpeg process. In 0.12+, `ffmpeg.run(...args)` is replaced by `await ffmpeg.exec([...args])`, and `ffmpeg.exit()` is replaced by `ffmpeg.terminate()`. ```javascript await ffmpeg.run(...args); // 0.11.x await ffmpeg.exec([...args]); // 0.12+ ``` ```javascript ffmpeg.exit(); // 0.11.x ffmpeg.terminate(); // 0.12+ ``` -------------------------------- ### Migrate FFmpeg File Operations (JavaScript) Source: https://github.com/ffmpegwasm/ffmpeg.wasm/blob/main/apps/website/docs/migration.md This snippet demonstrates the changes in file writing and reading operations when migrating from ffmpeg.wasm 0.11.x to 0.12+. The `ffmpeg.FS` namespace is replaced by `await ffmpeg.writeFile()` and `await ffmpeg.readFile()`. ```javascript ffmpeg.FS.writeFile(); // 0.11.x await ffmpeg.writeFile(); // 0.12+ ``` ```javascript ffmpeg.FS.readFile(); // 0.11.x await ffmpeg.readFile(); // 0.12+ ``` -------------------------------- ### Configure Vite for SharedArrayBuffer Support Source: https://context7.com/ffmpegwasm/ffmpeg.wasm/llms.txt Configures Vite's development server to include the necessary headers for SharedArrayBuffer support, essential for the multi-threaded ffmpeg.wasm. It also optimizes dependencies by excluding ffmpeg packages to prevent build issues. ```javascript export default { server: { headers: { "Cross-Origin-Embedder-Policy": "require-corp", "Cross-Origin-Opener-Policy": "same-origin", }, }, optimizeDeps: { exclude: ["@ffmpeg/ffmpeg", "@ffmpeg/util"], }, }; ``` -------------------------------- ### Transcode video with progress using FFmpeg.wasm (JavaScript) Source: https://github.com/ffmpegwasm/ffmpeg.wasm/blob/main/apps/website/docs/getting-started/usage.md This snippet demonstrates transcoding a WebM video to MP4 using FFmpeg.wasm and utilizes an experimental progress tracking feature. It loads the FFmpeg core, attaches a progress event listener, writes the input file, executes the transcoding command, and then reads and plays the output MP4. Note that the 'progress' feature is experimental. ```jsx function() { const [loaded, setLoaded] = useState(false); const ffmpegRef = useRef(new FFmpeg()); const videoRef = useRef(null); const messageRef = useRef(null); const load = async () => { const baseURL = 'https://cdn.jsdelivr.net/npm/@ffmpeg/core@0.12.10/dist/umd' const ffmpeg = ffmpegRef.current; // Listen to progress event instead of log. ffmpeg.on('progress', ({ progress, time }) => { messageRef.current.innerHTML = `${progress * 100} % (transcoded time: ${time / 1000000} s)`; }); // toBlobURL is used to bypass CORS issue, urls with the same // domain can be used directly. await ffmpeg.load({ coreURL: await toBlobURL(`${baseURL}/ffmpeg-core.js`, 'text/javascript'), wasmURL: await toBlobURL(`${baseURL}/ffmpeg-core.wasm`, 'application/wasm'), }); setLoaded(true); } const transcode = async () => { const ffmpeg = ffmpegRef.current; await ffmpeg.writeFile('input.webm', await fetchFile('https://raw.githubusercontent.com/ffmpegwasm/testdata/master/Big_Buck_Bunny_180_10s.webm')); await ffmpeg.exec(['-i', 'input.webm', 'output.mp4']); const data = await ffmpeg.readFile('output.mp4'); videoRef.current.src = URL.createObjectURL(new Blob([data.buffer], {type: 'video/mp4'})); } return (loaded ? ( <>

) : ( ) ); } ``` -------------------------------- ### Configure Next.js for SharedArrayBuffer Support Source: https://context7.com/ffmpegwasm/ffmpeg.wasm/llms.txt Sets up Cross-Origin Isolation headers in a Next.js application to facilitate the use of SharedArrayBuffer with ffmpeg.wasm. This configuration is applied globally to all routes, ensuring the multi-threaded functionality is accessible. ```javascript module.exports = { async headers() { return [ { source: "/:path*", headers: [ { key: "Cross-Origin-Embedder-Policy", value: "require-corp" }, { key: "Cross-Origin-Opener-Policy", value: "same-origin" }, ], }, ]; }, }; ``` -------------------------------- ### Configure ESLint TypeScript Parser Options Source: https://github.com/ffmpegwasm/ffmpeg.wasm/blob/main/apps/react-vite-app/README.md This snippet shows how to configure the `parserOptions` in ESLint to enable type-aware linting rules for TypeScript projects. It specifies the ECMAScript version, module source type, project configuration files, and the root directory for tsconfig. ```javascript parserOptions: { ecmaVersion: 'latest', sourceType: 'module', project: ['./tsconfig.json', './tsconfig.node.json'], tsconfigRootDir: __dirname, } ``` -------------------------------- ### Migrate FFmpeg Event Handling (JavaScript) Source: https://github.com/ffmpegwasm/ffmpeg.wasm/blob/main/apps/website/docs/migration.md This snippet shows how to update the logger and progress event handlers for ffmpeg.wasm. Version 0.12+ uses `ffmpeg.on('log', () => {})` and `ffmpeg.on('progress', () => {})` instead of `ffmpeg.setLogger()` and `ffmpeg.setProgress()`. ```javascript ffmpeg.setLogger(); // 0.11.x ffmpeg.on('log', () => {}); // 0.12+ ``` ```javascript ffmpeg.setProgress(); // 0.11.x ffmpeg.on('progress', () => {}); // 0.12+ ``` -------------------------------- ### Render File System Manager (JavaScript/React) Source: https://github.com/ffmpegwasm/ffmpeg.wasm/blob/main/apps/website/src/pages/playground.md This code demonstrates rendering the FileSystemManager component within the ffmpeg.wasm Playground. It leverages BrowserOnly for browser-specific execution and MuiThemeProvider for styling. The FileSystemManager is responsible for displaying and managing files within the in-memory file system, with initial nodes provided as an example. ```jsx import BrowserOnly from '@docusaurus/BrowserOnly'; import MuiThemeProvider from "@site/src/components/common/MuiThemeProvider"; // ... other imports
{() => { const FileSystemManager = require('@site/src/components/Playground/Workspace/FileSystemManager').default; return ( ); }}
``` -------------------------------- ### Mount Filesystem with ffmpeg.wasm Source: https://context7.com/ffmpegwasm/ffmpeg.wasm/llms.txt Mounts a filesystem at a specified path, enabling efficient access to files without explicit copying to memory. Supports mounting with File objects or Blobs for WORKERFS. Requires an FFmpeg instance, loaded worker, and the FFFSType enum. ```typescript import { FFmpeg } from "@ffmpeg/ffmpeg"; import { FFFSType } from "@ffmpeg/types"; const ffmpeg = new FFmpeg(); await ffmpeg.load(); // Mount WORKERFS with File objects (efficient for large files) const fileInput = document.getElementById("fileInput"); const files = fileInput.files; await ffmpeg.mount( FFFSType.WORKERFS, { files: Array.from(files) }, "/work" ); // Access mounted files without copying to memory await ffmpeg.exec(["-i", "/work/video.mp4", "output.mp4"]); // Unmount when done await ffmpeg.unmount("/work"); // Mount WORKERFS with Blobs const blobs = [ { name: "video1.mp4", data: blob1 }, { name: "video2.mp4", data: blob2 } ]; await ffmpeg.mount( FFFSType.WORKERFS, { blobs }, "/blobs" ); await ffmpeg.exec(["-i", "/blobs/video1.mp4", "-i", "/blobs/video2.mp4", "merged.mp4"]); await ffmpeg.unmount("/blobs"); ``` -------------------------------- ### Transcode webm to mp4 using ffmpeg.wasm (JavaScript) Source: https://github.com/ffmpegwasm/ffmpeg.wasm/blob/main/apps/website/docs/getting-started/usage.md This snippet demonstrates how to transcode a webm video file to mp4 format using the ffmpeg.wasm library in JavaScript. It includes loading the ffmpeg core, writing the input file, executing the transcoding command, and reading the output file. It utilizes `fetchFile` for input and `URL.createObjectURL` for output. ```jsx function() { const [loaded, setLoaded] = useState(false); const ffmpegRef = useRef(new FFmpeg()); const videoRef = useRef(null); const messageRef = useRef(null); const load = async () => { const baseURL = 'https://cdn.jsdelivr.net/npm/@ffmpeg/core@0.12.10/dist/umd' const ffmpeg = ffmpegRef.current; ffmpeg.on('log', ({ message }) => { messageRef.current.innerHTML = message; console.log(message); }); // toBlobURL is used to bypass CORS issue, urls with the same // domain can be used directly. await ffmpeg.load({ coreURL: await toBlobURL(`${baseURL}/ffmpeg-core.js`, 'text/javascript'), wasmURL: await toBlobURL(`${baseURL}/ffmpeg-core.wasm`, 'application/wasm'), }); setLoaded(true); } const transcode = async () => { const ffmpeg = ffmpegRef.current; await ffmpeg.writeFile('input.webm', await fetchFile('https://raw.githubusercontent.com/ffmpegwasm/testdata/master/Big_Buck_Bunny_180_10s.webm')); await ffmpeg.exec(['-i', 'input.webm', 'output.mp4']); const data = await ffmpeg.readFile('output.mp4'); videoRef.current.src = URL.createObjectURL(new Blob([data.buffer], {type: 'video/mp4'})); } return (loaded ? ( <>

Open Developer Tools (Ctrl+Shift+I) to View Logs

) : ( ) ); } ``` -------------------------------- ### Download Content with Progress using downloadWithProgress() in TypeScript Source: https://context7.com/ffmpegwasm/ffmpeg.wasm/llms.txt The downloadWithProgress() utility function enables downloading content from a specified URL while providing real-time progress updates through a callback function. The callback receives details about the download, including total bytes, received bytes, and delta. The function returns the downloaded content as an ArrayBuffer. ```typescript import { downloadWithProgress } from "@ffmpeg/util"; // Download with progress callback const buffer = await downloadWithProgress( "https://example.com/large-video.mp4", ({ url, total, received, delta, done }) => { console.log(`URL: ${url}`); console.log(`Total: ${total} bytes`); console.log(`Received: ${received} bytes`); console.log(`Delta: ${delta} bytes (this chunk)`); console.log(`Done: ${done}`); if (total > 0) { const percentage = (received / total) * 100; console.log(`Progress: ${percentage.toFixed(2)}%`); // Update UI document.getElementById("progress").style.width = `${percentage}%`; document.getElementById("status").textContent = `${(received / 1024 / 1024).toFixed(2)} MB / ${(total / 1024 / 1024).toFixed(2)} MB`; } } ); // Convert ArrayBuffer to Uint8Array const uint8Array = new Uint8Array(buffer); await ffmpeg.writeFile("video.mp4", uint8Array); ``` -------------------------------- ### Display Text on Video with ffmpeg.wasm Source: https://github.com/ffmpegwasm/ffmpeg.wasm/blob/main/apps/website/docs/getting-started/usage.md This snippet shows how to overlay text onto a video using ffmpeg.wasm. It requires the FFmpeg library, fetchFile, and a TTF font file. The function processes a video, adds text using the drawtext filter, and saves the output. The modified video is then displayed. ```jsx function() { const [loaded, setLoaded] = useState(false); const ffmpegRef = useRef(new FFmpeg()); const videoRef = useRef(null); const messageRef = useRef(null); const load = async () => { const baseURL = 'https://cdn.jsdelivr.net/npm/@ffmpeg/core@0.12.10/dist/umd' const ffmpeg = ffmpegRef.current; ffmpeg.on('log', ({ message }) => { messageRef.current.innerHTML = message; console.log(message); }); // toBlobURL is used to bypass CORS issue, urls with the same // domain can be used directly. await ffmpeg.load({ coreURL: await toBlobURL(`${baseURL}/ffmpeg-core.js`, 'text/javascript'), wasmURL: await toBlobURL(`${baseURL}/ffmpeg-core.wasm`, 'application/wasm'), }); setLoaded(true); } const transcode = async () => { const ffmpeg = ffmpegRef.current; await ffmpeg.writeFile('input.webm', await fetchFile('https://raw.githubusercontent.com/ffmpegwasm/testdata/master/Big_Buck_Bunny_180_10s.webm')); await ffmpeg.writeFile('arial.ttf', await fetchFile('https://raw.githubusercontent.com/ffmpegwasm/testdata/master/arial.ttf')); await ffmpeg.exec([ '-i', 'input.webm', '-vf', 'drawtext=fontfile=/arial.ttf:text=\'ffmpeg.wasm\':x=10:y=10:fontsize=24:fontcolor=white', 'output.mp4', ]); const data = await ffmpeg.readFile('output.mp4'); videoRef.current.src = URL.createObjectURL(new Blob([data.buffer], {type: 'video/mp4'})); } return (loaded ? ( <>

Open Developer Tools (Ctrl+Shift+I) to View Logs

) : ( ) ); } ``` -------------------------------- ### Transcode video with timeout using FFmpeg.wasm (JavaScript) Source: https://github.com/ffmpegwasm/ffmpeg.wasm/blob/main/apps/website/docs/getting-started/usage.md This snippet demonstrates transcoding a WebM video to MP4 using FFmpeg.wasm with a specified timeout. It loads the FFmpeg core, writes the input file, executes the transcoding command with a 1-second timeout, and then reads and plays the output MP4. Dependencies include '@ffmpeg/ffmpeg' and '@ffmpeg/util'. ```jsx function() { const [loaded, setLoaded] = useState(false); const ffmpegRef = useRef(new FFmpeg()); const videoRef = useRef(null); const messageRef = useRef(null); const load = async () => { const baseURL = 'https://cdn.jsdelivr.net/npm/@ffmpeg/core@0.12.10/dist/umd' const ffmpeg = ffmpegRef.current; ffmpeg.on('log', ({ message }) => { messageRef.current.innerHTML = message; console.log(message); }); // toBlobURL is used to bypass CORS issue, urls with the same // domain can be used directly. await ffmpeg.load({ coreURL: await toBlobURL(`${baseURL}/ffmpeg-core.js`, 'text/javascript'), wasmURL: await toBlobURL(`${baseURL}/ffmpeg-core.wasm`, 'application/wasm'), }); setLoaded(true); } const transcode = async () => { const ffmpeg = ffmpegRef.current; await ffmpeg.writeFile('input.webm', await fetchFile('https://raw.githubusercontent.com/ffmpegwasm/testdata/master/Big_Buck_Bunny_180_10s.webm')); // The exec should stop after 1 second. await ffmpeg.exec(['-i', 'input.webm', 'output.mp4'], 1000); const data = await ffmpeg.readFile('output.mp4'); videoRef.current.src = URL.createObjectURL(new Blob([data.buffer], {type: 'video/mp4'})); } return (loaded ? ( <>

Open Developer Tools (Ctrl+Shift+I) to View Logs

) : ( ) ); } ``` -------------------------------- ### Listen to FFmpeg Events with on() Source: https://context7.com/ffmpegwasm/ffmpeg.wasm/llms.txt Registers event listeners for log and progress events during FFmpeg operations. It takes an event type ('log' or 'progress') and a callback function. Log events provide messages from FFmpeg's stdout/stderr, while progress events offer operation status like completion percentage and time. ```typescript import { FFmpeg } from "@ffmpeg/ffmpeg"; const ffmpeg = new FFmpeg(); // Listen to log events (stdout/stderr output) ffmpeg.on("log", ({ type, message }) => { console.log(`[${type}] ${message}`); }); // Listen to progress events ffmpeg.on("progress", ({ progress, time }) => { console.log(`Progress: ${Math.round(progress * 100)}%`); console.log(`Time: ${time} microseconds`); // Update UI progress bar const progressBar = document.getElementById("progress"); if (progressBar) { progressBar.style.width = `${progress * 100}%`; } }); await ffmpeg.load(); // Progress events will fire during exec() await ffmpeg.exec(["-i", "input.avi", "output.mp4"]); ``` -------------------------------- ### Write Files to Virtual Filesystem with writeFile() Source: https://context7.com/ffmpegwasm/ffmpeg.wasm/llms.txt Writes data to the ffmpeg.wasm virtual filesystem from various sources, including URLs, File inputs, Blobs, text strings, Uint8Arrays, and base64 encoded data. The `fetchFile` utility is often used to handle different input types seamlessly. This is essential for providing input files to FFmpeg processing. ```typescript import { FFmpeg } from "@ffmpeg/ffmpeg"; import { fetchFile } from "@ffmpeg/util"; const ffmpeg = new FFmpeg(); await ffmpeg.load(); // From URL await ffmpeg.writeFile("video.mp4", await fetchFile("https://example.com/video.mp4")); // From File input const fileInput = document.getElementById("fileInput"); fileInput.addEventListener("change", async (e) => { const file = e.target.files[0]; await ffmpeg.writeFile("input.mp4", await fetchFile(file)); }); // From Blob const blob = new Blob([videoData], { type: "video/mp4" }); await ffmpeg.writeFile("blob-video.mp4", await fetchFile(blob)); // From text string await ffmpeg.writeFile("subtitle.srt", "1\n00:00:00,000 --> 00:00:05,000\nHello World"); // From Uint8Array const uint8Data = new Uint8Array([0xFF, 0xD8, 0xFF, 0xE0]); await ffmpeg.writeFile("image.jpg", uint8Data); // From base64 const base64Data = "data:image/png;base64,iVBORw0KGgoAAAANS..."; await ffmpeg.writeFile("image.png", await fetchFile(base64Data)); ``` -------------------------------- ### Fetch File Data with fetchFile() in TypeScript Source: https://context7.com/ffmpegwasm/ffmpeg.wasm/llms.txt The fetchFile() utility function retrieves data from various sources like URLs, File objects, Blobs, URL objects, or base64 data URIs. It returns a Uint8Array, which is directly compatible with ffmpeg.writeFile(). This function simplifies data acquisition for ffmpeg operations in the browser. ```typescript import { fetchFile } from "@ffmpeg/util"; // From URL string const fromURL = await fetchFile("https://example.com/video.mp4"); // From File object (user upload) const input = document.getElementById("fileInput"); input.addEventListener("change", async (e) => { const file = e.target.files[0]; const data = await fetchFile(file); console.log(`Loaded ${data.length} bytes`); }); // From Blob const blob = new Blob([videoData], { type: "video/mp4" }); const fromBlob = await fetchFile(blob); // From URL object const url = new URL("video.mp4", import.meta.url); const fromURLObj = await fetchFile(url); // From base64 data URI const base64 = "data:video/mp4;base64,AAAAIGZ0eXBpc29t..."; const fromBase64 = await fetchFile(base64); // All return Uint8Array ready for ffmpeg.writeFile() await ffmpeg.writeFile("video.mp4", fromURL); ```