Skip to content

Instantly share code, notes, and snippets.

@tsi
Created April 9, 2025 15:27
Show Gist options
  • Save tsi/cfb85f54812ae44de8beb7ca0db11e30 to your computer and use it in GitHub Desktop.
Save tsi/cfb85f54812ae44de8beb7ca0db11e30 to your computer and use it in GitHub Desktop.
function forwardPlayers(doc = document) {
doc.querySelectorAll(".vjs-v8").forEach(player => {
if (player.player.currentTime() < player.player.duration() - 1) {
player.player.currentTime(player.player.duration() - 0.1);
logs.push(["forwarded: ", player]);
}
});
}
function clickNext(doc = document) {
doc.querySelectorAll("button").forEach(btn => {
if (btn.title?.includes("Playback")) {
logs.push(["skipping (playback): ", btn]);
return;
}
// if button is a child of a span with class vjs-control-text, skip
if (btn.parentElement?.classList?.contains("vjs-has-started")) {
logs.push(["skipping (has started): ", btn]);
return;
}
if (btn.textContent?.includes("Next") || btn.title?.includes("Play") || btn.getAttribute('aria-label')?.includes("Play") || btn.getAttribute('aria-label')?.includes("Next")) {
btn.click();
logs.push(["clicked: ", btn]);
}
});
}
function parseDom(doc = document) {
forwardPlayers(doc);
clickNext(doc);
// Recursively check iframes
doc.querySelectorAll("iframe").forEach(iframe => {
try {
const iframeDoc = iframe.contentDocument || iframe.contentWindow.document;
if (iframeDoc) {
parseDom(iframeDoc);
}
} catch (e) {
// Skip iframes we can't access (cross-origin)
logs.push(["skipping iframe: ", iframe.name]);
}
});
}
// Create a collapsed group for all logs
const logs = [];
console.log("easierllama.js Logs", logs);
console.log("call `stop()` to kill the script");
const interval = setInterval(() => {
parseDom(document);
}, 1000);
// add a function to break the interval
const stop = () => {
clearInterval(interval);
console.log("easierllama.js stopped");
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment