From df6ac7ba73953640f9dc26c67bd2f51e86e443b5 Mon Sep 17 00:00:00 2001 From: Song367 <601337784@qq.com> Date: Wed, 6 Aug 2025 17:29:26 +0800 Subject: [PATCH] =?UTF-8?q?=E5=88=B7=E6=96=B0=E9=A1=B5=E9=9D=A2=E6=97=B6?= =?UTF-8?q?=E9=97=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- server.js | 12 +++++++- src/index.js | 79 +++++++++++++++++++++++++++++++++++++++------------- 2 files changed, 70 insertions(+), 21 deletions(-) diff --git a/server.js b/server.js index f38207c..de7d8f4 100644 --- a/server.js +++ b/server.js @@ -8,7 +8,17 @@ const { MessageHistory } = require('./src/message_history.js'); const app = express(); const server = http.createServer(app); -const io = socketIo(server); +const io = socketIo(server, { + pingTimeout: 60000, // 60秒超时 + pingInterval: 25000, // 25秒心跳间隔 + upgradeTimeout: 30000, // 30秒升级超时 + allowEIO3: true, // 允许Engine.IO v3客户端 + transports: ['websocket', 'polling'], // 支持多种传输方式 + cors: { + origin: "*", + methods: ["GET", "POST"] + } +}); // 创建消息历史管理器 const messageHistory = new MessageHistory(); diff --git a/src/index.js b/src/index.js index 2e5d558..dd51e1d 100644 --- a/src/index.js +++ b/src/index.js @@ -691,7 +691,18 @@ class WebRTCChat { clearTimeout(timeout); bufferVideo.removeEventListener('canplay', onCanPlay); bufferVideo.removeEventListener('error', onError); - resolve(); + + // 确保视频渲染了至少一帧 + if (bufferVideo.readyState >= 2) { + resolve(); + } else { + // 等待第一帧渲染 + const onTimeUpdate = () => { + bufferVideo.removeEventListener('timeupdate', onTimeUpdate); + resolve(); + }; + bufferVideo.addEventListener('timeupdate', onTimeUpdate, { once: true }); + } }; const onError = (error) => { @@ -701,8 +712,12 @@ class WebRTCChat { reject(error); }; - bufferVideo.addEventListener('canplay', onCanPlay); - bufferVideo.addEventListener('error', onError); + if (bufferVideo.readyState >= 3) { + onCanPlay(); + } else { + bufferVideo.addEventListener('canplay', onCanPlay); + bufferVideo.addEventListener('error', onError); + } // 开始播放缓冲视频 bufferVideo.play().catch(onError); @@ -762,27 +777,51 @@ class WebRTCChat { // 执行视频过渡动画 async performVideoTransition(currentVideo, bufferVideo) { return new Promise((resolve) => { - // 添加切换类 - currentVideo.classList.add('switching'); - bufferVideo.classList.add('switching'); + // 确保初始状态正确 + bufferVideo.style.opacity = '0'; + bufferVideo.style.zIndex = '3'; + currentVideo.style.opacity = '1'; + currentVideo.style.zIndex = '2'; - // 等待CSS过渡完成 - setTimeout(() => { - // 移除切换类 - currentVideo.classList.remove('switching'); - bufferVideo.classList.remove('switching'); - - // 交换z-index - if (currentVideo.style.zIndex === '2' || !currentVideo.style.zIndex) { + // 设置过渡属性(如果还没有) + if (!bufferVideo.style.transition) { + bufferVideo.style.transition = 'opacity 0.3s cubic-bezier(0.4, 0.0, 0.2, 1)'; + } + if (!currentVideo.style.transition) { + currentVideo.style.transition = 'opacity 0.3s cubic-bezier(0.4, 0.0, 0.2, 1)'; + } + + // 强制重绘以确保样式生效 + bufferVideo.offsetHeight; + + // 开始过渡 + requestAnimationFrame(() => { + bufferVideo.style.opacity = '1'; + currentVideo.style.opacity = '0'; + }); + + // 监听过渡完成 + const onTransitionEnd = (e) => { + if (e.target === bufferVideo && e.propertyName === 'opacity') { + bufferVideo.removeEventListener('transitionend', onTransitionEnd); + + // 重置z-index currentVideo.style.zIndex = '1'; bufferVideo.style.zIndex = '2'; - } else { - currentVideo.style.zIndex = '2'; - bufferVideo.style.zIndex = '1'; + + resolve(); } - + }; + + bufferVideo.addEventListener('transitionend', onTransitionEnd); + + // 备用超时机制 + setTimeout(() => { + bufferVideo.removeEventListener('transitionend', onTransitionEnd); + currentVideo.style.zIndex = '1'; + bufferVideo.style.zIndex = '2'; resolve(); - }, 500); // 与CSS过渡时间一致 + }, 400); }); } @@ -957,7 +996,7 @@ class WebRTCChat { window.location.reload(); this.startButton.style.display = 'block'; this.startButton.disabled = false; - }, 2000); + }, 300); } // 清除视频缓存的方法