From 5481a1e92fbf7d169df81600f1c8ccbf7d3b576d Mon Sep 17 00:00:00 2001 From: Andre Date: Sat, 21 Mar 2026 19:43:14 +0100 Subject: [PATCH] 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 --- .../comfyui_audiocraft/web/js/audioManager.js | 81 ++++++++++++++----- 1 file changed, 63 insertions(+), 18 deletions(-) diff --git a/comfyui-audio/comfyui_audiocraft/web/js/audioManager.js b/comfyui-audio/comfyui_audiocraft/web/js/audioManager.js index 39988ff..991e8b6 100644 --- a/comfyui-audio/comfyui_audiocraft/web/js/audioManager.js +++ b/comfyui-audio/comfyui_audiocraft/web/js/audioManager.js @@ -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; + } }; };