Skip to content

Instantly share code, notes, and snippets.

@ultrox
Created March 29, 2026 14:20
Show Gist options
  • Select an option

  • Save ultrox/d2df014457821bc4fd129fa7c451095a to your computer and use it in GitHub Desktop.

Select an option

Save ultrox/d2df014457821bc4fd129fa7c451095a to your computer and use it in GitHub Desktop.
walk the subs, change the language
// ==UserScript==
// @name PLM Styles Only
// @namespace http://tampermonkey.net/
// @version 0.3.0
// @description Toggle subs, clean mode & audio language on Prime Video
// @author Marko
// @match https://www.primevideo.com/*
// @icon https://www.google.com/s2/favicons?sz=64&domain=primevideo.com
// @grant none
// ==/UserScript==
(async function () {
"use strict";
// ── Boot ────────────────────────────────────────────────────
const xs = await loadXState();
if (!xs) return;
const { createMachine, createActor, assign } = xs;
const plmStyle = injectStyleTag();
const toast = createToast();
// ── Side effects ────────────────────────────────────────────
const applyStyles = ({ context }) => {
let css = "";
if (context.subsHidden) {
css += `.atvwebplayersdk-captions-text,
[class*="atvwebplayersdk-captions-text"] {visibility: hidden !important;}`;
}
if (context.overlayHidden) {
css += `[aria-label='Web Player'] {display: none !important;}`;
}
plmStyle.textContent = css;
};
const switchAudio = ({ context }) => {
const label = context.audioDeutsch ? "Deutsch" : "English";
const radio = document.querySelector(`.atvwebplayersdk-audio-group input[aria-label="${label}"]`);
if (radio) {
radio.click();
toast("🔊 " + label);
} else {
toast("⚠️ " + label + " not found");
}
};
// ── Machine ─────────────────────────────────────────────────
const machine = createMachine({
id: "plm",
initial: "active",
context: {
subsHidden: false,
overlayHidden: false,
audioDeutsch: false,
},
states: {
active: {
on: {
TOGGLE_SUBS: {
actions: [
assign({ subsHidden: ({ context }) => !context.subsHidden }),
applyStyles,
],
},
TOGGLE_OVERLAY: {
actions: [
assign({ overlayHidden: ({ context }) => !context.overlayHidden }),
applyStyles,
],
},
TOGGLE_AUDIO: {
actions: [
assign({ audioDeutsch: ({ context }) => !context.audioDeutsch }),
switchAudio,
],
},
},
},
},
});
// ── Actor ───────────────────────────────────────────────────
const actor = createActor(machine);
actor.start();
// ── Keyboard ────────────────────────────────────────────────
document.addEventListener("keydown", (e) => {
if (e.target.tagName === "INPUT" || e.target.tagName === "TEXTAREA") return;
if (!e.shiftKey || e.ctrlKey || e.altKey || e.metaKey) return;
switch (e.key) {
case "S":
case "s":
e.preventDefault();
e.stopPropagation();
actor.send({ type: "TOGGLE_SUBS" });
toast(actor.getSnapshot().context.subsHidden ? "👁️‍🗨️ Subs hidden" : "👁️ Subs visible");
break;
case "D":
case "d":
e.preventDefault();
e.stopPropagation();
actor.send({ type: "TOGGLE_OVERLAY" });
toast(actor.getSnapshot().context.overlayHidden ? "🧹 Clean mode" : "📺 Normal mode");
break;
case "A":
case "a":
e.preventDefault();
e.stopPropagation();
actor.send({ type: "TOGGLE_AUDIO" });
break;
}
}, true);
console.log("[PLM] v0.3.0 loaded (styles + audio)");
// ── Infrastructure (scroll past here) ───────────────────────
async function loadXState() {
try {
return await import("https://esm.sh/xstate@5");
} catch (e) {
console.error("[PLM] Failed to load XState:", e);
return null;
}
}
function injectStyleTag() {
const el = document.createElement("style");
el.id = "plm-style";
document.head.appendChild(el);
return el;
}
function createToast() {
const el = document.createElement("div");
Object.assign(el.style, {
position: "fixed",
top: "80px",
left: "50%",
transform: "translateX(-50%)",
zIndex: "9999999",
background: "rgba(0,0,0,0.9)",
color: "#fff",
fontFamily: "monospace",
fontSize: "14px",
padding: "8px 18px",
borderRadius: "20px",
opacity: "0",
transition: "opacity 0.3s",
pointerEvents: "none",
});
document.body.appendChild(el);
let timer;
return (msg) => {
el.textContent = msg;
el.style.opacity = "1";
clearTimeout(timer);
timer = setTimeout(() => (el.style.opacity = "0"), 1500);
};
}
})();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment