YouTube Exit Fullscreen on Video End (Modified)

Exit YouTube fullscreen when a video finishes playing (disabled for playlists)

目前為 2023-06-29 提交的版本,檢視 最新版本

// ==UserScript==
// @name         YouTube Exit Fullscreen on Video End (Modified)
// @namespace    https://www.youtube.com/
// @version      1.2.1
// @description  Exit YouTube fullscreen when a video finishes playing (disabled for playlists)
// @author       CY Fung
// @match        *://www.youtube.com/*
// @license      MIT
// @icon         https://www.google.com/s2/favicons?domain=youtube.com
// @grant        none
// @run-at       document-start
// ==/UserScript==

(() => {
    let lastPause = 0;
    let lastFullscreenEnded = 0;
    let observer = null;

    const check = () => Math.abs(lastFullscreenEnded - lastPause) < 400 && Date.now() - lastPause < 800;

    const mCallback = (mutations) => {
        if (!document.fullscreenElement) return;
        let detected = false;
        let video = null;
        for (const mutation of mutations) {
            video = (mutation || 0).target;
            if (!video) continue;
            const newValue = video.className;
            const oldValue = mutation.oldValue;
            if (newValue.indexOf("ended-mode") >= 0 && oldValue.indexOf("ended-mode") < 0) {
                detected = true;
                break;
            }
        }
        if (detected) {
            if (video && video.classList.contains("ended-mode")) {
                lastFullscreenEnded = Date.now();
                check() && endFullscreen(video);
            }
        }
    }

    const endFullscreen = (elm) => {
        lastPause = 0;
        lastFullscreenEnded = 0;
        const movie_player = HTMLElement.prototype.closest.call(elm, '#movie_player');
        const btn = movie_player ? HTMLElement.prototype.querySelector.call(movie_player, '.ytp-fullscreen-button') : null;
        if (btn) {
            btn.click();
        } else {
            document.exitFullscreen();
        }
    }

    const setup = async () => {
        if (location.href.includes("/watch") && !location.href.includes("list=")) {
            let videoPlayer = document.getElementById('movie_player');
            if (videoPlayer) {
                if (!observer) observer = new MutationObserver(mCallback); else {
                    observer.disconnect();
                    observer.takeRecords();
                }
                observer.observe(videoPlayer, {
                    attributes: true,
                    attributeFilter: ['class'],
                    attributeOldValue: true
                });
            } else if (observer) {
                observer.disconnect();
                observer.takeRecords();
                observer = null;
            }
        }
    }

    const onPause = (evt) => {
        const target = ((evt || 0).target || 0);
        if (!(target instanceof HTMLVideoElement)) return;
        if (observer === null) return;
        lastPause = Date.now();
        check() && endFullscreen(target);
    }

    document.addEventListener('yt-navigate-finish', setup, false);
    document.addEventListener('spfdone', setup, true);
    document.addEventListener("pause", onPause, true);
    setup();
})();

QingJ © 2025

镜像随时可能失效,请加Q群300939539或关注我们的公众号极客氢云获取最新地址