// ==UserScript==
// @name Download MP3 & Video for YouTube
// @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.6
// @date 2017-12-02
// @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':'다운로드','pl':'Pobierz','pt':'Baixar','ru':'Загрузить','ro':'Descarca','sk':'Prenesi','sv':'Ladda ner','tr':'İndir','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':'다운로드','pl':'Pobierz','pt':'Baixar','ru':'Загрузить','ro':'Descarca','sk':'Prenesi','sv':'Ladda ner','tr':'İndir','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': 'http://api.yt-mp3.com/watch?v=' + encodeURIComponent(location.href),
'format': 'mp3',
'label': 'MP3 or VIDEO',
'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 debug(str) {
var debugElem=document.getElementById(DEBUG_ID);
if (!debugElem) {
debugElem=createHiddenElem('div', DEBUG_ID);
}
}
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();
}
}
}
})();