YouTube Localhost Ad-Free Player

Play YouTube videos ad-free using an iframe embed served from localhost

2025-08-24 يوللانغان نەشرى. ئەڭ يېڭى نەشرىنى كۆرۈش.

You will need to install an extension such as Tampermonkey, Greasemonkey or Violentmonkey to install this script.

You will need to install an extension such as Tampermonkey or Violentmonkey to install this script.

You will need to install an extension such as Tampermonkey or Violentmonkey to install this script.

You will need to install an extension such as Tampermonkey or Userscripts to install this script.

You will need to install an extension such as Tampermonkey to install this script.

You will need to install a user script manager extension to install this script.

(I already have a user script manager, let me install it!)

You will need to install an extension such as Stylus to install this style.

You will need to install an extension such as Stylus to install this style.

You will need to install an extension such as Stylus to install this style.

You will need to install a user style manager extension to install this style.

You will need to install a user style manager extension to install this style.

You will need to install a user style manager extension to install this style.

(I already have a user style manager, let me install it!)

// ==UserScript==
// @name        YouTube Localhost Ad-Free Player
// @namespace   Violentmonkey Scripts
// @match       *://www.youtube.com/*
// @version     1.0
// @author      CyrilSLi
// @description Play YouTube videos ad-free using an iframe embed served from localhost
// @license     MIT
// ==/UserScript==

const frameId = "userscriptLocalhostFrame";
const embedURL = "https://www.youtube-nocookie.com/embed/%v?playlist=%p&autoplay=1&start=%start&enablejsapi=1";
const frameSrc = "http://localhost:8823?url=";
const runFreq = 200;

let resumeTime = 0, oldDataset = {};

window.addEventListener("message", (ev) => {
    if (!ev.data) {
        return;
    }
    const data = (typeof ev.data === 'string' || ev.data instanceof String) ? JSON.parse(ev.data) : ev.data;
    if (data.event == "infoDelivery") {
        resumeTime = Math.floor(data?.info?.currentTime || resumeTime);
        const playlist = data?.info?.playlist;
        if (playlist && playlist.length > 0) {
            oldDataset.playlist = playlist.join(",");
            const oldVideoId = oldDataset.videoId;
            oldDataset.videoId = playlist[data?.info?.playlistIndex] || globalFrame.dataset.videoId;
            if (oldVideoId && oldVideoId !== oldDataset.videoId) {
                const params = new URLSearchParams(window.location.search);
                params.set("v", oldDataset.videoId);
                params.set("userscript_modified", "1");
                window.history.pushState({}, "", window.location.pathname + "?" + params.toString());
            }
            if (playlist.length > 1) {
                const title = document.querySelector("h1.ytd-watch-metadata").children[0];
                if (title) {
                    title.textContent = data?.info?.videoData?.title || title.textContent;
                }
                const author = document.querySelector("#text.ytd-channel-name").children[0];
                if (author) {
                    author.textContent = data?.info?.videoData?.author || author.textContent;
                }
            }
        }
    }
});

function run(container) {
    const visible = container.offsetHeight > 0;
    let frame;

    [...container.children].forEach((el) => {
        if (el.className === frameId) {
            frame = el;
        } else {
            el.style.visibility = "hidden";
        }
    });
    if (!visible) {
        if (frame) {
            if (!oldDataset) {
                oldDataset = Object.assign({}, frame.dataset);
            }
            frame.remove();
        }
        return;
    }

    function updateSrc() {
        frame.src = frameSrc + encodeURIComponent(embedURL
            .replace("%v", frame.dataset.videoId)
            .replace("%p", frame.dataset.playlist || frame.dataset.videoId)
            .replace("%start", resumeTime)
        );
    }
    function selectList() {
        [...document.querySelector("#items.playlist-items").children].forEach((el) => {
            try {
                if (new URLSearchParams(el.getElementsByTagName("a")[0].search).get("v") === frame.dataset.videoId) {
                    el.setAttribute("selected", "true");
                } else {
                    el.removeAttribute("selected");
                }
            } catch (e) {
                // Error handling if needed
            }
        });
    }

    if (!frame) {
        frame = document.createElement("iframe");
        container.appendChild(frame);
        frame.className = frameId;
        frame.style.position = "absolute";
        frame.style.inset = "0";
        frame.style.width = "100%";
        frame.style.height = "100%";
        frame.style.border = "none";
        frame.allow = "autoplay; fullscreen";
        frame.allowFullscreen = true;
        if (oldDataset.videoId) {
            frame.dataset.videoId = oldDataset.videoId;
            frame.dataset.playlist = oldDataset.playlist || oldDataset.videoId;
            if (oldDataset.userscriptModified === "1") {
                const params = new URLSearchParams(window.location.search);
                if (params.get("list") && params.get("list") === oldDataset.listId) {
                    params.set("v", oldDataset.videoId);
                    window.history.pushState({}, "", window.location.pathname + "?" + params.toString());
                    selectList();
                }
            }
            oldDataset = {};
            updateSrc();
        }
    }

    if (!container.classList.contains("ytdMiniplayerPlayerContainerHost")) {
        const params = new URLSearchParams(window.location.search);
        videoId = params.get("v");
        if (!videoId) {
            return;
        } else if (videoId !== frame.dataset.videoId) {
            if (oldDataset.videoId) {
                if (params.get("userscript_modified") === "1" && params.get("list")) {
                    frame.dataset.videoId = oldDataset.videoId;
                    selectList();
                    return;
                } else {
                    window.location.reload();
                }
            }
            resumeTime = 0; // Switching videos, reset resume time
            frame.dataset.videoId = videoId;
            const playlistEl = document.querySelector("#items.playlist-items");
            if (playlistEl && playlistEl.children.length > 0) {
                const playlistIds = [];
                [...playlistEl.children].forEach((el) => {
                    try {
                        playlistIds.push(new URLSearchParams(el.getElementsByTagName("a")[0].search).get("v"));
                    } catch (e) {
                        // Error handling if needed
                    }
                });
                frame.dataset.playlist = playlistIds.join(",");
            } else {
                frame.dataset.playlist = videoId;
            }
            updateSrc();
        }
    } else {
        if (frame.dataset.playlist !== frame.dataset.videoId) {
            oldDataset.userscriptModified = "1";
            const params = new URLSearchParams(window.location.search);
            oldDataset.listId = params.get("list");
        }
    }
}

var lastRan = 0;
const observer = new MutationObserver(() => {
    document.getElementsByClassName("html5-main-video")[0]?.pause();
    if (Date.now() - lastRan < runFreq) {
        return;
    }
    lastRan = Date.now();
    ["#player-container-inner", "#full-bleed-container", ".ytdMiniplayerPlayerContainerHost"].forEach((id) => {
        const container = document.querySelector(id);
        if (container) {
            run(container);
        }
    });
});

if (!window.location.pathname.includes("embed")) {
    observer.observe(document.body, {
        attributes: false,
        childList: true,
        characterData: false,
        subtree: true
    });
}