Greasy Fork is available in English.

Botón de conversión de URL de YouTube Shorts

Convierte la URL de YouTube Shorts en una URL de video de YouTube normal.

Versión del día 26/2/2025. Echa un vistazo a la versión más reciente.

// ==UserScript==
// @name                YouTube Shorts URL Conversion Button
// @name:zh-TW          YouTube Shorts URL 轉換按鈕
// @name:zh-HK          YouTube Shorts URL 轉換按鈕
// @name:ja             YouTube Shorts URL コンバーター
// @name:zh-CN          YouTube Shorts URL 转换按钮
// @name:ko             YouTube Shorts URL 변환 버튼
// @name:ru             Кнопка преобразования URL YouTube Shorts
// @name:de             YouTube Shorts URL Konvertierungstaste
// @name:es             Botón de conversión de URL de YouTube Shorts
// @name:fr             Bouton de conversion d'URL YouTube Shorts
// @name:it             Pulsante di conversione URL YouTube Shorts
// @name:pt             Botão de conversão de URL do YouTube Shorts
// @name:ar             زر تحويل URL من YouTube Shorts
// @name:nl             YouTube Shorts URL Conversieknop
// @name:tr             YouTube Shorts URL Dönüştürme Butonu
// @name:pl             Przycisk konwersji URL YouTube Shorts
// @namespace           http://tampermonkey.net/
// @version             1.10
// @description         Convert YouTube Shorts URL to regular YouTube video URL.
// @description:zh-TW   將 YouTube Shorts 網址轉換為常規的 YouTube 影片網址。
// @description:zh-HK   將 YouTube Shorts 網址轉換為常規的 YouTube 影片網址。
// @description:ja      YouTube Shorts URLを通常のYouTubeビデオURLに変換します。
// @description:zh-CN   将 YouTube Shorts 网址转换为常规的 YouTube 视频网址。
// @description:ko      YouTube Shorts URL을 일반 YouTube 비디오 URL로 변환합니다.
// @description:ru      Преобразование URL YouTube Shorts в обычный URL видео YouTube.
// @description:de      Konvertiere YouTube Shorts URL in reguläre YouTube Video URL.
// @description:es      Convierte la URL de YouTube Shorts en una URL de video de YouTube normal.
// @description:fr      Convertir l'URL YouTube Shorts en URL vidéo YouTube classique.
// @description:it      Converti l'URL YouTube Shorts in URL video YouTube normale.
// @description:pt      Converte a URL do YouTube Shorts para URL normal do YouTube.
// @description:ar      تحويل رابط YouTube Shorts إلى رابط فيديو YouTube عادي.
// @description:nl      Converteer YouTube Shorts URL naar reguliere YouTube video URL.
// @description:tr      YouTube Shorts URL'sini normal YouTube video URL'sine dönüştür.
// @description:pl      Konwertuj URL YouTube Shorts na regularny URL wideo YouTube.
// @author              鮪魚大師
// @match               https://www.youtube.com/*
// @grant               none
// @license             MIT
// ==/UserScript==

