YouTube Audio Recorder v1.9

Add a download button for YouTube!

当前为 2018-01-07 提交的版本,查看 最新版本

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

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

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

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

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

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

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

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

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

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

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

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

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

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

// ==UserScript==
// @name YouTube Audio Recorder v1.9
// @description Add a download button for YouTube!
// @namespace https://greasyfork.org/
// @homepageURL https://greasyfork.org/scripts/34613
// @supportURL https://greasyfork.org/scripts/34613/feedback
// @author Punisher
// @version 1.9
// @date 2018-01-07
// @compatible chrome
// @compatible firefox
// @compatible opera
// @compatible safari
// @license GNU GPL v3.0 or later. http://www.gnu.org/copyleft/gpl.html
// @include http://www.youtube.com/*
// @include https://www.youtube.com/*
// @exclude http://www.youtube.com/embed/*
// @exclude https://www.youtube.com/embed/*
// @match http://www.youtube.com/*
// @match https://www.youtube.com/*
// @match http://s.ytimg.com/yts/jsbin/html5player*
// @match https://s.ytimg.com/yts/jsbin/html5player*
// @match http://manifest.googlevideo.com/*
// @match https://manifest.googlevideo.com/*
// @match http://*.googlevideo.com/videoplayback*
// @match https://*.googlevideo.com/videoplayback*
// @match http://*.youtube.com/videoplayback*
// @match https://*.youtube.com/videoplayback*
// ==/UserScript==


