OnlyFans - Hide Video Controls Overlay

Hide the controls overlay on Onlyfans video player

スクリプトをインストールするには、Tampermonkey, GreasemonkeyViolentmonkey のような拡張機能のインストールが必要です。

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

スクリプトをインストールするには、TampermonkeyViolentmonkey のような拡張機能のインストールが必要です。

スクリプトをインストールするには、TampermonkeyUserscripts のような拡張機能のインストールが必要です。

このスクリプトをインストールするには、Tampermonkeyなどの拡張機能をインストールする必要があります。

このスクリプトをインストールするには、ユーザースクリプト管理ツールの拡張機能をインストールする必要があります。

(ユーザースクリプト管理ツールは設定済みなのでインストール!)

このスタイルをインストールするには、Stylusなどの拡張機能をインストールする必要があります。

このスタイルをインストールするには、Stylus などの拡張機能をインストールする必要があります。

このスタイルをインストールするには、Stylus tなどの拡張機能をインストールする必要があります。

このスタイルをインストールするには、ユーザースタイル管理用の拡張機能をインストールする必要があります。

このスタイルをインストールするには、ユーザースタイル管理用の拡張機能をインストールする必要があります。

このスタイルをインストールするには、ユーザースタイル管理用の拡張機能をインストールする必要があります。

(ユーザースタイル管理ツールは設定済みなのでインストール!)

このスクリプトの質問や評価の投稿はこちら通報はこちらへお寄せください
// ==UserScript==
// @name         OnlyFans - Hide Video Controls Overlay
// @version      0.6.3
// @description  Hide the controls overlay on Onlyfans video player
// @author       pipstar
// @match        https://onlyfans.com/*
// @run-at       document-start
// @grant        GM_registerMenuCommand
// @grant        GM_unregisterMenuCommand
// @grant        GM_getValue
// @grant        GM_setValue
// @icon         data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAzMiAzMiI+PHJlY3QgeD0iMiIgeT0iMTAuNSIgd2lkdGg9IjI4IiBoZWlnaHQ9IjExIiByeD0iMy4yIiBmaWxsPSIjMDBBRkYwIi8+PHBhdGggZD0iTTcgMTMuNCBMNyAxOC42IEwxMS40IDE2IFoiIGZpbGw9IiNmZmYiLz48cmVjdCB4PSIxMy41IiB5PSIxNS4xIiB3aWR0aD0iMTQiIGhlaWdodD0iMS44IiByeD0iMC45IiBmaWxsPSIjZmZmIiBvcGFjaXR5PSIwLjQ1Ii8+PHJlY3QgeD0iMTMuNSIgeT0iMTUuMSIgd2lkdGg9IjYiIGhlaWdodD0iMS44IiByeD0iMC45IiBmaWxsPSIjZmZmIi8+PGNpcmNsZSBjeD0iMTkuNSIgY3k9IjE2IiByPSIyLjQiIGZpbGw9IiNmZmYiLz48bGluZSB4MT0iNCIgeTE9IjI4IiB4Mj0iMjgiIHkyPSI0IiBzdHJva2U9IiNmZmYiIHN0cm9rZS13aWR0aD0iNiIgc3Ryb2tlLWxpbmVjYXA9InJvdW5kIi8+PGxpbmUgeDE9IjQiIHkxPSIyOCIgeDI9IjI4IiB5Mj0iNCIgc3Ryb2tlPSIjZmYyZDU1IiBzdHJva2Utd2lkdGg9IjMuNCIgc3Ryb2tlLWxpbmVjYXA9InJvdW5kIi8+PC9zdmc+
// @license      MIT
// @namespace https://greasyfork.org/users/1275465
// ==/UserScript==

