-
-
Notifications
You must be signed in to change notification settings - Fork 1k
-
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); }
Beta Was this translation helpful? Give feedback.
All reactions
Replies: 2 comments 3 replies
-
any news?
Beta Was this translation helpful? Give feedback.
All reactions
-
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:
- WASI
- Building WebAssembly (WASM) for Cloudflare Workers
Interesting links:
Note: To make FFmpeg work on a Cloudflare Worker, you'll probably need a paid account that supports up to 10 MB Workers.
Beta Was this translation helpful? Give feedback.
All reactions
-
👍 1
-
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
Beta Was this translation helpful? Give feedback.
All reactions
-
🚀 1
-
Surprised its so hard to deploy ffmpeg to cloudflare worker given that it is an obvious use case!
Beta Was this translation helpful? Give feedback.
All reactions
-
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
Beta Was this translation helpful? Give feedback.