Miniplayer button

Adds the miniplayer button next to the YouTube logo.

Terá de instalar uma extensão como Tampermonkey, Greasemonkey ou Violentmonkey para instalar este script.

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

Terá de instalar uma extensão como Tampermonkey ou Violentmonkey para instalar este script.

Terá de instalar uma extensão como Tampermonkey ou Userscripts para instalar este script.

Terá de instalar uma extensão como Tampermonkey para instalar este script.

Terá de instalar uma extensão de gestão de scripts de utilizador para instalar este script.

(Já tenho um gestor de scripts de utilizador, deixe-me instalá-lo!)

Terá de instalar uma extensão como Stylus para instalar este estilo.

Terá de instalar uma extensão como Stylus para instalar este estilo.

Terá de instalar uma extensão como Stylus para instalar este estilo.

Terá de instalar uma extensão de gestão de estilos de utilizador para instalar este estilo.

Terá de instalar uma extensão de gestão de estilos de utilizador para instalar este estilo.

Terá de instalar uma extensão de gestão de estilos de utilizador para instalar este estilo.

(Já tenho um gestor de estilos de utilizador, deixe-me instalá-lo!)

// ==UserScript==
// @name         Miniplayer button
// @namespace    http://tampermonkey.net/
// @version      2026-06-26
// @description  Adds the miniplayer button next to the YouTube logo.
// @author       EiskaffeAffection
// @match        *://*.youtube.com/*
// @exclude      *://music.youtube.com/*
// @exclude      *://*.music.youtube.com/*
// @icon         https://www.google.com/s2/favicons?sz=64&domain=youtube.com
// @grant        none
// @license      MIT
// ==/UserScript==

(function() {
    'use strict';

    const style = document.createElement('style');
    style.textContent = `
        #miniplayer-button-container {
            padding-left: 10px;
            display: flex;
            align-items: center;
        }

        #miniplayer-button {
            display: flex;
            align-items: center;
            justify-content: center;
            width: 40px;
            height: 40px;
            border-radius: 50%;
            cursor: pointer;
            transition: background-color 0.2s ease;
            background-color: #272727;
        }
        #miniplayer-button:hover {
            background-color: #525252;
        }
        #miniplayer-button svg {
            fill: #FFFFFF;
            transition: fill 0.2s ease;
        }

        html:not([dark]) ytd-masthead:not([theater]) #miniplayer-button,
        html:not([dark]) ytd-masthead:not([dark]) #miniplayer-button {
            background-color: #F2F2F2;
        }
        html:not([dark]) ytd-masthead:not([theater]) #miniplayer-button:hover,
        html:not([dark]) ytd-masthead:not([dark]) #miniplayer-button:hover {
            background-color: #D9D9D9;
        }
        html:not([dark]) ytd-masthead:not([theater]) #miniplayer-button svg,
        html:not([dark]) ytd-masthead:not([dark]) #miniplayer-button svg {
            fill: #000000;
        }
    `;
    document.head.appendChild(style);

    const observer = new MutationObserver(() => {
        const isWatchPage = window.location.pathname.startsWith('/watch');
        const existingContainer = document.getElementById("miniplayer-button-container");

        if (!isWatchPage) {
            if (existingContainer) {
                existingContainer.remove();
            }
            return;
        }

        if (existingContainer) {
            return;
        }

        const strt = document.querySelector("#start.ytd-masthead");
        if (!strt) {
            return;
        }

        const container = document.createElement('div');
        container.id = "miniplayer-button-container";

        const btn = document.createElement('div');
        btn.id = "miniplayer-button";

        btn.addEventListener('click', () => {
            const player = document.querySelector('.html5-video-player');

            if (player) {
                const keyEvent = new KeyboardEvent('keydown', {
                    key: 'i',
                    code: 'KeyI',
                    keyCode: 73,
                    which: 73,
                    bubbles: true,
                    cancelable: true
                });
                player.dispatchEvent(keyEvent);
            }
        });

        const svg = document.createElementNS("http://www.w3.org/2000/svg", "svg");
        svg.setAttribute("height", "24");
        svg.setAttribute("viewBox", "0 0 24 24");
        svg.setAttribute("width", "24");

        const path = document.createElementNS("http://www.w3.org/2000/svg", "path");
        path.setAttribute("d", "M21.20 3.01C21.66 3.05 22.08 3.26 22.41 3.58C22.73 3.91 22.94 4.33 22.98 4.79L23 5V19C23.00 19.49 22.81 19.97 22.48 20.34C22.15 20.70 21.69 20.93 21.20 20.99L21 21H3L2.79 20.99C2.30 20.93 1.84 20.70 1.51 20.34C1.18 19.97 .99 19.49 1 19V13H3V19H21V5H11V3H21L21.20 3.01ZM1.29 3.29C1.10 3.48 1.00 3.73 1.00 4C1.00 4.26 1.10 4.51 1.29 4.70L5.58 9H3C2.73 9 2.48 9.10 2.29 9.29C2.10 9.48 2 9.73 2 10C2 10.26 2.10 10.51 2.29 10.70C2.48 10.89 2.73 11 3 11H9V5C9 4.73 8.89 4.48 8.70 4.29C8.51 4.10 8.26 4 8 4C7.73 4 7.48 4.10 7.29 4.29C7.10 4.48 7 4.73 7 5V7.58L2.70 3.29C2.51 3.10 2.26 3.00 2 3.00C1.73 3.00 1.48 3.10 1.29 3.29ZM19.10 11.00L19 11H12L11.89 11.00C11.66 11.02 11.45 11.13 11.29 11.29C11.13 11.45 11.02 11.66 11.00 11.89L11 12V17C10.99 17.24 11.09 17.48 11.25 17.67C11.42 17.85 11.65 17.96 11.89 17.99L12 18H19L19.10 17.99C19.34 17.96 19.57 17.85 19.74 17.67C19.90 17.48 20.00 17.24 20 17V12L19.99 11.89C19.97 11.66 19.87 11.45 19.70 11.29C19.54 11.13 19.33 11.02 19.10 11.00ZM13 16V13H18V16H13Z");

        svg.appendChild(path);
        btn.appendChild(svg);
        container.appendChild(btn);
        strt.appendChild(container);
    });

    observer.observe(document.body, {
        subtree: true,
        childList: true,
    });
})();