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

SharedArrayBuffer is not defined in "vite preview" mode while it works fine in "vite" mode with @ffmpeg/core": "^0.11.0"

Open htcongvn opened this issue 2 years ago • 7 comments

Describe the bug

  • Set up a vanilla React Typescript based project using Vitejs.
  • Make up two React components RecordMessage that uses react-media-recorder-2, and Controller that uses @ffmpeg/ffmpeg.

The files are as below.

  • RecordMessage.tsx:
import { ReactMediaRecorder } from "react-media-recorder-2";
....
<ReactMediaRecorder
      audio
      onStop={handleStop}
.... />
  • Controller.tsx:
....
import { createFFmpeg } from "@ffmpeg/ffmpeg";
....
const handleStop = async (blobUrl: string) => {
....
fetch(blobUrl)
      .then((res) => res.blob())
      .then(async (blob) => {
        const ffmpeg = createFFmpeg({
          corePath: "http://localhost:" + import.meta.env.VITE_APP_PORT + "/ffmpeg-core.js",
          wasmPath: "http://localhost:" + import.meta.env.VITE_APP_PORT + "/ffmpeg-core.wasm",
          workerPath: "http://localhost:" + import.meta.env.VITE_APP_PORT + "/ffmpeg-core.worker.js",
          log: true,
        });

        // This loads up the ffmpeg.wasm files from CDN
        await ffmpeg.load();

        //  wav to mp3.... will be from api to come back
        const arrayBuffer = await blob.arrayBuffer();
        const uint8Array = new Uint8Array(arrayBuffer);
        ffmpeg.FS("writeFile", "rachelMessage.wav", uint8Array);
        await ffmpeg.run("-i", "rachelMessage.wav", "rachelMessage.mp3");
        const data = ffmpeg.FS("readFile", "rachelMessage.mp3");

        const convertedBlob = data.buffer;
        const audio = new Audio();
        audio.src = createBlobUrl(convertedBlob);
....
  • vite.config.ts:
import { defineConfig } from "vite";
import react from "@vitejs/plugin-react";
// https://vitejs.dev/config/
export default defineConfig({
  plugins: [
    react(),
    {
      name: "configure-response-headers",
      configureServer: (server) => {
        server.middlewares.use((_req, res, next) => {
          res.setHeader("Cross-Origin-Embedder-Policy", "require-corp");
          res.setHeader("Cross-Origin-Opener-Policy", "same-origin");
          next();
        });
      },
    },
  ],
  build: {
    manifest: true,
    minify: false,
  },
});
  • .env.production: VITE_APP_PORT=4173

  • package.js:

{
  "name": "react-ts-vite sample",
  "private": true,
  "version": "0.0.0",
  "type": "module",
  "scripts": {
    "dev": "vite",
    "build": "tsc && vite build",
    "preview": "vite preview"
  },
  "dependencies": {
    "@ffmpeg/core": "^0.11.0",
    "@ffmpeg/ffmpeg": "^0.11.6",
    "axios": "^1.4.0",
    "react": "^18.2.0",
    "react-dom": "^18.2.0",
    "react-media-recorder-2": "^1.6.23"
  },
  "devDependencies": {
    "@types/react": "^18.0.15",
    "@types/react-dom": "^18.0.6",
    "@vitejs/plugin-react": "^2.0.0",
    "autoprefixer": "^10.4.14",
    "postcss": "^8.4.23",
    "tailwindcss": "^3.3.2",
    "typescript": "^5.0.4",
    "vite": "^4.3.0"
  }
}

To Reproduce Steps to reproduce the behavior:

  1. Go to chrome://flags/ and enable Experimental JavaScript shared memory features (aka. SharedArrayBuffers)
  2. yarn build --mode production in order to build the app
  3. yarn preview to run the frontend app on default local port 4173
  4. See error on the Chrome browser's console when go to at http://localhost:4173/ :
[info] use ffmpeg.wasm v0.11.6
[info] load ffmpeg-core
[info] loading ffmpeg-core
SharedArrayBuffer is not defined

Expected behavior ffmpeg-core and SharedArrayBuffer is defined as it was in "yarn dev" mode. And the browser console log should look like below:

[info] use ffmpeg.wasm v0.11.6
[info] load ffmpeg-core
[info] loading ffmpeg-core
[info] ffmpeg-core loaded
[info] run FS.writeFile rachelMessage.wav <2901 bytes binary file>
[info] run ffmpeg command: -i rachelMessage.wav rachelMessage.mp3
[fferr] ffmpeg version 9e96b1c Copyright (c) 2000-2020 the FFmpeg developers
....

Desktop (please complete the following information):

  • Browser [ chrome Version 113.0.5672.126 (Official Build) (x86_64)]

htcongvn avatar May 30 '23 07:05 htcongvn

Cross-Origin-Opener-Policy: same-origin
Cross-Origin-Embedder-Policy: require-corp

add the headers to your server response

rambo-panda avatar Aug 04 '23 03:08 rambo-panda

This is the vite.config.ts that should fix it:

export default {
  server: {
    headers: {
      "Cross-Origin-Embedder-Policy": "require-corp",
      "Cross-Origin-Opener-Policy": "same-origin",
    }
  }
}

mattiaz9 avatar Aug 09 '23 06:08 mattiaz9

@mattiaz9 can you provide me configuration for vue.config.js but it is causing issue in production again

 configureWebpack: {
        devServer: {
            onBeforeSetupMiddleware: ({ app }) => {
              app.use((_, res, next) => {
                res.setHeader("Cross-Origin-Opener-Policy", "same-origin");
                res.setHeader("Cross-Origin-Embedder-Policy", "require-corp");
                next();
              });
            },
          },

deepaksharmaongraph avatar Oct 03 '23 14:10 deepaksharmaongraph

Also I don't wanna to hurt other third party apis like firebase storage

deepaksharmaongraph avatar Oct 03 '23 14:10 deepaksharmaongraph

I added those headers and confirmed that they are being added in the Chrome dev console. However, I still get the "SharedArrayBuffer is not defined" error.

Update: I cleared the browser cache and that fixed it.

ijt avatar Dec 15 '23 16:12 ijt

Cross-Origin-Opener-Policy: same-origin
Cross-Origin-Embedder-Policy: require-corp

将标头添加到服务器响应

After adding, the iframe and server images cannot be accessed. How can I solve this problem

syjf avatar Apr 18 '24 10:04 syjf

此外,我不想伤害其他第三方 API,例如 firebase 存储

After adding, the iframe and server images cannot be accessed. How can I solve this problem

syjf avatar Apr 18 '24 10:04 syjf