|
|
@@ -590,75 +590,47 @@ export const WelcomePage = () => {
|
|
|
fallbackTimerRef.current = null;
|
|
|
}
|
|
|
|
|
|
- // 切换到加载状态
|
|
|
- setViewState('loading');
|
|
|
- setIsLoading(true);
|
|
|
- loadingStartTimeRef.current = Date.now();
|
|
|
-
|
|
|
- // 🔑 关键修复:在用户交互的直接调用链中立即尝试播放
|
|
|
- // 这样可以"锁定"用户交互权限,即使视频还没准备好
|
|
|
- if (playerRef.current) {
|
|
|
- const player = playerRef.current;
|
|
|
- const videoElement = player.el()?.querySelector('video') as HTMLVideoElement;
|
|
|
-
|
|
|
- if (videoElement) {
|
|
|
- // 确保未静音
|
|
|
- player.muted(false);
|
|
|
- videoElement.muted = false;
|
|
|
- videoElement.volume = 1.0;
|
|
|
-
|
|
|
- // 立即尝试播放(在用户交互的直接调用链中)
|
|
|
- // 如果视频还没准备好,这会失败,但没关系,我们会在视频准备好后再播放
|
|
|
- try {
|
|
|
- const playPromise = player.play();
|
|
|
- if (playPromise) {
|
|
|
- await playPromise;
|
|
|
- console.log('[WelcomePage] ✅ 在用户交互中立即播放成功');
|
|
|
- // 如果立即播放成功,直接进入播放状态
|
|
|
- setIsLoading(false);
|
|
|
- setViewState('playing');
|
|
|
- return; // 成功播放,直接返回
|
|
|
- }
|
|
|
- } catch (error) {
|
|
|
- console.log('[WelcomePage] 视频未准备好,等待加载完成后再播放:', error);
|
|
|
- // 播放失败是预期的(视频可能还没准备好),继续等待加载
|
|
|
- }
|
|
|
- }
|
|
|
+ // 直接进入播放状态(页面已预加载视频,无需再显示加载层)
|
|
|
+ setIsLoading(false);
|
|
|
+ setViewState('playing');
|
|
|
+
|
|
|
+ if (!playerRef.current) {
|
|
|
+ return;
|
|
|
}
|
|
|
|
|
|
- // 如果立即播放失败(视频未准备好),使用原来的逻辑等待加载
|
|
|
- // 检查视频是否已准备好
|
|
|
- if (isVideoReadyRef.current) {
|
|
|
- // 视频已准备好,使用最小加载时间
|
|
|
- setTimeout(() => {
|
|
|
- checkAndStartPlayback();
|
|
|
- }, 0);
|
|
|
- } else {
|
|
|
- // 视频未准备好,等待加载完成或达到最小时间
|
|
|
- // 设置一个兜底定时器(最多等待5秒)
|
|
|
- fallbackTimerRef.current = setTimeout(() => {
|
|
|
- if (viewStateRef.current === 'loading') {
|
|
|
- console.warn('[WelcomePage] 加载超时,强制开始播放');
|
|
|
- if (checkIntervalRef.current) {
|
|
|
- clearInterval(checkIntervalRef.current);
|
|
|
- checkIntervalRef.current = null;
|
|
|
- }
|
|
|
- setIsLoading(false);
|
|
|
- setViewState('playing');
|
|
|
- }
|
|
|
- }, 5000);
|
|
|
-
|
|
|
- // 定期检查是否可以开始播放
|
|
|
- checkIntervalRef.current = setInterval(() => {
|
|
|
- if (viewStateRef.current === 'loading') {
|
|
|
- checkAndStartPlayback();
|
|
|
- } else {
|
|
|
- if (checkIntervalRef.current) {
|
|
|
- clearInterval(checkIntervalRef.current);
|
|
|
- checkIntervalRef.current = null;
|
|
|
- }
|
|
|
+ const player = playerRef.current;
|
|
|
+ const videoElement = player.el()?.querySelector('video') as HTMLVideoElement;
|
|
|
+ if (!videoElement) {
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ // 确保未静音
|
|
|
+ player.muted(false);
|
|
|
+ videoElement.muted = false;
|
|
|
+ videoElement.volume = 1.0;
|
|
|
+
|
|
|
+ // 优先在用户交互链中直接播放
|
|
|
+ const tryPlay = async () => {
|
|
|
+ try {
|
|
|
+ const playPromise = player.play();
|
|
|
+ if (playPromise) {
|
|
|
+ await playPromise;
|
|
|
+ console.log('[WelcomePage] ✅ 点击后立即开始播放');
|
|
|
}
|
|
|
- }, 100);
|
|
|
+ } catch (error) {
|
|
|
+ console.warn('[WelcomePage] 立即播放失败,等待视频就绪后再试:', error);
|
|
|
+ }
|
|
|
+ };
|
|
|
+
|
|
|
+ await tryPlay();
|
|
|
+
|
|
|
+ // 如果视频尚未完全就绪,等待 canplaythrough 再尝试一次
|
|
|
+ if (videoElement.readyState < HTMLMediaElement.HAVE_FUTURE_DATA) {
|
|
|
+ const handleReady = async () => {
|
|
|
+ videoElement.removeEventListener('canplaythrough', handleReady);
|
|
|
+ await tryPlay();
|
|
|
+ };
|
|
|
+ videoElement.addEventListener('canplaythrough', handleReady, { once: true });
|
|
|
}
|
|
|
};
|
|
|
|