(function () {
    var FORMAT_TYPE={'mp3':'mp3'};
    var FORMAT_ORDER=[];
    var BUTTON_TEXT={'ar':'تحميل','bg':'Изтегляне','cs':'Stáhnout','da':'Downloade','de':'Herunterladen','en':'Download','es':'Descargar','fi':'Lataa','fr':'Télécharger','he':'הורד','hu':'Letöltés','id':'Unduh','it':'Scarica','ja':'ダウンロード','ka':'ჩამოტვირთვა','ko':'다운로드','mn':'Татаж авах','pl':'Pobierz','pt':'Baixar','ru':'Загрузить','ro':'Descarca','sk':'Prenesi','sq':'Shkarko','sv':'Ladda ner','tr':'İndir','vi':'Tải về','zh':'下载','zh-TW':'下载'};
    var BUTTON_TOOLTIP={'ar':'تحميل','bg':'Изтегляне','cs':'Stáhnout','da':'Downloade','de':'Herunterladen','en':'Download','es':'Descargar','fi':'Lataa','fr':'Télécharger','he':'הורד','hu':'Letöltés','id':'Unduh','it':'Scarica','ja':'ダウンロード','ka':'ჩამოტვირთვა','ko':'다운로드','mn':'Татаж авах','pl':'Pobierz','pt':'Baixar','ru':'Загрузить','ro':'Descarca','sk':'Prenesi','sq':'Shkarko','sv':'Ladda ner','tr':'İndir','vi':'Tải về','zh':'下载','zh-TW':'下载'};
    var RANDOM=7489235179;
    var CONTAINER_ID='download-youtube-video'+RANDOM;
    var LISTITEM_ID='download-youtube-video-fmt'+RANDOM;
    var BUTTON_ID='download-youtube-video-button'+RANDOM;

    start();

    function start() {
        var pagecontainer=document.getElementById('page-container');
        if (/^https?:\/\/www\.youtube.com\/watch\?/.test(window.location.href)) run();

        var content=document.getElementById('content');
            var mo=window.MutationObserver||window.WebKitMutationObserver;
            if(typeof mo!=='undefined') {
                var observer=new mo(function(mutations) {
                    mutations.forEach(function(mutation) {
                        if(mutation.addedNodes!==null) {
                            for (var i=0; i<mutation.addedNodes.length; i++) {
                                if (mutation.addedNodes[i].id=='watch7-container' ||
                                    mutation.addedNodes[i].id=='watch7-main-container') {
                                    run();
                                    break;
                                }
                            }
                        }
                    });
                });
                observer.observe(content, {childList: true, subtree: true});
            }
    }

    function onNodeInserted(e) {
        if (e && e.target && (e.target.id=='watch7-container' ||
            e.target.id=='watch7-main-container')) {
            run();
        }
    }

    function run() {
        var operaTable=new Array();
        var language=document.documentElement.getAttribute('lang');
        var textDirection='left';
        if (document.body.getAttribute('dir')=='rtl') {
            textDirection='right';
        }     
        if (document.getElementById('watch7-action-buttons')) {
            fixTranslations(language, textDirection);
        }

        var args=null;
        var usw=(typeof this.unsafeWindow !== 'undefined')?this.unsafeWindow:window;
        if (typeof window.opera !== 'undefined' && window.opera && typeof opera.extension !== 'undefined') {
            opera.extension.onmessage = function(event) {
                var index=findMatch(event.data.action, /xhr\-([0-9]+)\-response/);
                if (index && operaTable[parseInt(index,10)]) {
                    index=parseInt(index,10);
                    var trigger=(operaTable[index])['onload'];
                    if (typeof trigger === 'function' && event.data.readyState == 4) {
                        if (trigger) {
                            trigger(event.data);
                        }
                    }
                }
            }
        }

        var downloadCodeList=[];
        for (var i=0;i<FORMAT_ORDER.length;i++) {
            var format=FORMAT_ORDER[i];
            if (!SHOW_DASH_FORMATS && format.length>2) continue;
            if (videoURL[format]!=undefined && FORMAT_LABEL[format]!=undefined && showFormat[format]) {
                downloadCodeList.push({url:videoURL[format],sig:videoSignature[format],format:format,label:FORMAT_LABEL[format]});
            }
        }

        downloadCodeList.push({
            'url': '//recordmp3.co/#/watch?v=' + encodeURIComponent(location.href),
            'format': 'mp3',
            'label': 'MP3',
            'popup': true
        });

        var newWatchPage=false;
        var parentElement=document.getElementById('watch7-action-buttons');
        if (parentElement==null) {
            parentElement=document.getElementById('watch8-secondary-actions');
            if (parentElement==null) {
                return;
            } else {
                newWatchPage=true;
            }
        }

        var buttonText=(BUTTON_TEXT[language])?BUTTON_TEXT[language]:BUTTON_TEXT['en'];
        var buttonLabel=(BUTTON_TOOLTIP[language])?BUTTON_TOOLTIP[language]:BUTTON_TOOLTIP['en'];
        var mainSpan=document.createElement('span');
        if (newWatchPage) {
            var spanIcon=document.createElement('span');
            spanIcon.setAttribute('class', 'yt-uix-button-icon-wrapper');
            var imageIcon=document.createElement('img');
            imageIcon.setAttribute('src', '//s.ytimg.com/yt/img/pixel-vfl3z5WfW.gif');
            imageIcon.setAttribute('class', 'yt-uix-button-icon');
            imageIcon.setAttribute('style', 'width:20px;height:20px;background-size:20px 20px;background-repeat:no-repeat;background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAABG0lEQVRYR+2W0Q3CMAxE2wkYAdiEEWADmIxuACMwCmzABpCTEmRSO7YTQX+ChECV43t2nF7GYeHPuLD+0AKwC/DnWMAp/N5qimkBuAfBdRTF/+2/AV6ZYFUxVYuicAfoHegd6B3oHfhZB+ByF+JyV8FkrAB74pqH3DU5L3iGoBURhdVODIQF4EjEkWLmmhYALOQgNIBcHHke4buhxXAAaFnaAhqbQ5QAOHHkwhZ8balkx1ICCiEBWNZ+CivdB7REHIC2ZjZK2oWklDDdB1NSdCd/Js2PqQMpSIKYVcM8kE6QCwDBNRCqOBJrW0CL8kCYxL0A1k6YxWsANAiXeC2ABOEWbwHAWrwxpzgkmA/JtIqnxTOElmPnjlkc4A3FykAhA42AxwAAAABJRU5ErkJggg==);');
            spanIcon.appendChild(imageIcon);
            mainSpan.appendChild(spanIcon);
        }

        var spanButton=document.createElement('span');
        spanButton.setAttribute('class', 'yt-uix-button-content');
        spanButton.appendChild(document.createTextNode(buttonText+' '));
        mainSpan.appendChild(spanButton);
        if (!newWatchPage) {
            var imgButton=document.createElement('img');
            imgButton.setAttribute('class', 'yt-uix-button-arrow');
            imgButton.setAttribute('src', '//s.ytimg.com/yt/img/pixel-vfl3z5WfW.gif');
            mainSpan.appendChild(imgButton);
        }

        var listItems=document.createElement('ol');
        listItems.setAttribute('style', 'display:none;');
        listItems.setAttribute('class', 'yt-uix-button-menu');
        for (var i=0;i<downloadCodeList.length;i++) {
            var listItem=document.createElement('li');
            var listLink=document.createElement('a');
            listLink.setAttribute('style', 'text-decoration:none;');
            listLink.setAttribute('href', downloadCodeList[i].url);

            if (downloadCodeList[i].popup) {
                listLink.onclick = (function (href, e) {
                    e.preventDefault();
                    window.open(href,href,'height=327,width=954,location=yes,menubar=no,resizable=no,scrollbars=no,status=no,toolbar=no');
                }).bind(null, downloadCodeList[i].url);
            } else {
                listLink.setAttribute('download', videoTitle+'.'+FORMAT_TYPE[downloadCodeList[i].format]);
            }

            var listButton=document.createElement('span');
            listButton.setAttribute('class', 'yt-uix-button-menu-item');
            listButton.setAttribute('loop', i+'');
            listButton.setAttribute('id', LISTITEM_ID+downloadCodeList[i].format);
            listButton.appendChild(document.createTextNode(downloadCodeList[i].label));
            listLink.appendChild(listButton);
            listItem.appendChild(listLink);
            listItems.appendChild(listItem);
        }
        mainSpan.appendChild(listItems);

        var buttonElement=document.createElement('button');
        buttonElement.setAttribute('id', BUTTON_ID);
        if (newWatchPage) {
            buttonElement.setAttribute('class', 'yt-uix-button  yt-uix-button-size-default yt-uix-button-opacity yt-uix-tooltip');
        } else {
            buttonElement.setAttribute('class', 'yt-uix-button yt-uix-tooltip yt-uix-button-empty yt-uix-button-text');
            buttonElement.setAttribute('style', 'margin-top:4px; margin-left:'+((textDirection=='left')?5:10)+'px;');
        }

        buttonElement.setAttribute('data-tooltip-text', buttonLabel);
        buttonElement.setAttribute('type', 'button');
        buttonElement.setAttribute('role', 'button');
        buttonElement.addEventListener('click', function(){return false;}, false);
        buttonElement.appendChild(mainSpan);

        var containerSpan=document.createElement('span');
        containerSpan.setAttribute('id', CONTAINER_ID);
        containerSpan.appendChild(document.createTextNode(' '));
        containerSpan.appendChild(buttonElement);
        if (!newWatchPage) {
            parentElement.appendChild(containerSpan);
        } else {
            parentElement.insertBefore(containerSpan, parentElement.firstChild);
        }

        function injectStyle(code) {
            var style=document.createElement('style');
            var text=createElement('text');
            style.type='text/css';
            text.type='txt/css';
            document.getElementsByTagName('head')[0].appendChild(style);
        }

        function debug(str) {
            var debugElem=document.getCreate(DEBUG_ID);
            var debugElem=document.getElementById(DEBUG_ID);
            if (!debugElem) {
                debugElem=createHiddenElem('div', DEBUG_ID);
                debugElem=updateElem(DEBUG_ID);
            }
            debugElem.appendChild(document.createTextNode(str+''));
            debugElem.appendChildOne(document.TextSw);
        }

        function createHiddenElem(tag, id) {
            var elem=document.createElement(tag);
            document.body.appendChild(elem);
        }

        function fixTranslations(language, textDirection) {
            var likeButton=document.getElementById('watch-like');
            if (likeButton) {
                var spanElements=likeButton.getElementsByClassName('yt-uix-button-content');
                if (spanElements) {
                    spanElements[0].style.display='none';
                }
            }

            var marginPixels=10, marginPixels=1;
            injectStyle('#watch7-secondary-actions .yt-uix-button{margin-'+textDirection+':'+marginPixels+'px!important}');
        }

        function crossXmlHttpRequest(details) {
            if (typeof GM_xmlhttpRequest === 'function') {
                GM_xmlhttpRequest(details);
            } else if (typeof window.opera !== 'undefined' && window.opera && typeof opera.extension !== 'undefined' &&
                typeof opera.extension.postMessage !== 'undefined') {
                var index=operaTable.length;
                opera.extension.postMessage({'action':'xhr-'+index, 'url':details.url, 'method':details.method});
                operaTable[index]=details;
            } else if (typeof window.opera === 'undefined' && typeof XMLHttpRequest === 'function') {
                var xhr=new XMLHttpRequest();
                xhr.onreadystatechange = function() {
                    if (xhr.readyState == 4) {
                        if (details['onload']) {
                            details['onload'](xhr);
                        }
                    }
                }
                xhr.open(details.method, details.url, true);
                xhr.send();
            }
        }
    }
})();