let currentMode = 'normal'; // 🎬 默认为普通模式 // ⚡ 核心修正:自动适配本地与生产 (Hugging Face) 环境 const API_URL = window.location.hostname === "127.0.0.1" || window.location.hostname === "localhost" ? "http://127.0.0.1:7860/theater" : "https://jinv2-shensist-theater-matrix.hf.space/theater"; function setMode(mode) { currentMode = mode; const params = document.getElementById('director-params'); // 💡 物理切换与动画控制 if (mode === 'ai_factory') { params.style.display = 'flex'; setTimeout(() => params.classList.add('active'), 10); } else { params.classList.remove('active'); setTimeout(() => params.style.display = 'none', 500); } // UI 高亮切换 document.getElementById('btn-normal').classList.toggle('active', mode === 'normal'); document.getElementById('btn-factory').classList.toggle('active', mode === 'ai_factory'); document.getElementById('subtitle').innerText = mode === 'normal' ? "已进入:普通演示模式 (快速视觉校准)" : "已激活:AI 生产工厂 (准备深度对线)"; } async function runTheater() { const topic = document.getElementById('input-topic').value; const model = document.getElementById('model-select').value; const apiKey = document.getElementById('user-api-key').value; const btn = document.getElementById('action-btn'); const subtitle = document.getElementById('subtitle'); if (currentMode === 'ai_factory' && !apiKey) { alert("⚠️ 架构师,请先填入 API KEY 以激活 AI 生产工厂!"); return; } btn.disabled = true; subtitle.innerHTML = `🎬 演员正在后台${currentMode === 'ai_factory' ? '对词(AI)' : '准备'},请稍候...`; try { const res = await fetch(API_URL, { method: 'POST', headers: {'Content-Type': 'application/json'}, body: JSON.stringify({ topic, mode: currentMode, model, api_key: apiKey }) }); if (!res.ok) throw new Error('网络断电'); const data = await res.json(); // 🚀 灵魂演播开始! await playPerformance(data); } catch (err) { console.error("剧场故障:", err); document.getElementById('subtitle').innerHTML = '❌ 剧场意外断电,请检查后台。'; } finally { btn.disabled = false; } } async function playPerformance(lines) { const subtitle = document.getElementById('subtitle'); subtitle.innerText = "🚀 灵魂演播开始!"; for (let line of lines) { // 1. ⚡ 物理视觉切换 document.querySelectorAll('.actor').forEach(a => a.classList.remove('active')); const activeActor = document.getElementById(line.actor_id); if (activeActor) activeActor.classList.add('active'); // 2. ⚡ 播放内存音频 await new Promise((resolve) => { let audio = new Audio(line.audio_data); audio.oncanplaythrough = () => { subtitle.style.color = line.actor_id === 'left' ? '#ff4444' : '#ff44ff'; subtitle.innerText = line.text; audio.play().catch(resolve); }; audio.onended = () => setTimeout(resolve, 500); audio.onerror = resolve; }); } subtitle.style.color = "#fff"; subtitle.innerText = "🎬 演播结束。"; document.querySelectorAll('.actor').forEach(a => a.classList.remove('active')); }