增加帧数
All checks were successful
Gitea Actions Demo / Explore-Gitea-Actions (push) Successful in 2m48s

This commit is contained in:
Song367 2025-08-06 19:43:38 +08:00
parent 35c7e82375
commit 5cd134aa29

View File

@ -673,8 +673,10 @@ class WebRTCChat {
overlay.style.backgroundImage = `url(${frameData})`; overlay.style.backgroundImage = `url(${frameData})`;
overlay.style.backgroundSize = 'cover'; overlay.style.backgroundSize = 'cover';
overlay.style.backgroundPosition = 'center'; overlay.style.backgroundPosition = 'center';
overlay.style.backgroundRepeat = 'no-repeat';
overlay.style.zIndex = '10'; overlay.style.zIndex = '10';
overlay.style.pointerEvents = 'none'; overlay.style.pointerEvents = 'none';
overlay.style.willChange = 'auto'; // 优化渲染性能
overlay.id = 'video-frame-overlay'; overlay.id = 'video-frame-overlay';
return overlay; return overlay;
@ -699,6 +701,9 @@ class WebRTCChat {
if (frameData) { if (frameData) {
frameOverlay = this.createFrameOverlay(frameData); frameOverlay = this.createFrameOverlay(frameData);
currentVideo.parentElement.appendChild(frameOverlay); currentVideo.parentElement.appendChild(frameOverlay);
// 确保覆盖层立即显示
frameOverlay.offsetHeight; // 强制重绘
} }
// 3. 检查是否已缓存 // 3. 检查是否已缓存
@ -724,11 +729,14 @@ class WebRTCChat {
// 5. 在缓冲视频元素中预加载新视频 // 5. 在缓冲视频元素中预加载新视频
bufferVideo.srcObject = newStream; bufferVideo.srcObject = newStream;
// 6. 等待新视频完全准备好(至少渲染一帧) // 6. 增强的视频准备检测
await new Promise((resolve, reject) => { await new Promise((resolve, reject) => {
const timeout = setTimeout(() => { const timeout = setTimeout(() => {
reject(new Error('视频加载超时')); reject(new Error('视频加载超时'));
}, 5000); }, 8000); // 增加超时时间到10秒
let frameCount = 0;
const minFrames = 8; // 增加到8帧确保更稳定的切换
const onReady = () => { const onReady = () => {
clearTimeout(timeout); clearTimeout(timeout);
@ -741,16 +749,39 @@ class WebRTCChat {
const onCanPlay = () => { const onCanPlay = () => {
// 开始播放新视频 // 开始播放新视频
bufferVideo.play().then(() => { bufferVideo.play().then(() => {
// 等待至少一帧渲染 // 等待多帧渲染确保稳定
if (bufferVideo.currentTime > 0) { const checkFrames = () => {
onReady(); if (bufferVideo.currentTime > 0) {
} frameCount++;
if (frameCount >= minFrames) {
// 额外等待三个渲染周期确保完全稳定
requestAnimationFrame(() => {
requestAnimationFrame(() => {
requestAnimationFrame(() => {
onReady();
});
});
});
} else {
requestAnimationFrame(checkFrames);
}
} else {
requestAnimationFrame(checkFrames);
}
};
requestAnimationFrame(checkFrames);
}).catch(reject); }).catch(reject);
}; };
const onTimeUpdate = () => { const onTimeUpdate = () => {
if (bufferVideo.currentTime > 0) { if (bufferVideo.currentTime > 0) {
onReady(); frameCount++;
if (frameCount >= minFrames) {
// 额外等待确保帧稳定
setTimeout(() => {
onReady();
}, 100); // 增加等待时间到100ms
}
} }
}; };
@ -771,26 +802,58 @@ class WebRTCChat {
} }
}); });
// 7. 立即切换视频显示(无过渡) // 7. 三重确认新视频已准备好
await new Promise(resolve => {
let confirmCount = 0;
const maxConfirms = 5; // 增加确认次数
const finalCheck = () => {
if (bufferVideo.readyState >= 2 && bufferVideo.currentTime > 0) {
confirmCount++;
if (confirmCount >= maxConfirms) {
// 再等待三个渲染周期确保完全准备好
requestAnimationFrame(() => {
requestAnimationFrame(() => {
requestAnimationFrame(() => {
resolve();
});
});
});
} else {
requestAnimationFrame(finalCheck);
}
} else {
requestAnimationFrame(finalCheck);
}
};
finalCheck();
});
// 8. 立即切换视频显示(无过渡)
bufferVideo.style.zIndex = '2'; bufferVideo.style.zIndex = '2';
currentVideo.style.zIndex = '1'; currentVideo.style.zIndex = '1';
// 8. 移除静态帧覆盖层 // 9. 延迟移除静态帧覆盖层(进一步增加显示时长)
if (frameOverlay) { if (frameOverlay) {
frameOverlay.remove(); // 等待更长时间确保新视频完全显示
setTimeout(() => {
if (frameOverlay && frameOverlay.parentElement) {
frameOverlay.remove();
}
}, 300); // 增加到300ms
} }
// 9. 隐藏加载指示器 // 10. 隐藏加载指示器
if (!isCached) { if (!isCached) {
this.hideVideoLoading(); this.hideVideoLoading();
} }
// 10. 更新状态 // 11. 更新状态
this.currentVideoStream = newStream; this.currentVideoStream = newStream;
this.currentVideo = videoFile; this.currentVideo = videoFile;
this.activeVideoElement = this.activeVideoElement === 'main' ? 'buffer' : 'main'; this.activeVideoElement = this.activeVideoElement === 'main' ? 'buffer' : 'main';
// 11. 延迟清理旧视频流 // 12. 延迟清理旧视频流
setTimeout(() => { setTimeout(() => {
if (currentVideo.srcObject && currentVideo.srcObject !== newStream) { if (currentVideo.srcObject && currentVideo.srcObject !== newStream) {
currentVideo.srcObject.getTracks().forEach(track => track.stop()); currentVideo.srcObject.getTracks().forEach(track => track.stop());
@ -798,7 +861,7 @@ class WebRTCChat {
} }
}, 1000); }, 1000);
// 12. 更新WebRTC连接 // 13. 更新WebRTC连接
if (this.peerConnection && this.videoSender) { if (this.peerConnection && this.videoSender) {
const newVideoTrack = newStream.getVideoTracks()[0]; const newVideoTrack = newStream.getVideoTracks()[0];
if (newVideoTrack) { if (newVideoTrack) {
@ -806,7 +869,7 @@ class WebRTCChat {
} }
} }
// 13. 更新显示信息 // 14. 更新显示信息
if (text) { if (text) {
this.currentVideoName.textContent = `交互视频: ${videoFile} (${type}: ${text})`; this.currentVideoName.textContent = `交互视频: ${videoFile} (${type}: ${text})`;
this.logMessage(`成功切换到交互视频流: ${videoFile} (${type}: ${text})`, 'success'); this.logMessage(`成功切换到交互视频流: ${videoFile} (${type}: ${text})`, 'success');