Greasy Fork

Youtube download button - y2mate

This Script Adds a Download Button on the left side of the subscribe button, you can easily download Audio/Video

当前为 2024-06-15 提交的版本,查看 最新版本

// ==UserScript==
// @name            Youtube download button - y2mate
// @namespace       http://tampermonkey.net/
// @version         1.0.1
// @author          God Mario
// @match           https://www.youtube.com/watch
// @match           https://*.youtube.com/*
// @run-at          document-start
// @icon            https://cdn.icon-icons.com/icons2/822/PNG/512/download_icon-icons.com_66472.png
// @grant           GM_addStyle
// @license         MIT
// @description     This Script Adds a Download Button on the left side of the subscribe button, you can easily download Audio/Video
// ==/UserScript==

(function() {
    const textButton = "Descargar";
    const icon = '<div style="height: 90%; margin-left: -8px; fill: currentcolor;"><svg xmlns="http://www.w3.org/2000/svg" height="24" viewBox="0 0 24 24" width="24" focusable="false" style="pointer-events: none; display: inherit; width: 100%; height: 100%;"><path d="M17 18v1H6v-1h11zm-.5-6.6-.7-.7-3.8 3.7V4h-1v10.4l-3.8-3.8-.7.7 5 5 5-4.9z"></path></svg></div>';
    const API = "https://www.y2mate.com/download-youtube/";
    const BUTTON_ID = "dwnldBtn";
    const TARGET_BUTTON = "#analytics-button";

    const buttonStyle = `
        #${BUTTON_ID} {
            background-color: var(--yt-spec-additive-background);
            color: var(--yt-spec-text-primary);
            margin: 0px 4px;
            border-radius: 18px;
            width: 120px;
            height: 36px;
            line-height: 37px;
            text-align: center;
            font-style: normal;
            font-size: 14px;
            font-family: Roboto, Noto, sans-serif;
            font-weight: 500;
            text-decoration: none;
            display: flex;
            align-items: center;
            justify-content: center;
        }
        #${BUTTON_ID}:hover {
            background-color: var(--yt-spec-mono-tonal-hover);
            color: var(--yt-spec-text-primary);
        }
    `;

    GM_addStyle(buttonStyle);

    let lastUrl = null;

    function waitForElement(selector) {
        return new Promise(resolve => {
            if (document.querySelector(selector)) {
                return resolve(document.querySelector(selector));
            }
            const observer = new MutationObserver(mutations => {
                if (document.querySelector(selector)) {
                    resolve(document.querySelector(selector));
                    observer.disconnect();
                }
            });
            observer.observe(document.body, { childList: true, subtree: true });
        });
    }

    function getIdVideo(url) {
        if (url.includes("v=")) {
            let indice = url.indexOf("v=");
            let id = url.slice(indice + 2);

            return id;
        } else {
            return null;
        }
    }

    function addButton() {
        let url1 = window.location.href;
        let idVideo = getIdVideo(url1);
        waitForElement(TARGET_BUTTON).then((btn) => {
            btn.innerHTML += `<a href="${API + idVideo}" target="_blank" id="${BUTTON_ID}">${icon}${textButton}</a>`;
        });
    }

    function updateButton() {
        let url1 = window.location.href;
        if (url1 !== lastUrl) {
            lastUrl = url1;
            let idVideo = getIdVideo(url1);
            waitForElement(`#${BUTTON_ID}`).then((btn) => {
                btn.href = API + idVideo;
            });
        }
    }

    window.onload = function() {
        let url1 = window.location.href;
        let idVideo = getIdVideo(url1);
        addButton();
    };

    window.addEventListener("yt-navigate-start", updateButton, true);
})();