AudioManager: Loop-Toggle und globaler Audio-Stop
Loop AN/AUS Button in der Header-Leiste. Wenn Loop aktiv, wird der angeklickte Sound endlos wiederholt (zum Testen ob z.B. Wirbelwind sauber loopt). Nur ein Sound spielt gleichzeitig - neuer Klick stoppt den vorherigen. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
parent
5766fdb757
commit
5481a1e92f
1 changed files with 63 additions and 18 deletions
|
|
@ -1,6 +1,8 @@
|
|||
import { app } from "../../../scripts/app.js";
|
||||
import { api } from "../../../scripts/api.js";
|
||||
|
||||
let loopEnabled = false;
|
||||
|
||||
app.registerExtension({
|
||||
name: "AudioCraft.AudioManager",
|
||||
async beforeRegisterNodeDef(nodeType, nodeData, app) {
|
||||
|
|
@ -29,7 +31,6 @@ app.registerExtension({
|
|||
});
|
||||
}
|
||||
|
||||
// Resize node to fit all files (26px per row + header + padding)
|
||||
const listHeight = Math.min(40 + files.length * 26, 800);
|
||||
this._managerWidget.computeSize = () => [this.size[0], listHeight];
|
||||
this.setSize([Math.max(this.size[0], 500), listHeight + 80]);
|
||||
|
|
@ -39,11 +40,47 @@ app.registerExtension({
|
|||
},
|
||||
});
|
||||
|
||||
// Track currently playing audio globally so only one plays at a time
|
||||
let activeAudio = null;
|
||||
let activeBtn = null;
|
||||
|
||||
function stopActive() {
|
||||
if (activeAudio) {
|
||||
activeAudio.pause();
|
||||
activeAudio = null;
|
||||
}
|
||||
if (activeBtn) {
|
||||
activeBtn.textContent = "\u25B6";
|
||||
activeBtn.style.color = "#8f8";
|
||||
activeBtn = null;
|
||||
}
|
||||
}
|
||||
|
||||
function buildContent(container, summary, files) {
|
||||
const header = document.createElement("div");
|
||||
header.textContent = summary;
|
||||
header.style.cssText = "font-weight:bold;margin-bottom:8px;color:#fff;font-size:13px;padding:4px;background:#333;border-radius:4px;";
|
||||
container.appendChild(header);
|
||||
// Header with summary + loop toggle
|
||||
const headerRow = document.createElement("div");
|
||||
headerRow.style.cssText = "display:flex;align-items:center;justify-content:space-between;margin-bottom:8px;padding:4px;background:#333;border-radius:4px;";
|
||||
|
||||
const headerText = document.createElement("span");
|
||||
headerText.textContent = summary;
|
||||
headerText.style.cssText = "font-weight:bold;color:#fff;font-size:13px;";
|
||||
|
||||
const loopBtn = document.createElement("button");
|
||||
loopBtn.textContent = loopEnabled ? "\uD83D\uDD01 Loop AN" : "\uD83D\uDD01 Loop AUS";
|
||||
loopBtn.style.cssText = `background:${loopEnabled ? "#2a5a2a" : "#444"};border:none;color:${loopEnabled ? "#8f8" : "#888"};cursor:pointer;padding:3px 8px;border-radius:3px;font-size:11px;`;
|
||||
loopBtn.onclick = () => {
|
||||
loopEnabled = !loopEnabled;
|
||||
loopBtn.textContent = loopEnabled ? "\uD83D\uDD01 Loop AN" : "\uD83D\uDD01 Loop AUS";
|
||||
loopBtn.style.background = loopEnabled ? "#2a5a2a" : "#444";
|
||||
loopBtn.style.color = loopEnabled ? "#8f8" : "#888";
|
||||
if (activeAudio) {
|
||||
activeAudio.loop = loopEnabled;
|
||||
}
|
||||
};
|
||||
|
||||
headerRow.appendChild(headerText);
|
||||
headerRow.appendChild(loopBtn);
|
||||
container.appendChild(headerRow);
|
||||
|
||||
if (files.length === 0) return;
|
||||
|
||||
|
|
@ -64,33 +101,41 @@ function buildContent(container, summary, files) {
|
|||
playBtn.title = "Abspielen";
|
||||
playBtn.style.cssText = "background:#444;border:none;color:#8f8;cursor:pointer;padding:2px 8px;border-radius:3px;font-size:11px;margin-right:4px;";
|
||||
|
||||
const dlBtn = document.createElement("a");
|
||||
const audioSrc = api.apiURL(
|
||||
`/view?filename=${encodeURIComponent(f.name)}&subfolder=audio&type=output`
|
||||
);
|
||||
|
||||
const dlBtn = document.createElement("a");
|
||||
dlBtn.href = audioSrc;
|
||||
dlBtn.download = f.name;
|
||||
dlBtn.textContent = "\u2B07";
|
||||
dlBtn.title = "Download";
|
||||
dlBtn.style.cssText = "color:#8cf;text-decoration:none;font-size:13px;padding:0 4px;";
|
||||
|
||||
let currentAudio = null;
|
||||
playBtn.onclick = () => {
|
||||
if (currentAudio) {
|
||||
currentAudio.pause();
|
||||
currentAudio = null;
|
||||
playBtn.textContent = "\u25B6";
|
||||
playBtn.style.color = "#8f8";
|
||||
// If clicking the same button that's playing, stop it
|
||||
if (activeBtn === playBtn) {
|
||||
stopActive();
|
||||
return;
|
||||
}
|
||||
currentAudio = new Audio(audioSrc);
|
||||
currentAudio.play();
|
||||
// Stop any other playing audio first
|
||||
stopActive();
|
||||
|
||||
const audio = new Audio(audioSrc);
|
||||
audio.loop = loopEnabled;
|
||||
audio.play();
|
||||
activeAudio = audio;
|
||||
activeBtn = playBtn;
|
||||
playBtn.textContent = "\u25A0";
|
||||
playBtn.style.color = "#f88";
|
||||
currentAudio.onended = () => {
|
||||
playBtn.textContent = "\u25B6";
|
||||
playBtn.style.color = "#8f8";
|
||||
currentAudio = null;
|
||||
|
||||
audio.onended = () => {
|
||||
if (!audio.loop) {
|
||||
playBtn.textContent = "\u25B6";
|
||||
playBtn.style.color = "#8f8";
|
||||
activeAudio = null;
|
||||
activeBtn = null;
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue