Wait for YouTube readiness before applying state
This commit is contained in:
+40
-41
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user