(function() {
    'use strict';

    const debug = true;

    let convertButton;
    let resizeButton;
    let isButtonDown = false;
    let buttonSize = "medium"; // 預設大小 目前只有"medium"跟"small"

    const lang = document.documentElement.lang || navigator.language;
    const langData = [
        {
            name: "English",
            match: ["en", "en-US", "en-GB", "en-CA", "en-AU"],
            lang: {
                buttonText: "Convert Shorts",
                buttonTitle: "Convert Shorts URL to regular video URL",
                resizeButtonTitle: "Resize the buttons",
            },
        },
        {
            name: "Chinese (Traditional)",
            match: ["zh-TW", "zh-HK", "zh-Hant", "zh-Hant-TW"],
            lang: {
                buttonText: "Shorts轉換",
                buttonTitle: "將Shorts網址轉換成一般影片網址",
                resizeButtonTitle: "調整按鈕大小",
            },
        },
        {
            name: "Japanese",
            match: ["ja"],
            lang: {
                buttonText: "Shorts変換",
                buttonTitle: "YouTube Shorts URLを通常のYouTubeビデオURLに変換します",
                resizeButtonTitle: "ボタンサイズを変更する",
            },
        },
        {
            name: "Chinese (Simplified)",
            match: ["zh-CN", "zh-SG", "zh-Hans", "zh-Hans_CN"],
            lang: {
                buttonText: "Shorts转换",
                buttonTitle: "将 YouTube Shorts 网址转换为常规的 YouTube 视频网址",
                resizeButtonTitle: "调整按钮大小",
            },
        },
        {
            name: "Korean",
            match: ["ko"],
            lang: {
                buttonText: "Shorts변환",
                buttonTitle: "YouTube Shorts URL을 일반 YouTube 비디오 URL로 변환합니다",
                resizeButtonTitle: "버튼 크기 조정",
            },
        },
        {
            name: "Russian",
            match: ["ru"],
            lang: {
                buttonText: "Shorts конвертация",
                buttonTitle: "Преобразование URL YouTube Shorts в обычный URL видео YouTube",
                resizeButtonTitle: "Изменить размер кнопок",
            },
        },
        {
            name: "German",
            match: ["de"],
            lang: {
                buttonText: "Shorts konvertieren",
                buttonTitle: "Konvertiere YouTube Shorts URL in reguläre YouTube Video URL",
                resizeButtonTitle: "Größe der Schaltflächen ändern",
            },
        },
        {
            name: "Spanish",
            match: ["es", "es-ES", "es-MX", "es-AR", "es-CO"],
            lang: {
                buttonText: "Convertir Shorts",
                buttonTitle: "Convierte la URL de YouTube Shorts en una URL de video de YouTube normal",
                resizeButtonTitle: "Cambiar el tamaño de los botones",
            },
        },
        {
            name: "French",
            match: ["fr", "fr-FR", "fr-CA", "fr-BE", "fr-CH"],
            lang: {
                buttonText: "Convertir Shorts",
                buttonTitle: "Convertir l'URL YouTube Shorts en URL vidéo YouTube classique",
                resizeButtonTitle: "Redimensionner les boutons",
            },
        },
        {
            name: "Italian",
            match: ["it"],
            lang: {
                buttonText: "Converti Shorts",
                buttonTitle: "Converti l'URL YouTube Shorts in URL video YouTube normale",
                resizeButtonTitle: "Ridimensiona i pulsanti",
            },
        },
        {
            name: "Portuguese",
            match: ["pt", "pt-PT", "pt-BR"],
            lang: {
                buttonText: "Converter Shorts",
                buttonTitle: "Converter a URL do YouTube Shorts para a URL normal do vídeo do YouTube",
                resizeButtonTitle: "Alterar o tamanho dos botões",
            },
        },
        {
            name: "Arabic",
            match: ["ar"],
            lang: {
                buttonText: "تحويل Shorts",
                buttonTitle: "تحويل رابط YouTube Shorts إلى رابط فيديو YouTube عادي",
                resizeButtonTitle: "تغيير حجم الأزرار",
            },
        },
        {
            name: "Dutch",
            match: ["nl", "nl-NL", "nl-BE"],
            lang: {
                buttonText: "Shorts converteren",
                buttonTitle: "Converteer YouTube Shorts URL naar reguliere YouTube video URL",
                resizeButtonTitle: "Verander de grootte van de knoppen",
            },
        },
        {
            name: "Turkish",
            match: ["tr"],
            lang: {
                buttonText: "Shorts dönüştür",
                buttonTitle: "YouTube Shorts URL'sini normal YouTube video URL'sine dönüştür",
                resizeButtonTitle: "Düğme boyutunu değiştir",
            },
        },
        {
            name: "Polish",
            match: ["pl"],
            lang: {
                buttonText: "Konwertuj Shorts",
                buttonTitle: "Konwertuj URL YouTube Shorts na regularny URL wideo YouTube",
                resizeButtonTitle: "Zmień rozmiar przycisków",
            },
        },
        {
            name: "Hebrew",
            match: ["he"],
            lang: {
                buttonText: "המיר Shorts",
                buttonTitle: "המיר את כתובת ה-URL של YouTube Shorts לכתובת URL רגילה של סרטון YouTube",
                resizeButtonTitle: "שנה את גודל הכפתורים",
            },
        },
        {
            name: "Vietnamese",
            match: ["vi"],
            lang: {
                buttonText: "Chuyển đổi Shorts",
                buttonTitle: "Chuyển đổi URL YouTube Shorts thành URL video YouTube thông thường",
                resizeButtonTitle: "Thay đổi kích thước các nút",
            },
        },
    ];

    function debugLog(message) {
        if (debug) {
            console.log("[DEBUG] " + message);
        }
    }

    function getLanguageData() {
        console.log("偵測到的語言:", lang);
        for (const data of langData) {
            if (data.match.includes(lang)) {
                console.log(`匹配到語言: ${data.name}`);
                return data.lang;
            }
        }

        console.log(`找不到匹配的語言,使用預設語言: ${langData[0].name}`); // 印出預設語言
        return langData[0].lang;
    }

    const languageData = getLanguageData();

    // 根據 'buttonSize' 變數更新按鈕大小
    function updateButtonSize() {
        if (convertButton) {
            convertButton.style.fontSize = buttonSize === "small" ? "14px" : "24px";
            convertButton.style.padding = buttonSize === "small" ? "5px 10px" : "10px 20px";
        }
    }

    // 建立 Convert Button 和 Resize Button
    function createButtons() {
        // Convert 按鈕
        if (!convertButton) {
            debugLog("正在創建 Convert 按鈕...");
            convertButton = document.createElement('button');
            convertButton.textContent = languageData.buttonText;
            convertButton.style.position = 'fixed';
            convertButton.style.top = '150px';
            convertButton.style.right = '10px';
            convertButton.style.zIndex = '9999';
            convertButton.style.backgroundColor = '#FF0000';
            convertButton.style.color = '#FFFFFF';
            convertButton.style.fontSize = '24px';
            convertButton.style.padding = '10px 20px';
            convertButton.style.border = 'none';
            convertButton.style.borderRadius = '5px';
            convertButton.title = languageData.buttonTitle;
            document.body.appendChild(convertButton);
            updateButtonSize();

            convertButton.addEventListener('click', convertURL);
            convertButton.addEventListener('auxclick', convertURL);

            convertButton.addEventListener('mousedown', function() {
                convertButton.style.backgroundColor = '#D80000';
                isButtonDown = true;
            });

            convertButton.addEventListener('mouseup', function() {
                convertButton.style.backgroundColor = '#FF0000';
                isButtonDown = false;
            });

            convertButton.addEventListener('mouseout', function() {
                if (!isButtonDown) {
                    convertButton.style.backgroundColor = '#FF0000';
                }
            });

            convertButton.addEventListener('mouseenter', function() {
                convertButton.style.backgroundColor = '#FF3333';
            });

            convertButton.addEventListener('mouseleave', function() {
                convertButton.style.backgroundColor = '#FF0000';
            });

            debugLog("按鈕創建成功");
        }

        // Resize 按鈕
        if (!resizeButton) {
            debugLog("正在創建 Resize 按鈕...");
            resizeButton = document.createElement('button');
            resizeButton.textContent = "◱";
            resizeButton.style.position = 'fixed';
            resizeButton.style.right = '10px';
            resizeButton.style.top = (convertButton.getBoundingClientRect().bottom + 5) + 'px';
            resizeButton.style.zIndex = '9999';
            resizeButton.style.backgroundColor = '#008CBA';
            resizeButton.style.color = '#FFFFFF';
            resizeButton.style.fontSize = '18px';
            resizeButton.style.width = '25px';
            resizeButton.style.height = '25px';
            resizeButton.style.display = 'flex';
            resizeButton.style.justifyContent = 'center';
            resizeButton.style.alignItems = 'center';
            resizeButton.style.border = 'none';
            resizeButton.style.borderRadius = '5px';
            resizeButton.title = languageData.resizeButtonTitle;
            document.body.appendChild(resizeButton);

            resizeButton.addEventListener('click', () => {
                buttonSize = buttonSize === "small" ? "medium" : "small";
                updateButtonSize();
                resizeButton.style.top = (convertButton.getBoundingClientRect().bottom + 5) + 'px';
            });

            resizeButton.addEventListener('mouseenter', function() {
                resizeButton.style.backgroundColor = '#00bcd4';
            });

            resizeButton.addEventListener('mouseleave', function() {
                resizeButton.style.backgroundColor = '#008CBA';
            });
        }
    }

    //主要功能
    function convertURL(event) {
        const currentURL = window.location.href;
        debugLog("當前網址: " + currentURL);

        if (currentURL.includes("youtube.com/shorts/")) {
            const match = currentURL.match(/https:\/\/www\.youtube\.com\/shorts\/([A-Za-z0-9_-]+)/);
            if (match) {
                const videoID = match[1];
                const videoURL = `https://www.youtube.com/watch?v=${videoID}`;
                debugLog(`匹配到的影片ID: ${videoID}`);
                debugLog(`轉換後的網址: ${videoURL}`);

                if (event && event.button === 2) {
                    debugLog("檢測到右鍵點擊(未執行任何操作)");
                } else if (event && event.button === 1) {
                    debugLog("檢測到中鍵點擊(開啟新標籤)");
                    window.open(videoURL, '_blank');
                } else {
                    debugLog("正在導航至轉換後的網址");
                    window.location.href = videoURL;
                }
            } else {
                debugLog("網址中沒有匹配到影片ID");
            }
        } else {
            debugLog("不是 YouTube Shorts 網址");
        }
    }

    function removeConvertButton() {
        if (convertButton) {
            debugLog("正在移除 Convert 按鈕...");
            convertButton.remove();
            convertButton = null;
            debugLog("Convert 按鈕已移除");
        }

        if (resizeButton) {
            debugLog("正在移除 Resize 按鈕...");
            resizeButton.remove();
            resizeButton = null;
            debugLog("Resize 按鈕已移除");
        }
    }

    function debounce(func, wait) {
        let timeout;
        return function executedFunction(...args) {
            const later = () => {
                timeout = null;
                func(...args);
            };
            clearTimeout(timeout);
            timeout = setTimeout(later, wait);
        };
    }

    const checkAndCreateButton = debounce(function() {
        debugLog("檢查是否應該創建按鈕...");
        if (window.location.href.includes("youtube.com/shorts/")) {
            createButtons();
        } else {
            removeConvertButton();
        }
    }, 200); // 防抖200ms

    window.addEventListener('popstate', checkAndCreateButton);

    const observer = new MutationObserver(function(mutationsList) {
        for (const mutation of mutationsList) {
            if (mutation.type === 'childList') {
                checkAndCreateButton();
                break;
            }
        }
    });

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

})();