YouTube toolkit

Adds download and transcript buttons below video info on YouTube

Tendrás que instalar una extensión para tu navegador como Tampermonkey, Greasemonkey o Violentmonkey si quieres utilizar este script.

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

Tendrás que instalar una extensión como Tampermonkey o Violentmonkey para instalar este script.

Necesitarás instalar una extensión como Tampermonkey o Userscripts para instalar este script.

Tendrás que instalar una extensión como Tampermonkey antes de poder instalar este script.

Necesitarás instalar una extensión para administrar scripts de usuario si quieres instalar este script.

(Ya tengo un administrador de scripts de usuario, déjame instalarlo)

Tendrás que instalar una extensión como Stylus antes de poder instalar este script.

Tendrás que instalar una extensión como Stylus antes de poder instalar este script.

Tendrás que instalar una extensión como Stylus antes de poder instalar este script.

Para poder instalar esto tendrás que instalar primero una extensión de estilos de usuario.

Para poder instalar esto tendrás que instalar primero una extensión de estilos de usuario.

Para poder instalar esto tendrás que instalar primero una extensión de estilos de usuario.

(Ya tengo un administrador de estilos de usuario, déjame instalarlo)

// ==UserScript==
// @name            YouTube toolkit
// @namespace       http://tampermonkey.net/
// @version         1.5
// @description     Adds download and transcript buttons below video info on YouTube
// @author          Bui Quoc Dung
// @match           *://*.youtube.com/*
// @match           *://y2meta-us.com/*
// @run-at          document-idle
// @grant           GM_addStyle
// ==/UserScript==

(function () {
    "use strict";

    // ============================================
    // YOUTUBE.COM - Add Download & Transcript buttons
    // ============================================
    if (window.location.hostname.includes("youtube.com")) {
        const STYLES = `
            #download-container {
                margin-top: 6px;
                padding: 6px 0;
                display: flex;
                align-items: center;
                gap: 6px;
            }
            .download-btn, .transcript-btn {
                font-size: 14px;
                font-weight: 500;
                background-color: transparent;
                color: currentColor;
                padding: 10px 15px;
                border-radius: 18px;
                border: none;
                cursor: pointer;
                font-family: "Roboto", "Arial", sans-serif;
                transition: background-color 0.2s;
            }
            .download-btn:hover, .transcript-btn:hover {
                background-color: rgba(255, 255, 255, 0.1);
            }
        `;
        GM_addStyle(STYLES);

        function createDownloadButton() {
            if (document.querySelector(".download-btn")) return null;
            
            const btn = document.createElement("button");
            btn.className = "download-btn";
            btn.textContent = "Download";
            btn.addEventListener("click", function () {
                const youtubeUrl = window.location.href.split('#')[0].split('&')[0];
                const y2metaUrl = "https://y2meta-us.com/?url=" + encodeURIComponent(youtubeUrl);
                window.open(y2metaUrl, "_blank");
            });
            return btn;
        }

        function createTranscriptButton() {
            if (document.querySelector(".transcript-btn")) return null;
            
            const btn = document.createElement("button");
            btn.className = "transcript-btn";
            btn.textContent = "Transcript";
            btn.addEventListener("click", function () {
                const youtubeUrl = window.location.href.split('#')[0];
                const urlParams = new URLSearchParams(new URL(youtubeUrl).search);
                const videoId = urlParams.get('v');
                
                if (videoId) {
                    const transcriptUrl = `https://youtubetotranscript.com/transcript?v=${videoId}`;
                    window.open(transcriptUrl, "_blank");
                } else {
                    alert("Video ID not found!");
                }
            });
            return btn;
        }

        function addButtonBelowTopRow() {
            const topRow = document.querySelector("#top-row.ytd-watch-metadata");
            if (!topRow || document.querySelector("#download-container")) return;

            const container = document.createElement("div");
            container.id = "download-container";

            const downloadBtn = createDownloadButton();
            const transcriptBtn = createTranscriptButton();

            if (downloadBtn) container.appendChild(downloadBtn);
            if (transcriptBtn) container.appendChild(transcriptBtn);

            if (downloadBtn || transcriptBtn) {
                topRow.parentNode.insertBefore(container, topRow.nextSibling);
            }
        }

        function init() {
            if (window.location.pathname.includes("/watch")) {
                addButtonBelowTopRow();
            }
        }

        // Observe DOM changes for YouTube's dynamic content loading
        const observer = new MutationObserver(function(mutations) {
            for (let mutation of mutations) {
                if (mutation.target.id === 'top-row' ||
                    mutation.target.closest('#top-row') ||
                    mutation.target.querySelector('#top-row')) {
                    init();
                    break;
                }
            }
        });

        // Initialize observer
        if (document.readyState === 'loading') {
            document.addEventListener('DOMContentLoaded', function() {
                const targetNode = document.querySelector('ytd-watch-flexy') || document.body;
                observer.observe(targetNode, { childList: true, subtree: true });
                init();
            });
        } else {
            const targetNode = document.querySelector('ytd-watch-flexy') || document.body;
            observer.observe(targetNode, { childList: true, subtree: true });
            init();
        }

        // Handle YouTube's SPA navigation
        window.addEventListener("yt-navigate-finish", init);
    }

    // ============================================
    // Y2META-US.COM - Auto-fill YouTube URL
    // ============================================
    if (window.location.hostname.includes("y2meta-us.com")) {
        function autoFillAndSubmit() {
            // Get URL from query parameter
            const urlParams = new URLSearchParams(window.location.search);
            const youtubeUrl = urlParams.get('url');
            
            // Validate YouTube URL
            if (!youtubeUrl || !youtubeUrl.includes("youtube.com/watch")) {
                return;
            }
            
            // Find input and button elements
            const input = document.querySelector("#txt-url");
            const button = document.querySelector("#btn-submit");
            
            if (input && button) {
                // Fill the input field
                input.value = youtubeUrl;
                input.dispatchEvent(new Event("input", { bubbles: true }));
                input.dispatchEvent(new Event("change", { bubbles: true }));
                
                // Click submit button after short delay
                setTimeout(() => {
                    button.click();
                    // Clean up URL (remove query parameter)
                    history.replaceState(null, '', window.location.pathname);
                }, 500);
            } else {
                // Retry if elements not found yet
                setTimeout(autoFillAndSubmit, 300);
            }
        }
        
        // Start auto-fill process when page loads
        if (document.readyState === 'loading') {
            document.addEventListener('DOMContentLoaded', autoFillAndSubmit);
        } else {
            autoFillAndSubmit();
        }
    }
})();