Wait for YouTube readiness before applying state

This commit is contained in:
codex
2026-06-10 20:40:56 +02:00
parent 01fd20ccdb
commit 60fee1f5f5
+40 -41
View File
@@ -53,8 +53,8 @@ let applyingWatchStateUntil = 0;
let pauseEnforcementUntil = 0;
let syncedPlaybackRetryUntil = 0;
let desiredYoutubePlaying = false;
let pendingWatchState = null;
let pendingWatchStateOptions = null;
let youtubeReadyResolvers = [];
let watchApplySequence = 0;
let youtubePlaybackRequestId = 0;
let watchPlaylist = [];
const peers = new Map();
@@ -346,16 +346,10 @@ async function ensureYoutubePlayer(initialState = {}) {
youtubeReady = true;
const iframe = youtubePlayer?.getIframe?.();
iframe?.setAttribute("allow", "autoplay; encrypted-media; fullscreen; picture-in-picture");
youtubeReadyResolvers.splice(0).forEach((resolve) => resolve());
if (shouldAutoplay) {
requestYoutubePlayback(youtubePlayer, initialVideoId, initialPosition);
}
if (pendingWatchState) {
const state = pendingWatchState;
const pendingOptions = pendingWatchStateOptions || {};
pendingWatchState = null;
pendingWatchStateOptions = null;
applyWatchState(state, pendingOptions).catch(console.error);
}
},
onStateChange: handleYoutubeStateChange
}
@@ -370,6 +364,13 @@ async function ensureYoutubePlayer(initialState = {}) {
return youtubePlayer;
}
function whenYoutubeReady() {
if (youtubeReady) return Promise.resolve();
return new Promise((resolve) => {
youtubeReadyResolvers.push(resolve);
});
}
function loadYoutubeVideo(player, videoId, position) {
player.loadVideoById({
videoId,
@@ -523,6 +524,7 @@ function handleYoutubeStateChange(event) {
}
async function applyWatchState(state, { suppressEvents = true } = {}) {
const applySequence = ++watchApplySequence;
const shouldPlay = state?.action === "play" || (!state?.action && Boolean(state?.playing));
watchPlaylist = normalizedPlaylist(state?.playlist);
currentYoutubeVideoId = state?.videoId || "";
@@ -560,6 +562,8 @@ async function applyWatchState(state, { suppressEvents = true } = {}) {
position,
autoplay: shouldPlay
});
await whenYoutubeReady();
if (applySequence !== watchApplySequence) return;
if (suppressEvents) {
applyingWatchStateUntil = Date.now() + 3000;
}
@@ -575,41 +579,36 @@ async function applyWatchState(state, { suppressEvents = true } = {}) {
pauseEnforcementUntil = Math.max(pauseEnforcementUntil, Date.now() + 3000);
}
if (youtubeReady) {
if (shouldPlay) {
setYoutubeStartPromptVisible(true);
const sameVideo = player.getVideoData?.().video_id === currentYoutubeVideoId;
const playerState = player.getPlayerState?.();
if (sameVideo && ![YT.PlayerState.UNSTARTED, YT.PlayerState.CUED].includes(playerState)) {
player.seekTo(position, true);
} else {
loadYoutubeVideo(player, currentYoutubeVideoId, position);
}
if (playerState !== YT.PlayerState.PLAYING) {
player.playVideo();
}
requestYoutubePlayback(player, currentYoutubeVideoId, position);
if (shouldPlay) {
setYoutubeStartPromptVisible(true);
const sameVideo = player.getVideoData?.().video_id === currentYoutubeVideoId;
const playerState = player.getPlayerState?.();
if (sameVideo && ![YT.PlayerState.UNSTARTED, YT.PlayerState.CUED].includes(playerState)) {
player.seekTo(position, true);
} else {
if (player.getVideoData?.().video_id !== currentYoutubeVideoId) {
player.cueVideoById(currentYoutubeVideoId, position);
} else {
player.pauseVideo();
player.seekTo(position, true);
}
player.pauseVideo();
setTimeout(() => {
player.pauseVideo();
}, 150);
setTimeout(() => {
if (!desiredYoutubePlaying) player.pauseVideo();
}, 1200);
setTimeout(() => {
if (!desiredYoutubePlaying) player.pauseVideo();
}, 2500);
loadYoutubeVideo(player, currentYoutubeVideoId, position);
}
if (playerState !== YT.PlayerState.PLAYING) {
player.playVideo();
}
requestYoutubePlayback(player, currentYoutubeVideoId, position);
} else {
pendingWatchState = state;
pendingWatchStateOptions = { suppressEvents };
if (player.getVideoData?.().video_id !== currentYoutubeVideoId) {
player.cueVideoById(currentYoutubeVideoId, position);
} else {
player.pauseVideo();
player.seekTo(position, true);
}
player.pauseVideo();
setTimeout(() => {
player.pauseVideo();
}, 150);
setTimeout(() => {
if (!desiredYoutubePlaying) player.pauseVideo();
}, 1200);
setTimeout(() => {
if (!desiredYoutubePlaying) player.pauseVideo();
}, 2500);
}
}