From ad665df8173632af040830c721601122a9b63fd5 Mon Sep 17 00:00:00 2001 From: JacobiusMakes Date: Fri, 27 Mar 2026 01:17:11 -0400 Subject: [PATCH] feat: allow passing binary data directly to FFmpeg.load() Add support for passing ArrayBuffer, Uint8Array, or Blob directly to load() via new coreData, wasmData, and workerData config options. When provided, binary data takes precedence over URL strings and is converted to Blob URLs internally, enabling use cases where fetch is unavailable (e.g. userscripts with CORS restrictions). Closes #865 Co-Authored-By: Claude Sonnet 4.6 --- packages/ffmpeg/src/classes.ts | 27 +++++++++++++++++++++++++-- packages/ffmpeg/src/types.ts | 22 ++++++++++++++++++++++ 2 files changed, 47 insertions(+), 2 deletions(-) diff --git a/packages/ffmpeg/src/classes.ts b/packages/ffmpeg/src/classes.ts index 48d9e2c4a42..9d38f3bfa17 100644 --- a/packages/ffmpeg/src/classes.ts +++ b/packages/ffmpeg/src/classes.ts @@ -1,5 +1,6 @@ -import { FFMessageType } from "./const.js"; +import { FFMessageType, MIME_TYPE_JAVASCRIPT, MIME_TYPE_WASM } from "./const.js"; import { + BinaryFileData, CallbackData, Callbacks, FSNode, @@ -20,6 +21,16 @@ import { import { getMessageID } from "./utils.js"; import { ERROR_TERMINATED, ERROR_NOT_LOADED } from "./errors.js"; +/** + * Convert binary file data (ArrayBuffer, Uint8Array, or Blob) to a Blob URL + * so the web worker can consume it as a regular URL string. + */ +const toBlobURL = (data: BinaryFileData, mimeType: string): string => { + const blob = + data instanceof Blob ? data : new Blob([data], { type: mimeType }); + return URL.createObjectURL(blob); +}; + type FFMessageOptions = { signal?: AbortSignal; }; @@ -185,7 +196,13 @@ export class FFmpeg { * @returns `true` if ffmpeg core is loaded for the first time. */ public load = ( - { classWorkerURL, ...config }: FFMessageLoadConfig = {}, + { + classWorkerURL, + coreData, + wasmData, + workerData, + ...config + }: FFMessageLoadConfig = {}, { signal }: FFMessageOptions = {} ): Promise => { if (!this.#worker) { @@ -200,6 +217,12 @@ export class FFmpeg { }); this.#registerHandlers(); } + // Convert binary data to Blob URLs so the worker can load them as + // regular URL strings. Binary data takes precedence over URL strings. + if (coreData) config.coreURL = toBlobURL(coreData, MIME_TYPE_JAVASCRIPT); + if (wasmData) config.wasmURL = toBlobURL(wasmData, MIME_TYPE_WASM); + if (workerData) + config.workerURL = toBlobURL(workerData, MIME_TYPE_JAVASCRIPT); return this.#send( { type: FFMessageType.LOAD, diff --git a/packages/ffmpeg/src/types.ts b/packages/ffmpeg/src/types.ts index 5ddf97d50e0..7249fc4f818 100644 --- a/packages/ffmpeg/src/types.ts +++ b/packages/ffmpeg/src/types.ts @@ -1,5 +1,12 @@ export type FFFSPath = string; +/** + * Binary file data that can be passed directly instead of a URL. + * When provided, a Blob URL is created internally so the worker + * can consume it as a regular URL. + */ +export type BinaryFileData = ArrayBuffer | Uint8Array | Blob; + /** * ffmpeg-core loading configuration. */ @@ -23,6 +30,21 @@ export interface FFMessageLoadConfig { * @defaultValue `https://cdn.jsdelivr.net/npm/@ffmpeg/core-mt@${CORE_VERSION}/dist/umd/ffmpeg-core.worker.js`; */ workerURL?: string; + /** + * `ffmpeg-core.js` file content as binary data. When provided, takes + * precedence over `coreURL` and a Blob URL is created internally. + */ + coreData?: BinaryFileData; + /** + * `ffmpeg-core.wasm` file content as binary data. When provided, takes + * precedence over `wasmURL` and a Blob URL is created internally. + */ + wasmData?: BinaryFileData; + /** + * `ffmpeg-core.worker.js` file content as binary data. When provided, + * takes precedence over `workerURL` and a Blob URL is created internally. + */ + workerData?: BinaryFileData; /** * `ffmpeg.worker.js` URL. This worker is spawned when FFmpeg.load() is called, it is an essential worker and usually you don't need to update this config. *