Last active
July 6, 2023 15:20
-
-
Save hazycora/26bafd2a587c4aab6a01a3d953795b48 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// ==UserScript== | |
// @name Faster Ambient Mode | |
// @namespace http://tampermonkey.net/ | |
// @version 0.2 | |
// @description Makes YouTube's ambient mode feature change more rapidly. | |
// @author hazycora | |
// @match https://www.youtube.com/* | |
// @icon data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw== | |
// @grant none | |
// ==/UserScript== | |
// to use this, disable youtube's built-in ambient mode | |
const cinematicFrameDuration = 20 // milliseconds between frames (crossfade occurs during this duration) | |
// some might want to change this to 50 or 100 | |
function copyVideo(video, canvasContext) { | |
canvasContext.drawImage(video, 0, 0) | |
} | |
const observer = new MutationObserver(() => { | |
const video = document.querySelector('#container .html5-main-video') | |
const cinematics = document.querySelector('#cinematics') | |
if (video && cinematics) { | |
observer.disconnect() | |
console.log('hazy, disconnecting') | |
function drawCinematics({element, context}, {element: lastElement}) { | |
return new Promise(resolve => { | |
copyVideo(video, context) | |
const animation = element.animate([ | |
{ opacity: "0" }, | |
{ opacity: "1" }, | |
], { | |
duration: cinematicFrameDuration, | |
fill: 'forwards', | |
iterations: 1, | |
}) | |
animation.addEventListener('finish', () => resolve()) | |
lastElement.animate([ | |
{ opacity: "1" }, | |
{ opacity: "0" }, | |
], { | |
duration: cinematicFrameDuration, | |
fill: 'forwards', | |
iterations: 1, | |
}) | |
}) | |
} | |
async function drawLoop() { | |
const canvasLive = document.createElement('canvas') | |
const canvasLiveContext = canvasLive.getContext("2d") | |
canvasLive.id = 'cinematics-after' | |
const canvasPaused = document.createElement('canvas') | |
const canvasPausedContext = canvasPaused.getContext("2d") | |
canvasPaused.id = 'cinematics-before' | |
cinematics.appendChild(canvasPaused) | |
cinematics.appendChild(canvasLive) | |
let swap = false | |
let lastSize = '' | |
while (true) { | |
if (document.hidden) { | |
await new Promise(r => setTimeout(r, 1000)) | |
continue | |
} | |
const newSize = [video.videoWidth, video.videoHeight].join('x') | |
if (newSize != lastSize) { | |
canvasLive.width = video.videoWidth | |
canvasLive.height = video.videoHeight | |
canvasPaused.width = video.videoWidth | |
canvasPaused.height = video.videoHeight | |
lastSize = newSize | |
} | |
let cinematicsPromise | |
if (!swap) { | |
cinematicsPromise = drawCinematics({element: canvasLive, context: canvasLiveContext}, {element: canvasPaused}) | |
} else { | |
cinematicsPromise = drawCinematics({element: canvasPaused, context: canvasPausedContext}, {element: canvasLive}) | |
} | |
await Promise.race([cinematicsPromise, new Promise(r => setTimeout(r, cinematicFrameDuration * 2))]) | |
swap = !swap | |
} | |
} | |
drawLoop() | |
} | |
}) | |
observer.observe(document.body, { | |
childList: true, | |
subtree: true, | |
}) | |
const style = document.createElement('style') | |
style.innerHTML = ` | |
ytd-watch-flexy[theater] #player.ytd-watch-flexy { | |
display: unset !important; | |
position: absolute; | |
top: 0; | |
padding-top: 56px; | |
padding-bottom: 400px; | |
overflow: hidden; | |
left: 0; | |
right: 0; | |
z-index: 0; | |
pointer-events: none; | |
height: 56.25vw; | |
max-height: calc(100vh - 169px); | |
} | |
#player-theater-container { | |
position: relative; | |
z-index: 10; | |
} | |
ytd-watch-flexy[theater] #player-theater-container.ytd-watch-flexy, ytd-watch-flexy[fullscreen] #player-theater-container.ytd-watch-flexy, | |
ytd-watch-flexy[theater] #player-wide-container.ytd-watch-flexy, ytd-watch-flexy[fullscreen] #player-wide-container.ytd-watch-flexy { | |
background: none; | |
z-index: 10; | |
} | |
#cinematics { | |
isolation: isolate; | |
position: relative; | |
display: grid; | |
place-items: center; | |
} | |
ytd-watch-flexy[theater] #cinematics { | |
position: relative; | |
width: 100%; | |
height: 56.25vw; | |
max-height: calc(100vh - 169px); | |
} | |
#cinematics canvas { | |
position: absolute; | |
mix-blend-mode: plus-lighter; | |
filter: blur(var(--blur)); | |
--blur: 100px; | |
--spread: 8rem; | |
max-width: calc(100% + var(--spread)); | |
height: calc(100% + var(--spread)); | |
}` | |
document.body.appendChild(style) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment