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

Chrome with MT fixed and COEP/COOP server! #13

Open
radames opened this issue Sep 7, 2023 · 4 comments
Open

Chrome with MT fixed and COEP/COOP server! #13

radames opened this issue Sep 7, 2023 · 4 comments

Comments

@radames
Copy link

radames commented Sep 7, 2023

Hi @antiboredom, amazing project!
It looks like the issue with ffmpeg wasm MT on Chrome was solved with the latest @ffmpeg/ffmpeg@0.12.6 it worth trying!

const isChrome = navigator.userAgent.match(/chrome|chromium|crios/i);
const baseURL = `https://unpkg.com/@ffmpeg/core${!isChrome ? "-mt" : ""}@0.12.2/dist/esm`;

BTW is you ever need to host static pages with COEP/COOP header HuggingFace Static SDK now support custom headers!!
https://huggingface.co/spaces/radames/OpenAI-CLIP-JavaScript

# README.md
custom_headers:
  cross-origin-embedder-policy: require-corp
  cross-origin-opener-policy: same-origin
  cross-origin-resource-policy: cross-origin

docs: https://huggingface.co/docs/hub/spaces-config-reference#:~:text=can%20be%20embedded.-,custom_headers,-%3A%20Dict%5Bstring
ps. I work there 🤦🏼

@antiboredom
Copy link
Owner

Ah - thanks for the tip - I'll look give it a try!

@antiboredom
Copy link
Owner

@radames - trying this and I'm seeing a bunch of errors with the mt version on chrome. Maybe doing something wrong, but have you by any chance gotten it working?

@radames
Copy link
Author

radames commented Sep 8, 2023

hi @antiboredom, sorry I just ran a test on your repo upgrading the versions and indeed the problem continues 🤔 I'm working on a similar environment on different project, svelte + ffmpeg/wasm, the only difference is I'm running the ffmpeg on a web worker and I'm not getting the issue. Maybe worth trying using an web worker, since it's nice to your main webpage, it won't lock the main thread.
I'll happy to help, can't at the right minute but here are some snippets

@ffmpeg/core-mt@0.12.3
@ffmpeg/ffmpeg@0.12.6
@ffmpeg/util@0.12.1
// ffmpeg.worker.js
import { FFmpeg } from '@ffmpeg/ffmpeg';
import { fetchFile, toBlobURL } from '@ffmpeg/util';

class FFmpegSingleton {
  static instance = null;
  static async getInstance(logger = false) {
    if (this.instance === null) {
      const ffmpeg = new FFmpeg();
      if (ffmpeg === null) {
        throw new Error('ffmpeg is null');
      }
      ffmpeg.on('log', ({ message }) => {
        if (logger) {
          console.log(message);
        }
      });
      ffmpeg.on('progress', ({ progress, time }) => {
        console.log(progress, time);
      });
      const baseURL = `https://unpkg.com/@ffmpeg/core-mt@0.12.3/dist/esm`;
      console.log('baseURL', baseURL);
      await ffmpeg.load({
        coreURL: await toBlobURL(`${baseURL}/ffmpeg-core.js`, 'text/javascript'),
        wasmURL: await toBlobURL(`${baseURL}/ffmpeg-core.wasm`, 'applicaiton/wasm'),
        workerURL: await toBlobURL(`${baseURL}/ffmpeg-core.worker.js`, 'text/javascript')
      });

      this.instance = ffmpeg;
    }
    return this.instance;
  }
}

self.addEventListener('message', async (event) => {
  const { inputURL, inputName, outputName, mimeType, command } = event.data;

  const ffmpeg = await FFmpegSingleton.getInstance(true);
  self.postMessage({
    status: 'progress',
    message: 'writing file'
  });
  const inputFile = await fetchFile(inputURL);
  await ffmpeg.writeFile(inputName, inputFile);
  self.postMessage({
    status: 'progress',
    message: 'running command'
  });
  const cmd = ['-nostdin', '-y', '-i', inputName, ...command, outputName];
  console.log('cmd', cmd);
  await ffmpeg.exec(cmd);

  try {
    self.postMessage({
      status: 'progress',
      message: 'reading file'
    });
    const outputData = await ffmpeg.readFile(outputName);
    const blob = new Blob([outputData.buffer], { type: mimeType });
    const url = URL.createObjectURL(blob);

    self.postMessage({
      status: 'complete',
      output: url
    });
  } catch (e) {
    self.postMessage({
      status: 'error',
      message: 'Error processing ffmpeg command'
    });
  }
});
let ffmpegWorker;
onMount(() => {
    const _ffmpegWorker = await import('$lib/ffmpeg.worker.js?worker');
    ffmpegWorker = new _ffmpegWorker.default();
})
export async function runFFmpeg(worker, videoSrc, filterStr, command, statusCallback) {
  if (!videoSrc) return;
  if (!filterStr) return videoSrc.href;

  return new Promise(async (resolve, reject) => {
    // Create the worker if it does not yet exist.

    const onMessageReceived = (e) => {
      switch (e.data.status) {
        case 'complete':
          const videoURL = e.data.output;
          resolve(videoURL);
          break;
        case 'progress':
          statusCallback(e.data);
          break;
        case 'error':
          reject(e.data);
          break;
      }
    };

    // Attach the callback function as an event listener.
    worker.addEventListener('message', onMessageReceived);
    worker.postMessage({
      inputURL: videoSrc.href,
      inputName: videoSrc.name,
      outputName: 'out.mp4',
      mimeType: 'video/*',
      command: command
    });
  });
}

@antiboredom
Copy link
Owner

@radames thanks - this is super helpful!!!

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