From e801023beba4f27b52d9e997571114c3043f8b21 Mon Sep 17 00:00:00 2001 From: 3dtours Date: Mon, 27 Jul 2026 14:48:58 +0700 Subject: [PATCH] =?UTF-8?q?fix:=20locateFile=20cho=20FluidSynth=20WASM=20m?= =?UTF-8?q?odule=20(d=C3=B9ng=20self-host/CDN)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Module script (type=module) có document.currentScript === null, nên libfluidsynth không thể tự locate .wasm file. Fix: pass locateFile() trả về URL .wasm tương ứng với URL .js đã load. fluidsynthLoader.js: expose __FluidSynthLocateWasm() trả về FLUIDSYNTH_JS_URL.replace('.js', '.wasm'). Dùng polling setInterval thay vì resolve callback cho đáng tin cậy hơn. soundfontPlayer.js: pass locateFile factory khi gọi factory. --- app/static/js/services/fluidsynthLoader.js | 46 ++++++++++++++-------- app/static/js/services/soundfontPlayer.js | 9 ++++- 2 files changed, 38 insertions(+), 17 deletions(-) diff --git a/app/static/js/services/fluidsynthLoader.js b/app/static/js/services/fluidsynthLoader.js index ce9f229..d83cce9 100644 --- a/app/static/js/services/fluidsynthLoader.js +++ b/app/static/js/services/fluidsynthLoader.js @@ -1,23 +1,37 @@ -window.__FluidSynthReady = new Promise(function (resolve) { - var FLUIDSYNTH_SRC; +(function () { + if (window.__FluidSynthReady) return; + + var FLUIDSYNTH_JS_URL; + var FLUIDSYNTH_WASM_URL; if (window.__FLUIDSYNTH_CDN) { - FLUIDSYNTH_SRC = window.__FLUIDSYNTH_CDN; + FLUIDSYNTH_JS_URL = window.__FLUIDSYNTH_CDN; } else if (window.location.hostname === 'localhost' || window.location.hostname === '127.0.0.1') { - FLUIDSYNTH_SRC = 'https://cdn.jsdelivr.net/npm/@enikey87/fluidsynth-emscripten@0.1.1/dist/libfluidsynth-2.3.0-sf3.js'; + FLUIDSYNTH_JS_URL = 'https://cdn.jsdelivr.net/npm/@enikey87/fluidsynth-emscripten@0.1.1/dist/libfluidsynth-2.3.0-sf3.js'; } else { - FLUIDSYNTH_SRC = '/static/js/vendor/libfluidsynth-2.3.0-sf3.js'; + FLUIDSYNTH_JS_URL = '/static/js/vendor/libfluidsynth-2.3.0-sf3.js'; } - var script = document.createElement('script'); - script.type = 'module'; - script.textContent = [ - 'import FluidsynthModule from "' + FLUIDSYNTH_SRC + '";', - 'window.__FluidSynthModuleFactory = FluidsynthModule;', - 'window.__FluidSynthReadyResolver = function() { window.__FluidSynthReadyResolve(); };', - 'console.log("[FluidSynth] Loaded from:", "' + FLUIDSYNTH_SRC + '");' - ].join('\n'); - document.head.appendChild(script); + FLUIDSYNTH_WASM_URL = FLUIDSYNTH_JS_URL.replace(/\.js$/, '.wasm'); - window.__FluidSynthReadyResolve = resolve; -}); + window.__FluidSynthLocateWasm = function () { return FLUIDSYNTH_WASM_URL; }; + + window.__FluidSynthReady = new Promise(function (resolve) { + var script = document.createElement('script'); + script.type = 'module'; + script.textContent = [ + 'import FluidsynthModule from "' + FLUIDSYNTH_JS_URL + '";', + 'window.__FluidSynthModuleFactory = FluidsynthModule;', + 'console.log("[FluidSynth] Loaded:", "' + FLUIDSYNTH_JS_URL + '");' + ].join('\n'); + document.head.appendChild(script); + + var check = setInterval(function () { + if (window.__FluidSynthModuleFactory) { + clearInterval(check); + resolve(); + } + }, 50); + setTimeout(function () { clearInterval(check); resolve(); }, 15000); + }); +})(); diff --git a/app/static/js/services/soundfontPlayer.js b/app/static/js/services/soundfontPlayer.js index d750ca2..f040c13 100644 --- a/app/static/js/services/soundfontPlayer.js +++ b/app/static/js/services/soundfontPlayer.js @@ -73,7 +73,14 @@ } console.log("[SonicSF] Initializing FluidSynth WASM Engine..."); - _fluidModule = await window.__FluidSynthModuleFactory(); + _fluidModule = await window.__FluidSynthModuleFactory({ + locateFile: function (path) { + if (path.endsWith('.wasm')) { + return window.__FluidSynthLocateWasm ? window.__FluidSynthLocateWasm() : path; + } + return path; + } + }); if (!_fluidModule || !_fluidModule._new_fluid_settings) { throw new Error("FluidSynth WASM module loaded but API missing");