增加帧数
	
		
			
	
		
	
	
		
	
		
			All checks were successful
		
		
	
	
		
			
				
	
				Gitea Actions Demo / Explore-Gitea-Actions (push) Successful in 2m48s
				
			
		
		
	
	
				
					
				
			
		
			All checks were successful
		
		
	
	Gitea Actions Demo / Explore-Gitea-Actions (push) Successful in 2m48s
				
			This commit is contained in:
		
							parent
							
								
									35c7e82375
								
							
						
					
					
						commit
						5cd134aa29
					
				
							
								
								
									
										93
									
								
								src/index.js
									
									
									
									
									
								
							
							
						
						
									
										93
									
								
								src/index.js
									
									
									
									
									
								
							| @ -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'); | ||||||
|  | |||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user
	 Song367
						Song367