Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Export ffmpeg-core.worker.js for core package #767

Open
higgins opened this issue Jul 19, 2024 · 2 comments
Open

Export ffmpeg-core.worker.js for core package #767

higgins opened this issue Jul 19, 2024 · 2 comments

Comments

@higgins
Copy link

higgins commented Jul 19, 2024

In order to run the single threaded worker, we need to either serve the built worker.js file and its dependencies on the domain where the worker will be instantiated OR blobify (via toBlobURL()) a compiled worker asset.

The core-mt package makes this possible via:

const baseURL = 'https://unpkg.com/@ffmpeg/[email protected]/dist/esm'  
ffmpeg = new FFmpeg();
const [coreURL, wasmURL, workerURL] = await Promise.all([
  toBlobURL(`${baseURL}/ffmpeg-core.js`, 'text/javascript'),
  toBlobURL(`${baseURL}/ffmpeg-core.wasm`, 'application/wasm'),
  toBlobURL(`${baseURL}/ffmpeg-core.worker.js`, 'text/javascript'),
]);
await ffmpeg.load({ coreURL, wasmURL, workerURL, classWorkerURL: workerURL });

but since the core package does not produce this ffmpeg-core.worker.js artifact, we have to create our own (basically a concatenation of worker.js + const.js + errors.js -> ffmpeg-core.worker.js)

Describe the solution you'd like
Like you're already doing with the core-mt package, create and publish a ffmpeg-core.worker.js artifact for the single threaded core package.

Describe alternatives you've considered

  1. We're not ready to try the multithreaded solution
  2. The workaround noted here about hosting the worker.js, const.js and errors.js files on the our domain is error prone

Additional context
We think this is a reasonable alternative to perhaps bigger refactors proposed elsewhere: #617

Thank you for this great library and for your time and attention!

@ghnp5
Copy link

ghnp5 commented Jul 28, 2024

Hey

I'm struggling a lot to get this working (using core) if I want to serve all files from my own server.
If I don't set any of the "blob URLs", it works perfectly, but it fetches all files from unpkg.com, which I don't want.

However, once I start giving my own URLs and converting to blob URLs, both dev and prod start crashing for errors that are hard to understand.

For example,

throw ERROR_IMPORT_FAILURE;

it just throws this error, but it would be nice if it returned the exception itself. I've no way to know why it's crashing, and DevTools don't let me go there either, since it's a module. The catch isn't even setting the exception into a variable...

--

Anyway - reading your Issue above, are you saying that coreURL, wasmURL, workerURL only work for core-mt and not core?

I was looking at the code, and it seems that only coreURL is really used. It's very hard to follow.

But I was setting workerURL as the file that already exists, @ffmpeg/ffmpeg/dist/umd/814.ffmpeg.js. Is this not the one?
It seems to contain the 3 files you mentioned, but compressed/minified.

And the code references it as being bundled by webpack:

this.#worker = classWorkerURL ?
new Worker(new URL(classWorkerURL, import.meta.url), {
type: "module",
}) :
// We need to duplicated the code here to enable webpack
// to bundle worekr.js here.
new Worker(new URL("./worker.js", import.meta.url), {
type: "module",
});

I'm so confused!!

@ghnp5
Copy link

ghnp5 commented Jul 29, 2024

Alright... it was very hard to get this working when you want to host all the files, but I was able in the end.

There are indeed issues with the way the worker loads and gets bundled, so I had to create some patches in the gulpfile.

And it's not easy at all to debug errors happening in the ffmpeg modules, especially due to a catch that ignores the exception completely, making it impossible to know why it failed!

Here's how I have it, for now...

const loadFFmpeg = async () => {
	const coreURL = await toBlobURL(`${baseURL}/ffmpeg-core.js`, 'text/javascript');
	const workerURL = await toBlobURL(`${baseURL}/ffmpeg-worker.js`, 'text/javascript');
	const wasmURL = await toBlobURL(`${baseURL}/ffmpeg-core.wasm`, 'application/wasm');

	const ffmpeg = new FFmpeg();
	await ffmpeg.load({
		coreURL,
		wasmURL,
		workerURL
	});

	return ffmpeg;
};

Then these replaces in the gulpfile, against the main bundle...

.replace('r?new Worker(new URL(r,"."),{type:"module"}):new Worker(new URL(t.p+t.u(138),t.b),{type:void 0})', 'new Worker(r,{type:void 0})')
.replace('classWorkerURL:r', 'workerURL:r')

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants