How to Use File System in FFmpeg WebAssembly
Running FFmpeg in the browser via WebAssembly (Wasm) requires a
virtual file system to read input media and write output results, as
Wasm cannot directly access the user’s local hard drive. This article
explains how to interact with the Emscripten Virtual File System (MEMFS)
used by @ffmpeg/ffmpeg, write input files from browser
memory, execute processing commands, read the resulting output, and
capture standard input/output (stdio) for progress logging.
Understanding the Virtual File System (MEMFS)
Because WebAssembly runs in a secure browser sandbox, it operates on an in-memory virtual file system called MEMFS. When you run FFmpeg Wasm:
- You must first load your input media file into the browser (e.g.,
via an HTML
<input type="file">or a URL fetch). - You write this file data into FFmpeg’s virtual file system.
- You execute the FFmpeg command, referencing the virtual file name.
- FFmpeg writes the processed output back into the virtual file system.
- You read the output file from the virtual file system into browser memory to download it or display it in an HTML5 player.
Step 1: Initialize FFmpeg and Capture Logs (Standard I/O)
Standard output (stdout) and standard error (stderr) are essential for tracking conversion progress and debugging errors. You can intercept these logs by binding an event listener to your FFmpeg instance before loading it.
import { FFmpeg } from '@ffmpeg/ffmpeg';
import { fetchFile } from '@ffmpeg/util';
const ffmpeg = new FFmpeg();
// Handle Standard I/O (stdout / stderr)
ffmpeg.on('log', ({ type, message }) => {
console.log(`[FFmpeg ${type}]: ${message}`);
});
// Track progress
ffmpeg.on('progress', ({ progress, time }) => {
console.log(`Progress: ${(progress * 100).toFixed(2)}% (Time: ${time}ms)`);
});
await ffmpeg.load();Step 2: Write Files to the Virtual File System
To process a file, you must convert it into a Uint8Array
and write it to the virtual root directory using
ffmpeg.writeFile().
// Obtain a File object from an HTML input element
const fileInput = document.getElementById('upload');
const file = fileInput.files[0];
// Write the file to the virtual file system as 'input.mp4'
await ffmpeg.writeFile('input.mp4', await fetchFile(file));Step 3: Execute the FFmpeg Command
Run your FFmpeg command by passing an array of arguments to the
exec() method. Ensure the input and output filenames match
the virtual file system paths.
// Convert input.mp4 to output.mp3
await ffmpeg.exec(['-i', 'input.mp4', 'output.mp3']);Step 4: Read Output from the Virtual File System
Once execution is complete, read the output file from the virtual
file system using ffmpeg.readFile(). You can then convert
this data into a Blob URL for browser playback or download.
// Read the generated file from MEMFS
const data = await ffmpeg.readFile('output.mp3');
// Convert the Uint8Array to a Blob URL
const audioBlob = new Blob([data.buffer], { type: 'audio/mp3' });
const audioUrl = URL.createObjectURL(audioBlob);
// Assign to an HTML audio element or trigger a download
const audioPlayer = document.getElementById('audio-player');
audioPlayer.src = audioUrl;Step 5: Clean Up Memory
Because MEMFS stores files in browser RAM, keeping large video files in the virtual file system can cause the browser tab to crash due to out-of-memory errors. Always delete files after processing them.
// Remove files from the virtual file system
await ffmpeg.deleteFile('input.mp4');
await ffmpeg.deleteFile('output.mp3');