import BellaAI from './core.js'; document.addEventListener('DOMContentLoaded', async function() { // --- Get all necessary DOM elements first --- const transcriptDiv = document.getElementById('transcript'); const loadingScreen = document.getElementById('loading-screen'); const video1 = document.getElementById('video1'); const video2 = document.getElementById('video2'); const micButton = document.getElementById('mic-button'); // --- AI Core Initialization --- let bellaAI; micButton.disabled = true; transcriptDiv.textContent = '正在唤醒贝拉的核心...'; try { bellaAI = await BellaAI.getInstance(); micButton.disabled = false; transcriptDiv.textContent = '贝拉已准备好,请点击麦克风开始对话。'; } catch (error) { console.error('Failed to initialize Bella AI:', error); transcriptDiv.textContent = '唤醒贝拉时遇到问题,请检查控制台信息。'; // Keep the app running with visual features even if AI fails } // --- Loading screen handling --- setTimeout(() => { loadingScreen.style.opacity = '0'; // Hide it after the animation to prevent it from blocking interactions setTimeout(() => { loadingScreen.style.display = 'none'; }, 500); // This time should match the transition time in CSS }, 1500); // Start fading out after 1.5 seconds let activeVideo = video1; let inactiveVideo = video2; // 视频列表 const videoList = [ '视频资源/3D 建模图片制作.mp4', '视频资源/jimeng-2025-07-16-1043-笑着优雅的左右摇晃,过一会儿手扶着下巴,保持微笑.mp4', '视频资源/jimeng-2025-07-16-4437-比耶,然后微笑着优雅的左右摇晃.mp4', '视频资源/生成加油视频.mp4', '视频资源/生成跳舞视频.mp4', '视频资源/负面/jimeng-2025-07-16-9418-双手叉腰,嘴巴一直在嘟囔,表情微微生气.mp4' ]; // --- 视频交叉淡入淡出播放功能 --- function switchVideo() { // 1. 选择下一个视频 const currentVideoSrc = activeVideo.querySelector('source').getAttribute('src'); let nextVideoSrc = currentVideoSrc; while (nextVideoSrc === currentVideoSrc) { const randomIndex = Math.floor(Math.random() * videoList.length); nextVideoSrc = videoList[randomIndex]; } // 2. 设置不活动的 video 元素的 source inactiveVideo.querySelector('source').setAttribute('src', nextVideoSrc); inactiveVideo.load(); // 3. 当不活动的视频可以播放时,执行切换 inactiveVideo.addEventListener('canplaythrough', function onCanPlayThrough() { // 确保事件只触发一次 inactiveVideo.removeEventListener('canplaythrough', onCanPlayThrough); // 4. 播放新视频 inactiveVideo.play().catch(error => { console.error("Video play failed:", error); }); // 5. 切换 active class 来触发 CSS 过渡 activeVideo.classList.remove('active'); inactiveVideo.classList.add('active'); // 6. 更新角色 [activeVideo, inactiveVideo] = [inactiveVideo, activeVideo]; // 为新的 activeVideo 绑定 ended 事件 activeVideo.addEventListener('ended', switchVideo, { once: true }); }, { once: true }); // 使用 { once: true } 确保事件只被处理一次 } // 初始启动 activeVideo.addEventListener('ended', switchVideo, { once: true }); // --- 语音识别核心 --- const SpeechRecognition = window.SpeechRecognition || window.webkitSpeechRecognition; let recognition; // 检查浏览器是否支持语音识别 if (SpeechRecognition) { recognition = new SpeechRecognition(); recognition.continuous = true; // 持续识别 recognition.lang = 'zh-CN'; // 设置语言为中文 recognition.interimResults = true; // 获取临时结果 recognition.onresult = async (event) => { const transcriptContainer = document.getElementById('transcript'); let final_transcript = ''; let interim_transcript = ''; for (let i = event.resultIndex; i < event.results.length; ++i) { if (event.results[i].isFinal) { final_transcript += event.results[i][0].transcript; } else { interim_transcript += event.results[i][0].transcript; } } // Update interim results transcriptContainer.textContent = `你: ${final_transcript || interim_transcript}`; // Once we have a final result, process it with the AI if (final_transcript && bellaAI) { const userText = final_transcript.trim(); transcriptContainer.textContent = `你: ${userText}`; try { // Let Bella think const thinkingText = document.createElement('p'); thinkingText.textContent = '贝拉正在思考...'; transcriptContainer.appendChild(thinkingText); const response = await bellaAI.think(userText); transcriptContainer.removeChild(thinkingText); const bellaText = document.createElement('p'); bellaText.textContent = `贝拉: ${response}`; transcriptContainer.appendChild(bellaText); // Let Bella speak const audioData = await bellaAI.speak(response); const blob = new Blob([audioData], { type: 'audio/wav' }); const audioUrl = URL.createObjectURL(blob); const audio = new Audio(audioUrl); audio.play(); } catch (error) { console.error('Bella AI processing error:', error); const errorText = document.createElement('p'); errorText.textContent = '贝拉处理时遇到问题。'; transcriptContainer.appendChild(errorText); } } }; recognition.onerror = (event) => { console.error('语音识别错误:', event.error); }; } else { console.log('您的浏览器不支持语音识别功能。'); // 可以在界面上给用户提示 } // --- 麦克风按钮交互 --- let isListening = false; micButton.addEventListener('click', function() { if (!SpeechRecognition) return; // 如果不支持,则不执行任何操作 isListening = !isListening; micButton.classList.toggle('is-listening', isListening); const transcriptContainer = document.querySelector('.transcript-container'); const transcriptText = document.getElementById('transcript'); if (isListening) { transcriptText.textContent = '聆听中...'; // 立刻显示提示 transcriptContainer.classList.add('visible'); recognition.start(); } else { recognition.stop(); transcriptContainer.classList.remove('visible'); transcriptText.textContent = ''; // 清空文本 } }); });