document.addEventListener('DOMContentLoaded', function() { // --- 加载屏幕处理 --- const loadingScreen = document.getElementById('loading-screen'); setTimeout(() => { loadingScreen.style.opacity = '0'; // 在动画结束后将其隐藏,以防它阻碍交互 setTimeout(() => { loadingScreen.style.display = 'none'; }, 500); // 这个时间应该匹配 CSS 中的 transition 时间 }, 1500); // 1.5秒后开始淡出 // 获取需要的 DOM 元素 let video1 = document.getElementById('video1'); let video2 = document.getElementById('video2'); const micButton = document.getElementById('mic-button'); const favorabilityBar = document.getElementById('favorability-bar'); const floatingButton = document.getElementById('floating-button'); const menuContainer = document.getElementById('menu-container'); const menuItems = document.querySelectorAll('.menu-item'); 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 = (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; } } // 显示最终识别结果 transcriptContainer.textContent = final_transcript || interim_transcript; // 基于关键词的情感分析和视频切换 if (final_transcript) { analyzeAndReact(final_transcript); } }; 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 = ''; // 清空文本 } }); // --- 悬浮按钮交互 --- floatingButton.addEventListener('click', (event) => { event.stopPropagation(); // 防止事件冒泡到 document menuContainer.classList.toggle('hidden'); }); menuItems.forEach(item => { item.addEventListener('click', function() { const videoSrc = this.getAttribute('data-video'); playSpecificVideo(videoSrc); menuContainer.classList.add('hidden'); }); }); // 点击菜单外部区域关闭菜单 document.addEventListener('click', () => { if (!menuContainer.classList.contains('hidden')) { menuContainer.classList.add('hidden'); } }); // 阻止菜单自身的点击事件冒泡 menuContainer.addEventListener('click', (event) => { event.stopPropagation(); }); function playSpecificVideo(videoSrc) { const currentVideoSrc = activeVideo.querySelector('source').getAttribute('src'); if (videoSrc === currentVideoSrc) return; inactiveVideo.querySelector('source').setAttribute('src', videoSrc); inactiveVideo.load(); inactiveVideo.addEventListener('canplaythrough', function onCanPlayThrough() { inactiveVideo.removeEventListener('canplaythrough', onCanPlayThrough); activeVideo.pause(); // 暂停当前视频,防止其 'ended' 事件触发切换 inactiveVideo.play().catch(error => console.error("Video play failed:", error)); activeVideo.classList.remove('active'); inactiveVideo.classList.add('active'); [activeVideo, inactiveVideo] = [inactiveVideo, activeVideo]; activeVideo.addEventListener('ended', switchVideo, { once: true }); }, { once: true }); } // --- 情感分析与反应 --- const positiveWords = ['开心', '高兴', '喜欢', '太棒了', '你好', '漂亮']; const negativeWords = ['难过', '生气', '讨厌', '伤心']; const positiveVideos = [ '视频资源/jimeng-2025-07-16-1043-笑着优雅的左右摇晃,过一会儿手扶着下巴,保持微笑.mp4', '视频资源/jimeng-2025-07-16-4437-比耶,然后微笑着优雅的左右摇晃.mp4', '视频资源/生成加油视频.mp4', '视频资源/生成跳舞视频.mp4' ]; const negativeVideo = '视频资源/负面/jimeng-2025-07-16-9418-双手叉腰,嘴巴一直在嘟囔,表情微微生气.mp4'; function analyzeAndReact(text) { let reaction = 'neutral'; // 默认为中性 if (positiveWords.some(word => text.includes(word))) { reaction = 'positive'; } else if (negativeWords.some(word => text.includes(word))) { reaction = 'negative'; } if (reaction !== 'neutral') { switchVideoByEmotion(reaction); } } function switchVideoByEmotion(emotion) { let nextVideoSrc; if (emotion === 'positive') { const randomIndex = Math.floor(Math.random() * positiveVideos.length); nextVideoSrc = positiveVideos[randomIndex]; } else { // negative nextVideoSrc = negativeVideo; } // 避免重复播放同一个视频 const currentVideoSrc = activeVideo.querySelector('source').getAttribute('src'); if (nextVideoSrc === currentVideoSrc) return; // --- 以下逻辑与 switchVideo 函数类似,用于切换视频 --- inactiveVideo.querySelector('source').setAttribute('src', nextVideoSrc); inactiveVideo.load(); inactiveVideo.addEventListener('canplaythrough', function onCanPlayThrough() { inactiveVideo.removeEventListener('canplaythrough', onCanPlayThrough); activeVideo.pause(); // 暂停当前视频,防止其 'ended' 事件触发切换 inactiveVideo.play().catch(error => console.error("Video play failed:", error)); activeVideo.classList.remove('active'); inactiveVideo.classList.add('active'); [activeVideo, inactiveVideo] = [inactiveVideo, activeVideo]; // 情感触发的视频播放结束后,回归随机播放 activeVideo.addEventListener('ended', switchVideo, { once: true }); }, { once: true }); } });