(function () {
    'use strict';

    /* ------------------------------------------------------------------ *
     * CONFIG - which elements count as "the controls" the toggle governs.
     * ------------------------------------------------------------------ */
    const HIDE_CONTROL_BAR     = true;  // bottom bar: play, scrubber, volume, quality, fullscreen, "record"
    const HIDE_BIG_PLAY_BUTTON = true;  // large centered play button overlay

    const selectors = [];
    if (HIDE_CONTROL_BAR)     selectors.push('.video-js .vjs-control-bar');
    if (HIDE_BIG_PLAY_BUTTON) selectors.push('.video-js .vjs-big-play-button');

    const HIDE_CSS = `${selectors.join(',\n')} {
        display: none !important;
        opacity: 0 !important;
        pointer-events: none !important;
    }`;

    /* ------------------------------------------------------------------ *
     * STATE - persisted across page loads. Defaults to hidden.
     * ------------------------------------------------------------------ */
    const STORAGE_KEY = 'of_controls_hidden';
    let hidden = GM_getValue(STORAGE_KEY, true);

    // Single <style> element we flip on/off. Injected at document-start so
    // the bar never flashes when controls are meant to be hidden.
    const style = document.createElement('style');
    style.id = 'of-hide-controls-style';
    (document.head || document.documentElement).appendChild(style);

    function applyState() {
        // When hidden, inject the rules; when shown, clear them so video.js
        // resumes its normal hover/autohide behavior. Updates live.
        style.textContent = (hidden && selectors.length) ? HIDE_CSS : '';
    }

    /* ------------------------------------------------------------------ *
     * MENU TOGGLE - appears in the Tampermonkey popup under this script.
     * Re-registered on each toggle so its label reflects the current state.
     * ------------------------------------------------------------------ */
    let menuId;
    function registerMenu() {
        if (menuId !== undefined && typeof GM_unregisterMenuCommand === 'function') {
            try { GM_unregisterMenuCommand(menuId); } catch (e) { /* older TM */ }
        }
        const label = hidden
            ? 'Video controls: HIDDEN  \u2014  click to show  (Ctrl+Alt+V)'
            : 'Video controls: SHOWN  \u2014  click to hide  (Ctrl+Alt+V)';
        menuId = GM_registerMenuCommand(label, toggle);
    }

    function toggle() {
        hidden = !hidden;
        GM_setValue(STORAGE_KEY, hidden);
        applyState();
        registerMenu(); // refresh the menu label
    }

    /* ------------------------------------------------------------------ *
     * FULLSCREEN HELPERS - target the .video-js container, not the raw
     * <video>, so the browser doesn't draw its own native controls.
     * ------------------------------------------------------------------ */
    function pickPlayer() {
        const players = [...document.querySelectorAll('.video-js')];
        if (!players.length) return null;
        // Prefer a player that's actually playing.
        const playing = players.find(p => {
            const v = p.querySelector('video');
            return v && !v.paused && !v.ended && v.readyState > 2;
        });
        if (playing) return playing;
        // Otherwise, the one with the largest visible area in the viewport.
        let best = null, bestArea = -1;
        for (const p of players) {
            const r = p.getBoundingClientRect();
            const w = Math.max(0, Math.min(r.right, innerWidth) - Math.max(r.left, 0));
            const h = Math.max(0, Math.min(r.bottom, innerHeight) - Math.max(r.top, 0));
            const area = w * h;
            if (area > bestArea) { bestArea = area; best = p; }
        }
        return best || players[0];
    }

    function toggleFullscreen() {
        const fsEl = document.fullscreenElement || document.webkitFullscreenElement;
        if (fsEl) {
            (document.exitFullscreen || document.webkitExitFullscreen || function () {}).call(document);
            return;
        }
        const el = pickPlayer();
        if (!el) return;
        const req = el.requestFullscreen || el.webkitRequestFullscreen;
        if (req) req.call(el);
    }

    /* ------------------------------------------------------------------ *
     * KEYBOARD SHORTCUTS
     *   Ctrl+Alt+V : toggle controls (works regardless of state)
     *   F          : fullscreen the video, ONLY while controls are hidden
     *                and only when not typing in a field. Press again (or
     *                Esc) to exit.
     * Uses e.code (physical key) so it's layout-independent.
     * ------------------------------------------------------------------ */
    function isTyping(e) {
        const t = e.target;
        if (!t) return false;
        return t.isContentEditable ||
            t.tagName === 'INPUT' || t.tagName === 'TEXTAREA' || t.tagName === 'SELECT';
    }

    document.addEventListener('keydown', e => {
        // Ctrl+Alt+V -> toggle controls
        if (e.ctrlKey && e.altKey && !e.shiftKey && !e.metaKey &&
            (e.code === 'KeyV' || (e.key && e.key.toLowerCase() === 'v'))) {
            e.preventDefault();
            e.stopPropagation();
            toggle();
            return;
        }
        // F (no modifiers) -> fullscreen, only while controls are hidden
        if (!e.ctrlKey && !e.altKey && !e.metaKey && !e.shiftKey &&
            (e.code === 'KeyF' || (e.key && e.key.toLowerCase() === 'f'))) {
            if (hidden && !isTyping(e)) {
                e.preventDefault();
                e.stopPropagation();
                toggleFullscreen();
            }
        }
    }, true); // capture phase so we act before the page's own handlers

    /* ------------------------------------------------------------------ *
     * BOOT
     * ------------------------------------------------------------------ */
    applyState();
    registerMenu();
})();