Skip to content

Instantly share code, notes, and snippets.

@kyohsuke
Last active October 15, 2025 16:36
Show Gist options
  • Select an option

  • Save kyohsuke/eac69ddef61d4cd8d165c8b2e59ff0ef to your computer and use it in GitHub Desktop.

Select an option

Save kyohsuke/eac69ddef61d4cd8d165c8b2e59ff0ef to your computer and use it in GitHub Desktop.
// ==UserScript==
// @name Auto Refresh YouTube Live
// @description Automatically tracks live head for YouTube Live
// @match https://www.youtube.com/*
// @version 1.0.3
// @homepageURL https://gist.github.com/kyohsuke/eac69ddef61d4cd8d165c8b2e59ff0ef
// @updateURL https://gist.githubusercontent.com/kyohsuke/eac69ddef61d4cd8d165c8b2e59ff0ef/raw/youtubeLiveObserver.user.js
// @downloadURL https://gist.githubusercontent.com/kyohsuke/eac69ddef61d4cd8d165c8b2e59ff0ef/raw/youtubeLiveObserver.user.js
// @icon https://cdn3.iconfinder.com/data/icons/social-network-30/512/social-06-1024.png
// @grant none
// ==/UserScript==
(function(){
function liveTracker() {
console.log("Init Live Tracker");
const initialInterval = 3;
let observer = null;
let liveInterval = initialInterval;
let currentURL = "";
function isLive() {
let liveBtn = document.getElementsByClassName("ytp-live-badge")[0];
return (liveBtn != undefined && window.getComputedStyle(liveBtn).display != "none");
}
function addObserver() {
let liveBtn = document.getElementsByClassName("ytp-live-badge")[0];
const handleMutation = (mutationsList, observer) => {
mutationsList.forEach(mutation => {
// 変更に対する処理
let onLive = false;
mutation.target.classList.forEach(className => {
if(className == "ytp-live-badge-is-livehead") {
onLive = true;
}
});
if(isLive() && !onLive) {
let nextDelay = 1000 * liveInterval;
console.log("Move ahead after", liveInterval, "seconds");
if(liveInterval < 10) {
liveInterval += 1;
}
setTimeout(function(){
if(isLive()) {
console.log("Click Live!");
liveBtn.click();
}
}, nextDelay);
}
});
};
if(observer != null) {
observer.disconnect();
}
observer = new MutationObserver(handleMutation);
observer.observe(liveBtn, {
attributeFilter: ["class"],
});
}
function putEvents() {
liveInterval = initialInterval;
addObserver();
}
setInterval(function(){
let pickURL = location.href;
if(currentURL != pickURL) {
currentURL = pickURL;
setTimeout(putEvents, 1000);
}
}, 1000);
}
liveTracker();
})();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment