fix(denoise): ship the DeepFilterNet 3 worklet as a file so it starts in the desktop app
CI / Build & Quality Checks (push) Skipped
CI / Secret scan (gitleaks) (push) Skipped
CI / Playwright smoke (e2e) (push) Skipped
CI / Secret scan (gitleaks) (pull_request) Successful in 32s
CI / Build & Quality Checks (pull_request) Successful in 3m17s
CI / Trigger Desktop Build (pull_request) Skipped
CI / Docker image build & smoke test (pull_request) Skipped
CI / Playwright smoke (e2e) (pull_request) Successful in 18m41s
CI / Build & Quality Checks (push) Skipped
CI / Secret scan (gitleaks) (push) Skipped
CI / Playwright smoke (e2e) (push) Skipped
CI / Secret scan (gitleaks) (pull_request) Successful in 32s
CI / Build & Quality Checks (pull_request) Successful in 3m17s
CI / Trigger Desktop Build (pull_request) Skipped
CI / Docker image build & smoke test (pull_request) Skipped
CI / Playwright smoke (e2e) (pull_request) Successful in 18m41s
Reported: DeepFilterNet 3 "did not start" in a desktop call. Console: "Loading the script blob:http://127.0.0.1:44548/… violates … script-src", then "[lotus] denoise setProcessor failed … Failed to load worklet module". deepfilternet3-noise-filter inlines its AudioWorklet as a string and loads it from a blob: URL; audio worklets fall under script-src, and the desktop CSP has no blob: there (the web call page has no script-src, so web was fine). Instead of loosening the CSP, the build now writes the inline worklet to denoise/deepfilternet/dfn-worklet.js and patches the copied module to load it by URL (script-src self). The build fails if the library changes shape. Verified in Chromium under the exact desktop CSP with the built assets: before, DeepFilterNet fails as reported; after, it creates its node and, fed 4 s of white noise, cuts it by 60 dB (its configured level). RNNoise, Speex and DTLN load as before. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_017PCb59uY3UKqDqt7B6hzd5
This commit is contained in:
co-authored by
Claude Opus 5.5
parent
843a48dd10
commit
e8a04fee20
@@ -136,6 +136,36 @@ function denoiseSources() {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// deepfilternet3-noise-filter inlines its AudioWorklet as a string and loads it
|
||||||
|
// from a blob: URL. Audio worklets fall under script-src, and the desktop app's
|
||||||
|
// CSP (rightly) has no blob: there, so DeepFilterNet 3 failed to start ("denoise
|
||||||
|
// setProcessor failed … Failed to load worklet module script: blob:…"). Write
|
||||||
|
// the worklet out as a real file next to the module and load it by URL instead,
|
||||||
|
// which script-src 'self' allows everywhere. Fails the build if the library's
|
||||||
|
// shape changes, rather than shipping a model that cannot start.
|
||||||
|
const DFN_WORKLET_FILE = 'dfn-worklet.js';
|
||||||
|
const DFN_BLOB_LOAD = ` const blob = new Blob([workletCode], { type: 'application/javascript' });
|
||||||
|
const blobUrl = URL.createObjectURL(blob);
|
||||||
|
await audioContext.audioWorklet.addModule(blobUrl);`;
|
||||||
|
function dfnWorkletToFile(esmPath) {
|
||||||
|
const src = fs.readFileSync(esmPath, 'utf8');
|
||||||
|
const literal = src.match(/^var workletCode = (".*");\s*$/m)?.[1];
|
||||||
|
const code = literal ? JSON.parse(literal) : undefined;
|
||||||
|
if (!code?.includes('registerProcessor(') || !src.includes(DFN_BLOB_LOAD)) {
|
||||||
|
throw new Error(
|
||||||
|
`[lotus-denoise] deepfilternet3-noise-filter changed shape (inline worklet / blob loader not found in ${esmPath}) — build aborted; update dfnWorkletToFile in vite.config.js.`,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
fs.writeFileSync(path.join(path.dirname(esmPath), DFN_WORKLET_FILE), code);
|
||||||
|
fs.writeFileSync(
|
||||||
|
esmPath,
|
||||||
|
src.replace(
|
||||||
|
DFN_BLOB_LOAD,
|
||||||
|
` // [lotus] Loaded from a file, not a blob: URL (CSP script-src 'self').\n await audioContext.audioWorklet.addModule(new URL('./${DFN_WORKLET_FILE}', import.meta.url).href);`,
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
// Lotus ML noise suppression: ship the denoise worklets/wasm/models alongside
|
// Lotus ML noise suppression: ship the denoise worklets/wasm/models alongside
|
||||||
// the vendored Element Call bundle. Runs after viteStaticCopy has populated
|
// the vendored Element Call bundle. Runs after viteStaticCopy has populated
|
||||||
// dist/public/element-call (closeBundle order). [Gitea #293] The dev server
|
// dist/public/element-call (closeBundle order). [Gitea #293] The dev server
|
||||||
@@ -212,6 +242,7 @@ function lotusDenoise() {
|
|||||||
fs.mkdirSync(path.dirname(d), { recursive: true });
|
fs.mkdirSync(path.dirname(d), { recursive: true });
|
||||||
fs.copyFileSync(s, d);
|
fs.copyFileSync(s, d);
|
||||||
});
|
});
|
||||||
|
dfnWorkletToFile(path.join(denoiseDir, 'deepfilternet/index.esm.js'));
|
||||||
|
|
||||||
// [lotus] DENOISE CUTOVER: the getUserMedia shim is no longer injected.
|
// [lotus] DENOISE CUTOVER: the getUserMedia shim is no longer injected.
|
||||||
// Our forked Element Call now runs ML denoise in-source as a real LiveKit
|
// Our forked Element Call now runs ML denoise in-source as a real LiveKit
|
||||||
|
|||||||
Reference in New Issue
Block a user