Windows support: cross-built NSIS installer

- toFileURL and path-basename handling made Windows-safe (backslashes,
  drive letters) so media/model loading works there
- Blender discovery scans Program Files\Blender Foundation; ffmpeg
  candidates include common Windows paths
- build config: win/nsis target (x64, custom install dir), build/icon.ico
  generated from the 1024 png, dist:win script
Cross-compiled from macOS: dist/DJ Visualizer Setup 1.6.0.exe (95MB) with
scripts unpacked and models/MediaPipe bundled. Untested on real Windows.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
lucianoandClaude Fable 5 committed 2026-07-31 14:44:47 +02:00
1 parent a869d5b969
commit 7414dbe2ec
5 files changed
+38 -9

No files matched your search

+4 -4
View File
@@ -250,8 +250,8 @@ function glbLabel(name) {
: 'Il modello ruota a tempo di musica nella famiglia “Modello 3D”.';
}
if (glbPath) {
glbLabel(glbPath.split('/').pop());
if (!glbModels.some(m => m.path === glbPath)) addGlbModel(glbPath.split('/').pop(), glbPath);
glbLabel(glbPath.split(/[\\/]/).pop());
if (!glbModels.some(m => m.path === glbPath)) addGlbModel(glbPath.split(/[\\/]/).pop(), glbPath);
}
renderGlbModels();
// every shader family can be a backdrop too (fluid/interactive/3D excluded:
@@ -292,7 +292,7 @@ $('#anim-input').addEventListener('change', async (e) => {
if (res && res.ok) {
if (!glbAnimFiles.includes(res.path)) glbAnimFiles.push(res.path);
send({ type: 'animAdd', path: res.path });
glbLabel(glbPath ? glbPath.split('/').pop() : '');
glbLabel(glbPath ? glbPath.split(/[\\/]/).pop() : '');
} else {
$('#glb-name').textContent = '⚠️ ' + ((res && res.error) || 'conversione fallita');
}
@@ -784,7 +784,7 @@ function refreshScenePreview(i) {
advanceCues(playCur || 0);
}
const baseName = (p) => p.split('/').pop();
const baseName = (p) => p.split(/[\\/]/).pop();
function probePaths(paths) {
const todo = paths.filter(p => p && !(p in durations));
+6 -3
View File
@@ -17,9 +17,12 @@ try {
const audio = new AudioEngine();
let speed = 1.0;
// Convert an absolute filesystem path into a file:// URL the renderer can load.
// Convert an absolute filesystem path into a file:// URL the renderer can
// load (Windows: backslashes -> slashes, drive letter needs a leading /).
function toFileURL(p) {
return encodeURI('file://' + p).replace(/#/g, '%23').replace(/\?/g, '%3F');
let n = String(p).replace(/\\/g, '/');
if (n[0] !== '/') n = '/' + n;
return encodeURI('file://' + n).replace(/#/g, '%23').replace(/\?/g, '%3F');
}
// ---------------------------------------------------------------- overlays
@@ -341,7 +344,7 @@ djv.onControl(async (m) => {
const buf = bytes.buffer.slice(bytes.byteOffset, bytes.byteOffset + bytes.byteLength);
const ok = viz.setModelData(buf);
if (ok === false) throw new Error((viz.model3d && viz.model3d.loadError) || 'GLB non valido');
djv.report({ type: 'glbLoaded', name: m.path.split('/').pop() });
djv.report({ type: 'glbLoaded', name: m.path.split(/[\\/]/).pop() });
reportClips();
hideHint();
} catch (e) { djv.report({ type: 'error', message: 'GLB: ' + e.message }); }