ffmpeg.wasm
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"
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:
- Go to chrome://flags/ and enable Experimental JavaScript shared memory features (aka. SharedArrayBuffers)
- yarn build --mode production in order to build the app
- yarn preview to run the frontend app on default local port 4173
- 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)]
Cross-Origin-Opener-Policy: same-origin
Cross-Origin-Embedder-Policy: require-corp
add the headers to your server response
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 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();
});
},
},
Also I don't wanna to hurt other third party apis like firebase storage
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.
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
此外,我不想伤害其他第三方 API,例如 firebase 存储
After adding, the iframe and server images cannot be accessed. How can I solve this problem