Spaces:
Sleeping
Sleeping
File size: 3,643 Bytes
acc335f 4a7f6be acc335f | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 | 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 = `<span style="color: #ff0000; font-weight: bold;">🎬 演员正在后台${currentMode === 'ai_factory' ? '对词(AI)' : '准备'},请稍候...</span>`;
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 = '<span style="color:red">❌ 剧场意外断电,请检查后台。</span>';
} 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'));
}
|