From 1cb499d443482e5c2608ec63255c26aba08f24a6 Mon Sep 17 00:00:00 2001 From: Cyril Li Date: Mon, 13 Apr 2026 03:06:41 -0500 Subject: [PATCH 1/2] show controls when fullscreen, allow fullscreen button to exit fullscreen --- YouTubeEmbeddedPlayerScrubber.js | 19 ++++++++++++++++--- 1 file changed, 16 insertions(+), 3 deletions(-) diff --git a/YouTubeEmbeddedPlayerScrubber.js b/YouTubeEmbeddedPlayerScrubber.js index d4a6bdf..f676207 100644 --- a/YouTubeEmbeddedPlayerScrubber.js +++ b/YouTubeEmbeddedPlayerScrubber.js @@ -163,8 +163,12 @@ textContent: "⛶", }); fsBtn.addEventListener("click", () => { - const player = document.getElementById("player"); - (player.requestFullscreen ?? player.webkitRequestFullscreen)?.call(player); + if (document.fullscreenElement) { + document.exitFullscreen(); + } else { + const player = document.getElementById("player"); + (player.requestFullscreen ?? player.webkitRequestFullscreen)?.call(player); + } }); // Fix double click fullscreen. @@ -243,7 +247,16 @@ }); // Add all elements. - document.body.prepend(fsBtn, vol, muteBtn, ppBtn); + function fullscreenchangeHandler() { + [fsBtn, vol, muteBtn, ppBtn].forEach((el) => el.remove()); + if (document.fullscreenElement) { + document.querySelector(".html5-video-player").prepend(fsBtn, vol, muteBtn, ppBtn); + } else { + document.body.prepend(fsBtn, vol, muteBtn, ppBtn); + } + } + document.addEventListener("fullscreenchange", fullscreenchangeHandler); + fullscreenchangeHandler(); // Set arrow key scrubbing to 5 seconds. window.addEventListener( From 90ff2b6410288140c4f39acc0392fa5573d93707 Mon Sep 17 00:00:00 2001 From: Cyril Li Date: Mon, 13 Apr 2026 05:15:10 -0500 Subject: [PATCH 2/2] show and hide the custom controls in sync with youtube controls, and on a timer when fullscreen --- YouTubeEmbeddedPlayerScrubber.js | 51 ++++++++++++++++++++++++++++++++ 1 file changed, 51 insertions(+) diff --git a/YouTubeEmbeddedPlayerScrubber.js b/YouTubeEmbeddedPlayerScrubber.js index f676207..0aa1ed7 100644 --- a/YouTubeEmbeddedPlayerScrubber.js +++ b/YouTubeEmbeddedPlayerScrubber.js @@ -258,6 +258,57 @@ document.addEventListener("fullscreenchange", fullscreenchangeHandler); fullscreenchangeHandler(); + // Helper function to set visibility of all controls. + function setControlsVisibility(visibility) { + [fsBtn, vol, muteBtn, ppBtn].forEach((el) => { + el.style.visibility = visibility; + }); + } + + // Show and hide elements in sync with YouTube's controls. + const controlsObserver = new MutationObserver(() => { + if (document.fullscreenElement) { + return; + } + const visibility = getComputedStyle(document.querySelector(".player-controls-content")).visibility; + setControlsVisibility(visibility); + }); + + // Activate the observer when .player-controls is added to the DOM + if (document.querySelector(".player-control-overlay")) { + controlsObserver.observe(document.querySelector(".player-control-overlay"), { + attributes: true, + }); + } else { + const playerControlsObserver = new MutationObserver(() => { + if (document.getElementById("player-control-overlay")) { + playerControlsObserver.disconnect(); + controlsObserver.observe(document.getElementById("player-control-overlay"), { + attributes: true, + }); + } + }); + playerControlsObserver.observe(document.body, { + childList: true, + subtree: true + }); + } + + // Show controls on mouse movement in fullscreen. + let mousemoveTimeout; + window.addEventListener("mousemove", () => { + if (!document.fullscreenElement) { + return; + } + clearTimeout(mousemoveTimeout); + setControlsVisibility("visible"); + mousemoveTimeout = setTimeout(() => { + if (document.fullscreenElement) { + setControlsVisibility("hidden"); + } + }, 2500); + }); + // Set arrow key scrubbing to 5 seconds. window.addEventListener( "keydown",