Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

How to run ffmpeg.wasm directly on the main thread (usacase: cloudflare worker, browser extension service worker, etc) #782

Unanswered
clmnin asked this question in Q&A
Discussion options

I am trying to run ffmpeg wasm on a cloudflare worker with a custom build. But since I can't start a web worker from within a CF worker I get the error

Caution

Worker is not defined

Is there a way to run ffmpeg.wasm on the main thread (in my case directly in the CF worker)?

Running ./build-with-docker.sh to build a very small version of ffmpeg.wasm. By following this blog post - link. The final wasm file is only 8.4 mb (2.8 mb gzipped). CF Worker can support upto 10 MB compressed.

Here is the code for the worker

import { FFmpeg } from '@ffmpeg/ffmpeg';
import { fetchFile } from '@ffmpeg/util';
export interface Env {
	// Add any environment variables here
}
export default {
	async fetch(request: Request, env: Env, ctx: ExecutionContext): Promise<Response> {
		if (request.method !== 'POST') {
			return new Response('Send a POST request with a video file', { status: 400 });
		}
		const formData = await request.formData();
		const videoFile = formData.get('video') as File | null;
		if (!videoFile) {
			return new Response('No video file provided', { status: 400 });
		}
		try {
			const trimmedVideo = await trimVideo(videoFile);
			if (!trimmedVideo) {
				return new Response(`Failed to trim video`, { status: 500 });
			}
			return new Response(trimmedVideo, {
				headers: {
					'Content-Type': 'video/mp4',
					'Content-Disposition': `attachment; filename="trimmed_${videoFile.name}"`,
				},
			});
		} catch (error) {
			// @ts-ignore
			return new Response(`Error processing video: ${error.message}`, { status: 500 });
		}
	},
};
async function trimVideo(videoFile: File): Promise<Uint8Array | null> {
	const ffmpeg = new FFmpeg();
	try {
		await ffmpeg.load({
			coreURL: 'http://localhost:8787/ffmpeg-core.js',
			wasmURL: 'http://localhost:8787/ffmpeg-core.wasm',
		});
	} catch (error) {
		// @ts-ignore
		console.error(error.message);
		return null;
	}
	const inputFileName = 'input.mp4';
	const outputFileName = 'output.mp4';
	ffmpeg.writeFile(inputFileName, await fetchFile(videoFile));
	await ffmpeg.exec([
		'-i',
		inputFileName,
		'-ss',
		'1', // Start at 1 second
		'-to',
		'-1', // End 1 second before the end
		'-c',
		'copy', // Use the same codec (faster)
		outputFileName,
	]);
	const data = await ffmpeg.readFile(outputFileName);
	await ffmpeg.deleteFile(inputFileName);
	await ffmpeg.deleteFile(outputFileName);
	return new Uint8Array(data as ArrayBuffer);
}
You must be logged in to vote

Replies: 2 comments 3 replies

Comment options

any news?

You must be logged in to vote
3 replies
Comment options

Nope, this project is on the back burner for now. I may come back to it in a few months.

A few ideas to explore are:

  1. WASI
  2. Building WebAssembly (WASM) for Cloudflare Workers

Interesting links:

  1. https://github.com/SebastiaanYN/FFmpeg-WASI
  2. https://github.com/Yahweasel/libav.js

Note: To make FFmpeg work on a Cloudflare Worker, you'll probably need a paid account that supports up to 10 MB Workers.

Comment options

I have added some wasm optimization to FFmpeg
https://github.com/FFmpeg/FFmpeg/commits?author=quink-black

And it's easy to build and run upstream FFmpeg with wasi
https://github.com/quink-black/ffmpeg-ci/blob/master/wasi_ffmpeg.sh

Comment options

Surprised its so hard to deploy ffmpeg to cloudflare worker given that it is an obvious use case!

Comment options

For the case of browser extension, I got it working by using the offscreen API
https://github.com/sebastianwd/redditgrab/blob/master/entrypoints/background.ts#L98

You must be logged in to vote
0 replies
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

AltStyle によって変換されたページ (->オリジナル) /