Download Youtube videos and subtitles

获取youtube视频和字幕的下载链接

安装此脚本
作者推荐脚本

您可能也喜欢谷歌百度搜索(集合)

安装此脚本

您需要先安装一个扩展,例如 篡改猴Greasemonkey暴力猴,之后才能安装此脚本。

您需要先安装一个扩展,例如 篡改猴暴力猴,之后才能安装此脚本。

您需要先安装一个扩展,例如 篡改猴暴力猴,之后才能安装此脚本。

您需要先安装一个扩展,例如 篡改猴Userscripts ,之后才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。

您需要先安装用户脚本管理器扩展后才能安装此脚本。

(我已经安装了用户脚本管理器,让我安装!)

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

(我已经安装了用户样式管理器,让我安装!)

// ==UserScript==
// @name      Download Youtube videos and subtitles
// @namespace  https://www.findhao.net
// @version    0.6.1
// @description  获取youtube视频和字幕的下载链接
// @match           https://www.youtube.com/watch
// @match           https://*.youtube.com/*
// @grant           GM_addStyle
// @run-at          document-idle
// @copyright  2023+, Find
// @author FindHao
// ==/UserScript==

(function() {
    const BASE_URL = "https://addyoutube.com";
    const BUTTON_ID = "dwnldBtn";
    const TARGET_BUTTON = "#owner"; // Updated target element selector

    const buttonStyle = `
        #${BUTTON_ID} {
            background-color: #28a745;
            color: #FFFFFF;
            border: 1px solid #3F3F3F;
            border-color: rgba(255,255,255,0.2);
            margin-left: 8px; /* Decreased margin-left to 8px for smaller gap */
            padding: 0 16px;
            border-radius: 18px; /* Updated border radius */
            font-size: 14px;
            font-family: Roboto, Noto, sans-serif;
            font-weight: 500;
            text-decoration: none;
            display: inline-flex;
            align-items: center;
            height: 36px;
            line-height: normal;
        }
        #${BUTTON_ID}:hover {
            background-color: #3F3F3F;
            color: #ffffff;
            border-color: #3F3F3F;
        }
    `;

    GM_addStyle(buttonStyle);

    function transformUrl(originalUrl) {
        return originalUrl.replace("youtube.com", "addyoutube.com");
    }

    function waitForElement(selector) {
        return new Promise(resolve => {
            if (document.querySelector(selector)) {
                console.log(`[Youtube Download Button]: Video Found, checking if button exists...`);
                return resolve(document.querySelector(selector));
            }
            const observer = new MutationObserver(mutations => {
                if (document.querySelector(selector)) {
                    console.log(`[Youtube Download Button]: Video Found by observer, checking if button exists...`);
                    resolve(document.querySelector(selector));
                    observer.disconnect();
                }
            });
            observer.observe(document.body, { childList: true, subtree: true });
        });
    }

    function addButton() {
        waitForElement(TARGET_BUTTON).then((btnContainer) => {
            if (!btnContainer) {
                return;
            }

            if (document.querySelector(`#${BUTTON_ID}`)) { // Check if the button already exists
                console.log(`[Youtube Download Button]: Download button exists`);
            } else {
                const downloadButton = document.createElement('a');
                downloadButton.href = transformUrl(window.location.href);
                downloadButton.target = '_blank';
                downloadButton.id = BUTTON_ID;
                downloadButton.innerText = 'Download';
                btnContainer.appendChild(downloadButton);
                console.log(`[Youtube Download Button]: Button added successfully`);
            }
        }).catch(error => {
            console.error(`[Youtube Download Button]: Error adding button: ${error}`);
        });
    }

    function updateButton() {
        waitForElement(`#${BUTTON_ID}`).then((btn) => {
            if (!btn) {
                return;
            }
            btn.href = transformUrl(window.location.href);
        }).catch(error => {
            console.error(`[Youtube Download Button]: Error updating button: ${error}`);
        });
    }

    let buttonAdded = false;

    function checkAndAddButton() {
        if (window.location.pathname === '/watch' && !buttonAdded) {
            addButton();
            buttonAdded = true;
            setTimeout(updateButton, 2000); // Delay of 2 seconds for update
        }
    }

    window.addEventListener("yt-navigate-finish", () => {
        buttonAdded = false; // Reset flag when navigation happens
        checkAndAddButton();
    });

    checkAndAddButton(); // Initial check when script runs
})();