Load Multi-Threaded ffmpeg.wasm and Configure COOP/COEP
This article provides a step-by-step guide on how to load and run the
multi-threaded version of ffmpeg.wasm in your web
applications. You will learn how to set up the necessary Cross-Origin
Opener Policy (COOP) and Cross-Origin Embedder Policy (COEP) headers on
your server to enable SharedArrayBuffer support, followed
by the JavaScript code required to initialize the multi-threaded FFmpeg
core.
Why COOP and COEP Headers are Required
Multi-threaded ffmpeg.wasm relies on Web Workers and
SharedArrayBuffer to share memory across multiple threads.
Due to security vulnerabilities like Spectre, modern web browsers
restrict the use of SharedArrayBuffer by default.
To enable this feature, your server must serve the HTML page with specific HTTP response headers that place the document in a secure, isolated context.
The Required Headers
You must configure your web server to send the following two HTTP headers:
Cross-Origin-Opener-Policy: same-origin
Cross-Origin-Embedder-Policy: require-corp
Server Configuration Examples
Node.js (Express)
If you are using Express, you can set these headers using middleware:
const express = require('express');
const app = express();
app.use((req, res, next) => {
res.setHeader('Cross-Origin-Opener-Policy', 'same-origin');
res.setHeader('Cross-Origin-Embedder-Policy', 'require-corp');
next();
});
app.use(express.static('public'));
app.listen(3000);Nginx
For an Nginx server, add these directives to your configuration block:
server {
listen 80;
server_name localhost;
location / {
add_header Cross-Origin-Opener-Policy "same-origin";
add_header Cross-Origin-Embedder-Policy "require-corp";
root /usr/share/nginx/html;
index index.html;
}
}
Next.js
(next.config.js)
If you are using Next.js, configure the headers in your configuration file:
module.exports = {
async headers() {
return [
{
source: '/(.*)',
headers: [
{
key: 'Cross-Origin-Opener-Policy',
value: 'same-origin',
},
{
key: 'Cross-Origin-Embedder-Policy',
value: 'require-corp',
},
],
},
];
},
};Loading Multi-Threaded ffmpeg.wasm
Once the headers are configured, you can load the multi-threaded
version of ffmpeg.wasm in your frontend application. You
must use the multi-threaded version of the core library
(@ffmpeg/core-mt) and explicitly define the worker URL
during initialization.
Step 1: Install Dependencies
Install the latest versions of @ffmpeg/ffmpeg and
@ffmpeg/util:
npm install @ffmpeg/ffmpeg @ffmpeg/utilStep 2: Initialize and Load FFmpeg
Import the required modules and load the multi-threaded core assets. Using a CDN like unpkg is standard, but you can also host these files locally on your server.
import { FFmpeg } from '@ffmpeg/ffmpeg';
import { toBlobURL } from '@ffmpeg/util';
const ffmpeg = new FFmpeg();
async function loadMultiThreadedFFmpeg() {
// Use the multi-threaded (core-mt) version of ffmpeg.wasm
const baseURL = 'https://unpkg.com/@ffmpeg/core-mt@0.12.6/dist/esm';
try {
await ffmpeg.load({
coreURL: await toBlobURL(`${baseURL}/ffmpeg-core.js`, 'text/javascript'),
wasmURL: await toBlobURL(`${baseURL}/ffmpeg-core.wasm`, 'application/wasm'),
// workerURL is required for multi-threading
workerURL: await toBlobURL(`${baseURL}/ffmpeg-core.worker.js`, 'text/javascript'),
});
console.log('Multi-threaded ffmpeg.wasm loaded successfully!');
} catch (error) {
console.error('Failed to load multi-threaded ffmpeg.wasm:', error);
}
}
loadMultiThreadedFFmpeg();Verifying the Setup
To confirm that multi-threading is working: 1. Open your browser’s
Developer Tools (F12). 2. Go to the Network tab, reload
the page, and select your main HTML document. Check the Response
Headers to ensure
Cross-Origin-Opener-Policy: same-origin and
Cross-Origin-Embedder-Policy: require-corp are present. 3.
Check the Console to ensure no
SharedArrayBuffer or CORS-related errors are thrown during
ffmpeg.load().