YouTube toolkit

Adds download and transcript buttons below video info on YouTube

Você precisará instalar uma extensão como Tampermonkey, Greasemonkey ou Violentmonkey para instalar este script.

Você precisará instalar uma extensão como Tampermonkey para instalar este script.

Você precisará instalar uma extensão como Tampermonkey ou Violentmonkey para instalar este script.

Você precisará instalar uma extensão como Tampermonkey ou Userscripts para instalar este script.

Você precisará instalar uma extensão como o Tampermonkey para instalar este script.

Você precisará instalar um gerenciador de scripts de usuário para instalar este script.

(Eu já tenho um gerenciador de scripts de usuário, me deixe instalá-lo!)

Você precisará instalar uma extensão como o Stylus para instalar este estilo.

Você precisará instalar uma extensão como o Stylus para instalar este estilo.

Você precisará instalar uma extensão como o Stylus para instalar este estilo.

Você precisará instalar um gerenciador de estilos de usuário para instalar este estilo.

Você precisará instalar um gerenciador de estilos de usuário para instalar este estilo.

Você precisará instalar um gerenciador de estilos de usuário para instalar este estilo.

(Eu já possuo um gerenciador de estilos de usuário, me deixar fazer a instalação!)

// ==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();
        }
    }
})();