ffmpegwasm / ffmpeg.wasm

FFmpeg for browser, powered by WebAssembly
https://ffmpegwasm.netlify.app
MIT License
13.63k stars 787 forks source link

SecurityError: Failed to construct 'Worker' #560

Open HeAmazigh opened 11 months ago

HeAmazigh commented 11 months ago

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):

jeromewu commented 11 months ago

Need Angular expert to help on this one.

DeepHorizons commented 11 months ago

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.

LostBeard commented 10 months ago

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

fromage9747 commented 9 months ago

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

DeepHorizons commented 9 months ago

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

fromage9747 commented 9 months ago

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

DeepHorizons commented 9 months ago

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

RoloufGoudebin commented 9 months ago

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!

DeepHorizons commented 9 months ago

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

fromage9747 commented 9 months ago

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

RoloufGoudebin commented 9 months ago

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

DASMACHETE commented 4 months ago

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/core-mt@0.12.6/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);
  }