ffmpeg.wasm icon indicating copy to clipboard operation
ffmpeg.wasm copied to clipboard

SecurityError: Failed to construct 'Worker'

Open HeAmazigh opened this issue 1 year ago • 12 comments

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 Screenshot 2023-08-22 at 11 21 22

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

HeAmazigh avatar Aug 22 '23 10:08 HeAmazigh

Need Angular expert to help on this one.

jeromewu avatar Aug 22 '23 14:08 jeromewu

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.

DeepHorizons avatar Aug 24 '23 19:08 DeepHorizons

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. 👍

LostBeard avatar Sep 01 '23 17:09 LostBeard

@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.

fromage9747 avatar Oct 16 '23 06:10 fromage9747

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 avatar Oct 17 '23 12:10 DeepHorizons

@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.

fromage9747 avatar Oct 17 '23 12:10 fromage9747

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: @.***>

DeepHorizons avatar Oct 17 '23 13:10 DeepHorizons

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!

RoloufGoudebin avatar Oct 17 '23 13:10 RoloufGoudebin

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: @.***>

DeepHorizons avatar Oct 17 '23 15:10 DeepHorizons

@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.

fromage9747 avatar Oct 17 '23 15:10 fromage9747

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

RoloufGoudebin avatar Oct 19 '23 12:10 RoloufGoudebin

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);
  }

DASMACHETE avatar Mar 22 '24 11:03 DASMACHETE