From a96fc86d4258b06448f784055544465902723daf Mon Sep 17 00:00:00 2001 From: songjvcheng Date: Tue, 29 Jul 2025 01:36:40 +0800 Subject: [PATCH] =?UTF-8?q?=E5=A4=84=E7=90=86=E7=BB=93=E5=B0=BE=E5=88=A4?= =?UTF-8?q?=E6=96=AD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/index.js | 66 +++++++++++++++++++++++++++++++++++++++++- src/minimaxi_stream.js | 24 +++++++-------- 2 files changed, 77 insertions(+), 13 deletions(-) diff --git a/src/index.js b/src/index.js index 1aa6282..b672e11 100644 --- a/src/index.js +++ b/src/index.js @@ -390,6 +390,70 @@ class WebRTCChat { }); this.logMessage(`视频流创建成功: ${videoFile}`, 'success'); + + if (videoFile === this.defaultVideo) { + let lastCurrentTime = 0; + video.addEventListener('timeupdate', async () => { + const currentTime = video.currentTime; + const duration = video.duration; + + // 方法2a:检查是否接近结束(最后0.1秒) + if (duration - currentTime <= 0.1) { + console.log('视频即将播放完成'); + // 处理即将结束的逻辑 + if (videoFile === this.defaultVideo) { + let lastCurrentTime = 0; + video.addEventListener('timeupdate', async () => { + const currentTime = video.currentTime; + const duration = video.duration; + + // 检查音频是否正在播放(从minimaxi_stream.js获取isPlaying状态) + const isAudioPlaying = window.isPlaying || false; // 需要确保isPlaying是全局可访问的 + + // 如果音频没有播放,且当前不是默认视频,则切换到默认视频 + if (!isAudioPlaying) { + const currentVideoFile = this.currentVideo; // 获取当前播放的视频文件名 + + if (currentVideoFile !== this.defaultVideo) { + console.log('音频已停止,当前视频不是默认视频,准备切换到默认视频'); + + // 停止当前视频的循环 + if (this.recordedVideo) { + this.recordedVideo.loop = false; + } + + // 切换到默认视频 + try { + await this.switchVideoWithReplaceTrack(this.defaultVideo, 'auto-switch', 'audio-ended'); + console.log('已自动切换到默认视频'); + } catch (error) { + console.error('自动切换到默认视频失败:', error); + } + } + } + + lastCurrentTime = currentTime; + }); + } + } + + // 方法2b:检查是否已经到达结尾 + if (currentTime >= duration) { + console.log('视频播放完成'); + // 处理播放完成的逻辑 + } + + // 方法2c:检查时间是否停止更新(可能表示播放结束) + if (Math.abs(currentTime - lastCurrentTime) < 0.01) { + // 时间没有更新,可能播放结束或暂停 + if (currentTime >= duration) { + console.log('视频播放完成(通过时间停止检测)'); + } + } + + lastCurrentTime = currentTime; + }); + } // 使用有限缓存策略(最多缓存3个视频流) if (this.videoStreams.size >= 3) { @@ -422,7 +486,7 @@ class WebRTCChat { // }); // 特别确保添加了5.mp4(从日志看这是常用视频) - videosToPreload.add('5.mp4'); + videosToPreload.add('6.mp4'); // 开始预加载 for (const videoFile of videosToPreload) { diff --git a/src/minimaxi_stream.js b/src/minimaxi_stream.js index c5e29ad..17f739b 100644 --- a/src/minimaxi_stream.js +++ b/src/minimaxi_stream.js @@ -1,11 +1,11 @@ // 以流式或非流式方式请求 minimaxi 大模型接口,并打印/返回内容 // import { text } from "express"; - +window.isPlaying = false; // 在文件顶部添加音频播放相关的变量和函数 let audioContext = null; let audioQueue = []; // 音频队列 -let isPlaying = false; +// let isPlaying = false; let isProcessingQueue = false; // 队列处理状态 let nextStartTime = 0; // 添加这行来声明 nextStartTime 变量 @@ -60,17 +60,17 @@ async function processAudioQueue() { isProcessingQueue = true; console.log('开始处理音频队列'); let isFirstChunk = true; - while (audioQueue.length > 0 || isPlaying) { + while (audioQueue.length > 0 || window.isPlaying) { // 如果当前没有音频在播放,且队列中有音频 - if (!isPlaying && audioQueue.length > 0) { + if (!window.isPlaying && audioQueue.length > 0) { const audioItem = audioQueue.shift(); - const sayName = 'say-5s-m-sw' - const targetVideo = '5.mp4' + const sayName = 'say-3s-m-sw' + const targetVideo = '6.mp4' // 如果是第一个音频片段,触发视频切换 if (sayName != window.webrtcApp.currentVideoTag && window.webrtcApp && window.webrtcApp.handleTextInput) { try { console.log('--------------触发视频切换:', sayName); - await window.webrtcApp.switchVideoWithReplaceTrack(targetVideo, 'audio', 'say-5s-m-sw'); + await window.webrtcApp.switchVideoWithReplaceTrack(targetVideo, 'audio', 'say-3s-m-sw'); isFirstChunk = false; window.webrtcApp.currentVideoTag = sayName; } catch (error) { @@ -104,19 +104,19 @@ function playAudioData(audioData) { source.buffer = audioData; source.connect(ctx.destination); - isPlaying = true; + window.isPlaying = true; source.onended = () => { console.log('音频片段播放完成'); - isPlaying = false; + window.isPlaying = false; resolve(); }; // 超时保护 setTimeout(() => { - if (isPlaying) { + if (window.isPlaying) { console.log('音频播放超时,强制结束'); - isPlaying = false; + window.isPlaying = false; resolve(); } }, (audioData.duration + 0.5) * 1000); @@ -126,7 +126,7 @@ function playAudioData(audioData) { } catch (error) { console.error('播放音频失败:', error); - isPlaying = false; + window.isPlaying = false; resolve(); } });