ffmpeg.wasm
ffmpeg.wasm copied to clipboard
SecurityError: Failed to construct 'Worker'
Describe the bug I'm encountering an issue while trying to use the @ffmpeg/ffmpeg library within my Angular project. The problem seems to be related to CORS issues when attempting to access the worker.js file from the library. Despite following the recommended solutions, I'm still facing this problem.
Code
import { Injectable } from '@angular/core';
import { FFmpeg } from '@ffmpeg/ffmpeg';
@Injectable({
providedIn: 'root',
})
export class FfmpegService {
isLoad: boolean = false;
private ffmpeg;
constructor() {
this.ffmpeg = new FFmpeg();
}
async init() {
if (this.isLoad) {
return;
}
this.ffmpeg.on('log', ({ message }) => {
console.log(message);
});
await this.ffmpeg.load();
this.isLoad = true;
}
}
Screenshots
Desktop (please complete the following information):
- Angular version: "^16.1.0"
- Angular CLI: 16.1.8
- Node: 18.17.0
- Package Manager: yarn 1.22.5
- OS: MocOS Catalina version 10.15.7
- @ffmpeg/ffmpeg: "^0.12.5"
- @ffmpeg/util: "^0.12.0"
- Browser(s) affected: Brave v 1.57.47 Chrome v 116.0.5845.96, Firefox v 116.0.3
Need Angular expert to help on this one.
I was able to get the worker to load by editing my local files. It seems the issue comes out of the new URL(...)
object. I'm unsure what it does but it transforms it to a filesystem location when serving the files using ng serve
, which is a different origin than localhost:xxxx
and is a browser security violation.
I served my worker.js
file out of the angular assets, modified the load()
function to not use the new URL(...)
, and hardcoded the location of the worker file into the new Worker(...)
call.
My proposed solution in #562 is to add an extra item to the config to be able to set the URL. It would default to new URL('./worker.js',...)
but allow the developer to specify where we are going to load the worker from explicitly.
I support @DeepHorizons proposed change #562 as it would fix an issue I have to work around in Blazor WASM. I wrote a Blazor WASM wrapper for ffmpeg.wasm and I currently modify ffmpeg.js (umd minified version) by replacing new URL(e.p+e.u(814),e.b)
with r.worker814URL
so that I can specify the worker path with the config argument sent to the ffmpeg.load method... It's a hackier version of what @DeepHorizons has done. 👍
@DeepHorizons I checked out your fork and couldn't find the changes. I see the changes in the PR, but when I make the modifications to my local instance of the library, none of the changes are detected. Made all the necessary configurations to ensure that node_moduels isn't cached, and yet It's still not seeing the change.
Trying to avoid having to create a server to do the necessary FFmpeg work.
Did you check out the branch I was working on? I didn't work on it in master.
I'm not sure how you would test this without a server except maybe for installing it via URL. I don't have a lot of experience with node, would you happen to have some dice you can throw my way. I'd love to test this on my own as well.
On Mon, Oct 16, 2023, 2:58 AM fromage9747 @.***> wrote:
@DeepHorizons https://github.com/DeepHorizons I checked out your fork and couldn't find the changes. I see the changes in the PR, but when I make the modifications to my local instance of the library, none of the changes are detected. Made all the necessary configurations to ensure that node_moduels isn't cached, and yet It's still not seeing the change.
Trying to avoid having to create a server to do the necessary FFmpeg work.
— Reply to this email directly, view it on GitHub https://github.com/ffmpegwasm/ffmpeg.wasm/issues/560#issuecomment-1763847415, or unsubscribe https://github.com/notifications/unsubscribe-auth/ABKLJKKYIT3ESXNVWSWRFWLX7TLH3ANCNFSM6AAAAAA3ZXDGTI . You are receiving this because you were mentioned.Message ID: @.***>
@DeepHorizons Just to be clear, this library does not allow for ffmpeg to be used within Angular and still requires an external server?
I thought this allowed for FFMpeg to be run within the browser.
For now, I have found a workaround to what I was trying to achieve. Ability to download and save a stream from m3u8.
It has to be served under the same origin as the page as that's the issue at hand. You can use the same http server you use to serve the pages. For my testing I put the worker.js file in my assets folder and referenced the equivalent http path, then used "ng serve" to host the application.
On Tue, Oct 17, 2023, 8:41 AM fromage9747 @.***> wrote:
@DeepHorizons https://github.com/DeepHorizons Just to be clear, this library does not allow for ffmpeg to be used within Angular and still requires an external server?
I thought this allowed for FFMpeg to be run within the browser.
For now, I have found a workaround to what I was trying to achieve. Ability to download and save a stream from m3u8.
— Reply to this email directly, view it on GitHub https://github.com/ffmpegwasm/ffmpeg.wasm/issues/560#issuecomment-1766339619, or unsubscribe https://github.com/notifications/unsubscribe-auth/ABKLJKIR2Y347G24ZVZI66DX7Z4IHAVCNFSM6AAAAAA3ZXDGTKVHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHMYTONRWGMZTSNRRHE . You are receiving this because you were mentioned.Message ID: @.***>
Hello,
I'm facing a similar issue. I've implemented your fix, but when I import my worker.js, nothing happens (the path is correct). If I provide an incorrect path, there's still no response. Here's my code:
async load() {
console.log("ffmpeg loading");
await this.ffmpeg.load({
workerLoadURL: 'http://localhost:8100/worker/worker.js',
});
this.loaded = true;
console.log('ffmpeg loaded');
}
Would appreciate any insights or assistance on this matter. Thank you!
I think you need to have the URL be relative to your origin. For example I copied the ffmpeg folder into my assets folder and referenced it like so.
"/assets/js/ffmpeg/ffmpeg/dist/esm/worker.js"
It may take some poking around but you should be able to go to that page directly and see the code on a browser.
On Tue, Oct 17, 2023, 9:52 AM RoloufGoudebin @.***> wrote:
Hello,
I'm facing a similar issue. I've implemented your fix, but when I import my worker.js, nothing happens (the path is correct). If I provide an incorrect path, there's still no response. Here's my code:
async load() { console.log("ffmpeg loading"); await this.ffmpeg.load({ workerLoadURL: 'http://localhost:8100/worker/worker.js', }); this.loaded = true; console.log('ffmpeg loaded');}
Would appreciate any insights or assistance on this matter. Thank you!
— Reply to this email directly, view it on GitHub https://github.com/ffmpegwasm/ffmpeg.wasm/issues/560#issuecomment-1766465899, or unsubscribe https://github.com/notifications/unsubscribe-auth/ABKLJKNMF54BGESPOXMVT3DX72ERFAVCNFSM6AAAAAA3ZXDGTKVHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHMYTONRWGQ3DKOBZHE . You are receiving this because you were mentioned.Message ID: @.***>
@RoloufGoudebin I had the same issue.
If you check the JavaScript in your browser you might find that it hasn't loaded your changes. At least that is what I experienced.
Hello,
Thanks for your answers but it doesn't work yet. I can see that the worker is load but it does nothing. @DeepHorizons do you have a working example to see what I am doing wrong ?
Thanks a lot
Are there any news to get this working on angular 16 or 17?
What i tried: Basic Example from Docs... 548 - @LostBeard Answer
My code: Changed the workerUrl to classWorkerURL. Now the Error is gone but the loading never finishes, my code:
ngOnInit(): void {
this.load();
}
baseURL = 'https://unpkg.com/@ffmpeg/[email protected]/dist/esm';
ffmpeg = new FFmpeg();
async load() {
const config = {
coreURL: await this.toBlobURLV2(
`${this.baseURL}/ffmpeg-core.js`,
'text/javascript',
),
wasmURL: await this.toBlobURLV2(
`${this.baseURL}/ffmpeg-core.wasm`,
'application/wasm',
),
classWorkerURL: await this.toBlobURLV2(
`${this.baseURL}/ffmpeg-core.worker.js`,
'text/javascript',
),
};
console.log('worked');
if (this.ffmpeg) {
console.log('turning ffmpeg on');
this.ffmpeg.on('log', ({ message }) => {
console.log(message);
});
}
if (this.ffmpeg) {
console.log('loading', config);
await this.ffmpeg.load(config).catch((error: Error) => {
console.log(error);
});
console.log('cfg loaded');
}
this.loaded = true;
console.log('ffmpeg.load success');
}
async toBlobURLV2(url: string, mimeType: string) {
console.log(url);
var resp = await fetch(url);
var body = await resp.blob();
var blob = new Blob([body], { type: mimeType });
return window.URL.createObjectURL(blob);
}