Closed gaurav10610 closed 3 months ago
Similar issue here. It appears that @ffmpeg/ffmpeg
must be imported from the same domain as the user's script. I am trying to import it from unpkg in a plain simple html+js page, not a single thing will make it work.
So it looks to me like this is not an Angular issue. Although for me the error is about dist/umd/814.ffmpeg.js
rather than dist/esm/worker.js
:
DOMException: Failed to construct 'Worker': Script at 'https://unpkg.com/@ffmpeg/ffmpeg/dist/umd/814.ffmpeg.js' cannot be accessed from origin 'http://localhost:8000'.
If i merely download the contents of @ffmpeg/ffmpeg
and serve them myself, then it works properly, even importing util
, core
and core-mt
from unpkg. The only issue is @ffmpeg/ffmpeg
.
How simpler were the days without cors and domexception
so because of this line:
https://github.com/ffmpegwasm/ffmpeg.wasm/blob/1b2f5f14f5b4eeecb0c95588c0c337274eca7405/packages/ffmpeg/src/classes.ts#L166
and the above explanation on stackoverflow, you need headers or whatever other kind of bullshit on the domain hosting @ffmpeg/ffmpeg
. So unpkg will NOT work AT ALL...
@Willy-JL
Same issue using ffmpeg.wasm with Blazor WASM, but using ffmpeg files from unpkg does work after a simple patch (very similar to pull #562)
I am able to use unpkg as the host for all of the ffmpeg files (umd version) using Blob and URL.createObjectURL. But I do have to modify the ffmpeg.js code slightly to do it. In fact, that line you mentioned is the part I have to modify so that I can specify the URL that the worker is created with in the config passed to ffmpeg.load
. The code patch can easily be done on the fly before creating the Blob using a single text replacement. If pull #562 gets merged, or at least a similar fix enabled, I won't need to modify ffmpeg.js at all and neither will others with similar issues like yours.
In the umd version of ffmpeg.js change
new Worker(new URL(e.p+e.u(814),e.b),{type:void 0})
to
new Worker(r.worker814URL,{type:void 0})
.
Once it is patched you can create a BlobURL of it and then call import
on that BlobURL.
Then create a BlobURL of 814.ffmpeg.js and add it to the config you send to ffmpeg.load as the property worker814URL
.
No extra headers are needed from the unpkg site to use the ffmpeg files directly from them. Your server hosting your html file does need additional headers if you wish to use multithreading due to the requirements of SharedArrayBuffer. SharedArrayBuffer on MDN. I have tested the multithreaded version also using unpkg as the ffmpeg cdn and it works also.
If you think patch #562, which allows the path for the primary worker to be set via the config sent to ffmpeg.load
may help resolve your issue also please go give it a thumbs up.
Working code example that does on the fly patching of ffmpeg.js and uses unpkg for all ffmpeg.wasm files.
The below code must be served via http:// or https:// but will not work if served via file://
index.html
<html>
<head>
<script src="index.js"></script>
</head>
<body>
<video autoplay muted id="video-result" controls></video><br/>
<button disabled id="load-button">Load ffmpeg-core (~31 MB)</button><br/>
<button disabled id="transcode-button">Transcode webm to mp4</button><br/>
<p id="log-div"></p>
<p>Open Developer Tools (Ctrl+Shift+I) to View Logs</p>
</body>
</html>
index.js
"use strict";
var loaded = false;
var ffmpeg = null;
var loadBtn = null;
var transcodeBtn = null;
var logDiv = null;
var videoEl = null;
const toBlobURLPatched = async (url, mimeType, patcher) => {
var resp = await fetch(url);
var body = await resp.text();
if (patcher) body = patcher(body);
var blob = new Blob([body], { type: mimeType });
return URL.createObjectURL(blob);
};
const toBlobURL = async (url, mimeType,) => {
var resp = await fetch(url);
var body = await resp.blob();
var blob = new Blob([body], { type: mimeType });
return URL.createObjectURL(blob);
};
const fetchFile = async (url) => {
var resp = await fetch(url);
var buffer = await resp.arrayBuffer();
return new Uint8Array(buffer);
};
const load = async () => {
loadBtn.setAttribute('disabled', true);
const baseURLFFMPEG = 'https://unpkg.com/@ffmpeg/ffmpeg@0.12.6/dist/umd'
const ffmpegBlobURL = await toBlobURLPatched(`${baseURLFFMPEG}/ffmpeg.js`, 'text/javascript', (js) => {
return js.replace('new URL(e.p+e.u(814),e.b)', 'r.worker814URL');
});
const baseURLCore = 'https://unpkg.com/@ffmpeg/core@0.12.3/dist/umd'
const config = {
worker814URL: await toBlobURL(`${baseURLFFMPEG}/814.ffmpeg.js`, 'text/javascript'),
coreURL: await toBlobURL(`${baseURLCore}/ffmpeg-core.js`, 'text/javascript'),
wasmURL: await toBlobURL(`${baseURLCore}/ffmpeg-core.wasm`, 'application/wasm'),
};
await import(ffmpegBlobURL);
ffmpeg = new FFmpegWASM.FFmpeg();
ffmpeg.on('log', ({ message }) => {
logDiv.innerHTML = message;
console.log(message);
});
await ffmpeg.load(config);
loaded = true;
console.log('ffmpeg.load success');
transcodeBtn.removeAttribute('disabled');
}
const transcode = async () => {
transcodeBtn.setAttribute('disabled', true);
await ffmpeg.writeFile('input.webm', await fetchFile('https://raw.githubusercontent.com/ffmpegwasm/testdata/master/Big_Buck_Bunny_180_10s.webm'));
await ffmpeg.exec(['-i', 'input.webm', 'output.mp4']);
const data = await ffmpeg.readFile('output.mp4');
videoEl.src = URL.createObjectURL(new Blob([data.buffer], { type: 'video/mp4' }));
}
addEventListener("load", async (event) => {
loadBtn = document.querySelector('#load-button');
loadBtn.addEventListener('click', async () => await load());
loadBtn.removeAttribute('disabled');
transcodeBtn = document.querySelector('#transcode-button');
transcodeBtn.addEventListener('click', async () => await transcode());
logDiv = document.querySelector('#log-div');
videoEl = document.querySelector('#video-result');
console.log('window loaded');
});
In webpack, this issue is still exists. @jeromewu
Not sure if this has reference value: https://webpack.docschina.org/guides/asset-modules/#url-assets
Hi. I've described the solution here)
Describe the bug [Angular] Encountering the following error in an angular application while the app is locally served(npm serve) - Error: Failed to construct 'Worker': Script at 'file:///some-location/node_modules/@ffmpeg/ffmpeg/dist/esm/worker.js'
To Reproduce
Expected behavior FFmpeg should be loaded correctly
Screenshots
Desktop (please complete the following information):
Additional Information: Also, if we can have a small example added for Angular in the examples section then it will be really great. Thanks!