// ==UserScript==
// @name Youtube downloader for NoScript
// @include http://*.youtube.com/watch*
// @include http://youtube.com/watch*
// @include https://*.youtube.com/watch*
// @include https://youtube.com/watch*
// @run-at document-end
// @description This script is no longer maintained, please use https://greasyfork.org/en/scripts/1317-download-youtube-videos-as-mp4
// @version 0.0.1.20170330045620
// @namespace https://greasyfork.org/users/10916
// ==/UserScript==
var nasp, spec, fmtvar, titlevar, newa2 = "", scrhead = document.getElementsByTagName("script");
var formats = {
5: { itag: 5, quality: 5, description: "Low Quality, 240p", format: "FLV", fres: "240p", mres: { width: 400, height: 240 }, acodec: "MP3", vcodec: "SVQ"},
17: { itag: 17, quality: 4, description: "Low Quality, 144p", format: "3GP", fres: "144p", mres: { width: 0, height: 0 }, acodec: "AAC", vcodec: ""},
18: { itag: 18, quality: 15, description: "Low Definition, 360p", format: "MP4", fres: "360p", mres: { width: 480, height: 360 }, acodec: "AAC", vcodec: "H.264"},
22: { itag: 22, quality: 35, description: "High Definition, 720p", format: "MP4", fres: "720p", mres: { width: 1280, height: 720 }, acodec: "AAC", vcodec: "H.264"},
34: { itag: 34, quality: 10, description: "Low Definition, 360p", format: "FLV", fres: "360p", mres: { width: 640, height: 360 }, acodec: "AAC", vcodec: "H.264"},
35: { itag: 35, quality: 25, description: "Standard Definition, 480p", format: "FLV" , fres: "480p", mres: { width: 854, height: 480 }, acodec: "AAC", vcodec: "H.264"},
36: { itag: 36, quality: 6, description: "Low Quality, 240p", format: "3GP", fres: "240p", mres: { width: 0, height: 0 }, acodec: "AAC", vcodec: ""},
37: { itag: 37, quality: 45, description: "Full High Definition, 1080p", format: "MP4", fres: "1080p", mres: {width: 1920, height: 1080}, acodec: "AAC", vcodec: "H.264"},
38: { itag: 38, quality: 55, description: "Original Definition", format: "MP4" , fres: "Orig", mres: { width: 4096, height: 3072 }, acodec: "AAC", vcodec: "H.264"},
43: { itag: 43, quality: 20, description: "Low Definition, 360p", format: "WebM", fres: "360p", mres: { width: 640, height: 360 }, acodec: "Vorbis", vcodec: "VP8"},
44: { itag: 44, quality: 30, description: "Standard Definition, 480p", format: "WebM", fres: "480p", mres: { width: 854, height: 480 }, acodec: "Vorbis", vcodec: "VP8"},
45: { itag: 45, quality: 40, description: "High Definition, 720p", format: "WebM", fres: "720p", mres: { width: 1280, height: 720 }, acodec: "Vorbis", vcodec: "VP8"},
46: { itag: 46, quality: 50, description: "Full High Definition, 1080p", format: "WebM", fres: "1080p", mres: {width: 1280, height: 720}, acodec: "Vorbis", vcodec: "VP8"},
82: { itag: 82, quality: 16, description: "Low Definition 3D, 360p", format: "MP4", fres: "360p", mres: { width: 640, height: 360 }, acodec: "AAC", vcodec: "H.264"},
84: { itag: 84, quality: 41, description: "High Definition 3D, 720p", format: "MP4", fres: "720p", mres: { width: 1280, height: 720 }, acodec: "AAC", vcodec: "H.264"},
100: { itag: 100, quality: 17, description: "Low Definition 3D, 360p", format: "WebM", fres: "360p", mres: { width: 640, height: 360 }, acodec: "Vorbis", vcodec: "VP8"},
102: { itag: 102, quality: 42, description: "High Definition 3D, 720p", format: "WebM", fres: "720p", mres: {width: 1280, height: 720}, acodec: "Vorbis", vcodec: "VP8"},
133: { itag: 133, description: "", format: "MP4", fres: "240p", acodec: "noaudio", vcodec: "H.264"},
134: { itag: 134, description: "", format: "MP4", fres: "360p", acodec: "noaudio", vcodec: "H.264"},
135: { itag: 135, description: "MP4 480p - no audio", format: "MP4", fres: "480p", acodec: "noaudio", vcodec: "H.264"},
136: { itag: 136, description: "MP4 720p", format: "MP4", fres: "720p", acodec: "noaudio", vcodec: "H.264"},
137: { itag: 137, description: "MP4 1080p - no audio", format: "MP4", fres: "1080p", acodec: "noaudio", vcodec: "H.264"},
138: { itag: 138, description: "MP4 2160p - no audio", format: "MP4", fres: "2160p", acodec: "noaudio", vcodec: "H.264"},
140: { itag: 140, description: "M4A 128kbps - audio", format: "m4a", fres: "128k", acodec: "AAC", vcodec: "novideo"},
141: { itag: 141, description: "M4A 256kbps - audio", format: "m4a", fres: "256k", acodec: "AAC", vcodec: "novideo"},
160: { itag: 160, description: "", format: "MP4", acodec: "noaudio", fres: "144p", vcodec: "H.264/15fps"},
264: { itag: 264, description: "MP4 1440p - no audio", format: "MP4", fres: "1440p", acodec: "noaudio", vcodec: ""},
298: { itag: 298, description: "MP4 720p 60fps - no audio", format: "MP4", fres: "720p", acodec: "noaudio", vcodec: "H.264/60fps"},
299: { itag: 299, description: "MP4 1080p 60fps - no audio", format: "MP4", fres: "1080p", acodec: "noaudio", vcodec: "H.264/60fps"}
}
var wclh = (window.content||window).location.href.toString();
var html = "";
if (document.getElementById("eow-title")) {
titlevar = parseTV(document.getElementById("eow-title").textContent.toString());
} else if (document.getElementById("watch-headline-title")&&document.getElementById("watch-headline-title").childNodes[1].innerHTML.toString()) {
titlevar = parseTV(document.getElementById("watch-headline-title").childNodes[1].textContent.toString());
} else {
titlevar = "Download_Video_Link";
}
function addBox(strR) {
var q = strR.split("itag=")[1].split("&")[0];
var fmt = formats[q];
if (fmt) {
html = html + "<option value='"+strR+"&title="+titlevar+"'>" + fmt.format + " " + fmt.fres + " " +fmt.acodec + " " + fmt.vcodec + "</option>";
}
}
function parseTV(h) {
h = unescape(h);
h = h.replace(/\W/g,"_").replace(/\_+/g,"_").replace("_amp_", "_and_");
while (!h.charAt(0).match(/[a-zA-Z0-9]/i)&&h.length>1) {h = h.substr(1);}
while (h.length>1&&!h.charAt(h.length-1).match(/[a-zA-Z0-9]/i)) {h = h.substring(0,h.length-1);}
return(h);
}
function getSType(spec) {
return formats[spec].quality;
}
function procURLS(nasp) {
nasp = cleanArray(nasp);
for (x=0;x<nasp.length;x++) {
var newalink = unescape(nasp[x]);
if (newalink.indexOf("http")==-1) { nasp.splice(x,1); }
}
for (x=0;x<nasp.length;x++) {
var nchkend = "", nlink = "", nchk = "", ny = "", narray = new Array();
nasp[x] = unescape(unescape(nasp[x]));
narray = nasp[x].split("&");
narray = cleanArray(narray);
for (y=0;y<narray.length;y++) {
ny = narray[y];
if (ny!=null&&ny!=""&&ny.match(/url\=/i)!=-1&&ny.indexOf("?")!=-1) {
nlink = unescape(ny.split("url=")[1]);
narray.splice(y,1);
break;
}
ny = "";
}
for (var nx=0; nx<narray.length; nx++) {
if (narray[nx].split("=")) {
nchk = narray[nx].split("=")[0];
var specific = "";
nchkend = narray[nx].indexOf("=");
nchkend = narray[nx].substr(nchkend+1);
//if (acceptargs.indexOf(nchk)!=-1 && nlink.indexOf("&"+nchk+"=")==-1 && nlink.indexOf("?"+nchk+"=")==-1) { //for compatibility, no longer checking against accepted arguments
if (nlink.indexOf("&"+nchk+"=")==-1 && nlink.indexOf("?"+nchk+"=")==-1) {
if (nchk.match(/fallback_host$/i)) {
var nrxp = new RegExp("^(http|https)\:\/\/.{0,}\.(com|net)","i");
if (nlink.indexOf("videoplayback")==-1&&nlink.match(nrxp)) {
}
}
else if (nchk.match(/signature$/i)) {
nlink+="&signature=" + nchkend;
}
else if (nchk.match(/sig$/i)&&nlink.indexOf("?signature=")==-1&&nlink.indexOf("&signature=")==-1) {
nlink+="&signature=" + nchkend;
}
else if (nchk.length==1&&nchk.match(/s$/i)&&nlink.indexOf("?signature=")&&nlink.indexOf("&signature=")==-1) {
//alert(static_decrypt_signature(nchkend).length);
nlink+="&signature=" + static_decrypt_signature(nchkend);
}
else if (nchk.match(/type$/i)||nchk.match(/quality$/i)) {
nlink = nlink+"&"+nchk+"="+encodeURIComponent(nchkend);
} else {
nlink+="&"+nchk+"="+nchkend;
}
}
}
}
if (nlink!=null&&nlink!="") {
if (nlink.indexOf("requiressl")!=-1 && nlink.indexOf("requiressl=")==-1) {
nlink+="&requiressl=yes";
}
addBox(decodeURIComponent(nlink));
}
}
}
function cleanArray(act){
var newAr = new Array();
for(var x = 0; x<act.length; x++){
if (act[x]){
newAr.push(act[x].toString());
}
}
return newAr;
}
function cleanJSON(jsn) {
if (jsn.charAt(0)!="{") {jsn = jsn.substring(jsn.indexOf('{'));}
while (jsn.charAt(jsn.length-1).match(/\s/)) {jsn = jsn.substring(0,jsn.length-2);}
if (jsn.indexOf("},")!=-1) {jsn = jsn.split('},')[0] + '}'}
try {var jda = eval(JSON.parse(jsn))}
catch(err) {
while (!jsn.charAt(jsn.length-1).match(/\}/)) {jsn = jsn.substring(0,jsn.length-2);}
var jda = eval(JSON.parse(jsn));
}
return jda;
}
function runIt(a1) {
for (var b3=0; b3<a1.length; b3++) {
if (a1[b3].innerHTML.match(/yt.playerConfig\ \=/gi)||a1[b3].innerHTML.match(/ytplayer.config\ \=/gi)) {
var jsn = a1[b3].innerHTML.toString();
if (jsn.match(/ytplayer.config\ \=/gmi)) {
jsn = jsn.split('ytplayer.config\ =')[1];
jsnaf = '{"adaptive_fmts' + jsn.split("adaptive_fmts")[1];
jsnsm = '{"url_encoded_fmt_stream_map' + jsn.split("url_encoded_fmt_stream_map")[1];
}
var dat ="";
jdata = cleanJSON(jsnsm);
try { var dat = jdata.args.url_encoded_fmt_stream_map }
catch(err) {try { var dat = jdata.url_encoded_fmt_stream_map } catch(err){}}
dat = dat.replace(/\"/g,"\%22").replace(/\,\+/g,"%2C%2B");
if (dat.indexOf(",")!=-1) {dat = dat.split(",")}
procURLS(dat);
var dat ="";
jdata = cleanJSON(jsnaf);
try { var dat = jdata.args.adaptive_fmts }
catch(err) {try { var dat = jdata.adaptive_fmts } catch(err){}}
dat = dat.replace(/\"/g,"\%22").replace(/\,\+/g,"%2C%2B");
if (dat.indexOf(",")!=-1) {dat = dat.split(",")}
procURLS(dat);
}
}
}
function setCook() {
if (window.navigator.cookieEnabled) {
document.cookie = "GEO=;domain=.youtube.com;path=/";
//document.cookie = "use_hitbox=;";
document.cookie = "VISITOR_INFO1_LIVE=;domain=.youtube.com;path=/";
//document.cookie = "recently_watched_video_id_list=;"
document.cookie = "YSC=;domain=.youtube.com;path=/";
}
}
function reverse(s){
return s.split("").reverse().join("");
}
function static_decrypt_signature(s, age_gate) {
if (age_gate) {
if (s.length==86) {
// return s[2:63] + s[82] + s[64:82] + s[63];
return s.substring(2,63) + s.substr(82,1) + s.substring(64,82) + s.substr(63,1);
}
}
if (s.length==93) {
s = reverse(s);
//return s[86:29:-1] + s[88] + s[28:5:-1];
return s.substring(7,64) + s.substr(5,1) + s.substring(65,88);
} else if(s.length==92) {
// return s[25] + s[3:25] + s[0] + s[26:42] + s[79] + s[43:79] + s[91] + s[80:83];
return s.substr(25,1) + s.substring(3,25) + s.substr(0,1) + s.substring(26,42) + s.substr(79,1) + s.substring(43,79) + s.substr(91,1) + s.substring(80,83);
} else if(s.length==91) {
s = reverse(s);
//return s;
// return s[84:27:-1] + s[86] + s[26:5:-1];
return s.substring(7,64) + s.substr(5,1) + s.substring(65,86);
} else if(s.length==90) {
// return s[25] + s[3:25] + s[2] + s[26:40] + s[77] + s[41:77] + s[89] + s[78:81];
return s.substr(25,1) + s.substring(3,25) + s.substr(2,1) + s.substring(26,40) + s.substr(77,1) + s.substring(41,77) + s.substr(89,1) + s.substring(78,81);
} else if(s.length==89) {
s = reverse(s);
// return s[84:78:-1] + s[87] + s[77:60:-1] + s[0] + s[59:3:-1];
return s.substring(5,11) + s.substr(2,1) + s.substring(12,29) + s.substr(89,1) + s.substring(30,86);
} else if(s.length==88) {
// return s[7:28] + s[87] + s[29:45] + s[55] + s[46:55] + s[2] + s[56:87] + s[28];
return s.substring(7,28) + s.substr(87,1) + s.substring(29,45) + s.substr(55,1) + s.substring(46,55) + s.substr(2,1) + s.substring(56,87) + s.substr(28,1);
} else if(s.length==87) {
// return s[6:27] + s[4] + s[28:39] + s[27] + s[40:59] + s[2] + s[60:];
return s.substring(6,27) + s.substr(4,1) + s.substring(28,39) + s.substr(27,1) + s.substring(40,59) + s.substr(2,1) + s.substring(60);
} else if(s.length==86) {
s = reverse(s);
// return s[80:72:-1] + s[16] + s[71:39:-1] + s[72] + s[38:16:-1] + s[82] + s[15::-1];
return s.substring(6,14)+s.substr(70,1)+s.substring(15,47)+s.substr(14,1)+s.substring(48,70)+s.substr(4,1)+s.substring(71);
} else if(s.length==85) {
//return s[3:11] + s[0] + s[12:55] + s[84] + s[56:84];
return s.substring(3,11)+s.subtr(0,1)+s.substring(12,55)+s.subtr(84,1)+s.substring(56,84);
} else if(s.length==84) {
//return s[78:70:-1] + s[14] + s[69:37:-1] + s[70] + s[36:14:-1] + s[80] + s[:14][::-1];
s = reverse(s);
return s.substring(6,14)+s.substr(70,1)+s.substring(15,47)+s.substr(14,1)+s.substring(48,70)+s.substr(4,1)+s.substring(70)+s.substr(0,1);
} else if(s.length==83) {
s = reverse(s);
// return s[80:63:-1] + s[0] + s[62:0:-1] + s[63];
return s.substring(3,20)+s.substr(83,1)+s.substring(21,83)+s.substr(20,1);
} else if(s.length==82) {
s = reverse(s);
// return s[80:37:-1] + s[7] + s[36:7:-1] + s[0] + s[6:0:-1] + s[37];
return s.substring(2,45)+s.substr(75,1)+s.substring(46,75)+s.substr(82,1)+s.substring(76,82)+s.substr(45,1);
} else if(s.length==81) {
s = reverse(s);
// return s[56] + s[79:56:-1] + s[41] + s[55:41:-1] + s[80] + s[40:34:-1] + s[0] + s[33:29:-1] + s[34] + s[28:9:-1] + s[29] + s[8:0:-1] + s[9];
return s.substr(25,1)+s.substring(2,25)+s.substr(40,1)+s.substring(26,40)+s.substr(1,1)+s.substring(41,47)+s.substr(81,1)+s.substring(48,52)+s.substr(47,1)+s.substring(53,72)+s.substr(52,1)+s.substring(73,81)+s.substr(72,1);
//return s;
} else if(s.length==80) {
// return s[1:19] + s[0] + s[20:68] + s[19] + s[69:80];
return s.substring(1,19)+s.substr(0,1)+s.substring(20,68)+s.substr(19,1)+s.substring(69,80);
} else if(s.length==79) {
s = reverse(s);
// return s[54] + s[77:54:-1] + s[39] + s[53:39:-1] + s[78] + s[38:34:-1] + s[0] + s[33:29:-1] + s[34] + s[28:9:-1] + s[29] + s[8:0:-1] + s[9];
return s.substr(25,1)+s.substring(2,25)+s.substr(40,1)+s.substring(26,40)+s.substr(1,1)+s.substring(41,45)+s.substr(79,1)+s.substring(46,50)+s.substr(45,1)+s.substring(51,70)+s.substr(50,1)+s.substring(71,79)+s.substr(70,1);
}
}
if (scrhead!=null&&scrhead!=""&&(wclh.indexOf("/watch?")!=-1)) {
setCook();
var select = document.createElement('select');
var info = document.createElement('a');
var gui = document.getElementById('watch-uploader-info');
info.className = 'yt-uix-button yt-uix-button-default';
gui.appendChild(select);
gui.appendChild(info);
info.innerText = "Click here (or save as) to download"
select.onchange = function() {
info.href = select.value;
//document.location = select.value;
}
runIt(scrhead);
select.innerHTML = html;
select.onchange();
setCook();
}