Join a room where someone is already watching something and the player stays empty. Nothing appears until the next video starts, so you sit out the rest of whatever was playing.
Root cause is in onYouTubeIframeAPIReady() in public/script.js:
player = new YT.Player("player", { ... events: { onStateChange, onError } });
if (pendingSync) {
applySync(pendingSync);
pendingSync = null;
}
new YT.Player() is asynchronous and there is no onReady handler registered. So applySync(pendingSync) runs against a player whose loadVideoById / cueVideoById don't exist yet, the call is dropped, and pendingSync is cleared anyway.
The socket connects faster than the YouTube iframe API loads, so on a fresh join the sync_state almost always lands first and gets thrown away. It only looks fine when you're already in the room, because by then the player is ready and sync_state takes the other branch.
Fix: add onReady to the events map and apply pendingSync from there. The sync_state handler (public/script.js:145) also guards on if (!player), which is true the moment new YT.Player() returns even though the player isn't usable — that check should be "is the player ready", not "does the object exist".
Join a room where someone is already watching something and the player stays empty. Nothing appears until the next video starts, so you sit out the rest of whatever was playing.
Root cause is in
onYouTubeIframeAPIReady()inpublic/script.js:new YT.Player()is asynchronous and there is noonReadyhandler registered. SoapplySync(pendingSync)runs against a player whoseloadVideoById/cueVideoByIddon't exist yet, the call is dropped, andpendingSyncis cleared anyway.The socket connects faster than the YouTube iframe API loads, so on a fresh join the
sync_statealmost always lands first and gets thrown away. It only looks fine when you're already in the room, because by then the player is ready andsync_statetakes the other branch.Fix: add
onReadyto the events map and applypendingSyncfrom there. Thesync_statehandler (public/script.js:145) also guards onif (!player), which is true the momentnew YT.Player()returns even though the player isn't usable — that check should be "is the player ready", not "does the object exist".