Last active
March 29, 2024 19:45
-
-
Save Explosion-Scratch/061ed67bd292e07fbd018cc7ddbdce8d 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 Auto Picture-in-Picture | |
// @namespace mailto:explosionscratch@gmail.com | |
// @version 0.1 | |
// @description Auto picture in picture for YouTube | |
// @author Explosion-Scratch | |
// @match *://youtube.*/* | |
// @grant none | |
// ==/UserScript== | |
/* Copyright (C) Mar 29, 2024 Explosion-Scratch - All Rights Reserved | |
* You may use, distribute and modify this code under the | |
* terms of the Attribution-ShareAlike 4.0 International license. | |
* | |
* You should have received a copy of the Attribution-ShareAlike | |
* 4.0 International license with this file. If not, please write | |
* to: explosionscatch@gmail.com, or visit: | |
* https://creativecommons.org/licenses/by-sa/4.0/ | |
*/ | |
const getVideo = () => | |
[...document.querySelectorAll("video")].filter((i) => { | |
let rect = i.getBoundingClientRect(); | |
return ( | |
rect.width * rect.height > window.innerWidth * window.innerHeight * 0.2 && | |
!i.paused && | |
!i.mute | |
); | |
})?.[0]; | |
let isBlurred = false; | |
const listeners = { | |
blur: (vid) => { | |
vid.requestPictureInPicture(); | |
}, | |
focus: (vid) => { | |
document.exitPictureInPicture(); | |
}, | |
}; | |
const cb = () => { | |
const vid = getVideo(); | |
if (!vid) { | |
return; | |
} | |
window.onblur = () => listeners.blur(vid); | |
window.onfocus = () => listeners.focus(vid); | |
}; | |
observe("body", cb); | |
cb(); | |
function observe(target, callback, options = {}) { | |
let elements = []; | |
if (typeof target === "string") { | |
elements = Array.from(document.querySelectorAll(target)); | |
} else if (target instanceof Element) { | |
elements = [target]; | |
} else { | |
throw new Error( | |
"Invalid target. Expected a query selector string or an Element." | |
); | |
} | |
const observer = new MutationObserver((mutations) => { | |
mutations.forEach((mutation) => { | |
callback(mutation.target, options); | |
}); | |
}); | |
const defaultOptions = { | |
childList: true, | |
attributes: true, | |
characterData: true, | |
subtree: true, | |
}; | |
const observerOptions = { ...defaultOptions, ...options }; | |
elements.forEach((element) => { | |
observer.observe(element, observerOptions); | |
}); | |
return observer; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment