1 | // ==UserScript==
|
---|
2 | // @name Popup Videos Respooled
|
---|
3 | // @version 1.0
|
---|
4 | // @description Transfers user selected YouTube (and similar video sites) to the Popup Videos site for embelishment
|
---|
5 | // @homepageURL http://www.greenstone.org/popup-videos-respooled
|
---|
6 | // @namespace http://www.greenstone.org
|
---|
7 | // @include about:addons
|
---|
8 | // @include http://www.youtube.com/*
|
---|
9 | // @include https://www.youtube.com/*
|
---|
10 | // @exclude http://www.youtube.com/embed/*
|
---|
11 | // @exclude https://www.youtube.com/embed/*
|
---|
12 | // @match http://www.youtube.com/*
|
---|
13 | // @match https://www.youtube.com/*
|
---|
14 | // @match http://s.ytimg.com/yts/jsbin/html5player*
|
---|
15 | // @match https://s.ytimg.com/yts/jsbin/html5player*
|
---|
16 | // @match http://manifest.googlevideo.com/*
|
---|
17 | // @match https://manifest.googlevideo.com/*
|
---|
18 | // @match http://*.googlevideo.com/videoplayback*
|
---|
19 | // @match https://*.googlevideo.com/videoplayback*
|
---|
20 | // @match http://*.youtube.com/videoplayback*
|
---|
21 | // @match https://*.youtube.com/videoplayback*
|
---|
22 | // @grant GM_xmlhttpRequest
|
---|
23 | // @grant GM_getValue
|
---|
24 | // @grant GM_setValue
|
---|
25 | // @run-at document-end
|
---|
26 | // @license GPL v3
|
---|
27 | // @icon data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAEAAAABACAMAAACdt4HsAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAB3RJTUUH3wYQAiYzj2+QOQAAAB1pVFh0Q29tbWVudAAAAAAAQ3JlYXRlZCB3aXRoIEdJTVBkLmUHAAABF1BMVEUAAABpOcRqOsVrO8ZsPcZuPsdvQMdwQchxQ8hyRMlzRsl1R8p2Scp3S8p5Tst6T8x8Ucx9Us1/Vc6AV86BWc6DWs+EXM+FXdCGX9CHYNGIYtGNaNOOatORbdSSbtWUcdaVc9aWdNeYdteaedicfNmff9qggdqhgtuihNujhtulh9ymidynit2pjd6qj96skN+tkt+uk+Cwl+CzmuG0m+K1neK6o+S7peS8puW+qea/q+bBrOfEsejFs+nGtOnItunJt+rKuerNvezPv+zQwO3Rwu3SxO3Txe7Ux+7Xyu/Yy/DZzfDazvHb0PHd0vHg1vPh2PPi2fTl3PXm3vXn3/bo4fbp4/br5Pft5/jv6vny7frz7/r///8b1pnDAAAAAXRSTlMAQObYZgAAAAFiS0dEXOrYAJcAAAKmSURBVFjD5ddre9IwFADgNhjCZUAZl21cnbXbHJt4m2UwJuIu1rmCUJV2//9/CAVKDyeFtn7TfGFPsvM+SXqSngrCv9y+XzXr+9lsNl9TWndPAYOfPtUTEbs9sxuNHbQm/sN/NRfRDjAlKK3d+wufnEUJ4QGUljQf8R8ThHgBlB1tW8ikQsgGgFJp8yQGKbIFoOzdhvg7SrYD7NQz/poQPwA78po/FRGgtNtlBLBzbvzPuIiAq9lACwFM5QG7IgKU+YiMgPgAx78WMdCeD31GAMtZaANEDtCbj33DAN6GUkCAjWD8jRgUOIRAMTDAwD5+FYMDYBeOQwAp14OwYiEA1scrCAYoK+BtKCC3AsqhAPbDAXbCATfLeCMSDmgvgQcxHHCyBL6EBOS/BereQDbKASTfgGIKQi8KgVhXEPSSB3APgX27c5R1A5mx/VcOAC+XgA4Bfd5rHqyAgrm43ABw4eQBA4CTX/ISODSXXQC4dv4zzweE3+BnVjcA4MHpfwGAK+93H1hCxnD6LwEQHXnFm5IbqKwGhhHwGFMewjgHHmPTNbQHEyk64L47JZBIcd1dlqxlYkTH8XoMZmLF/XIaJtfPgsrZPwhcCpxr2XWYmjD+/fphyhlgfDEF92l85R4/Rafxw9oMz/FxllejMjrOJWMNMPbwfVBbZLBZQ/dBrIc2uc/whVKwk3hcwBfKMaoPBOsNxSVOeppSgwwuccoGJ08smeAiiw10hous4i03Ux+rPss8qe9xVrSqL2C3Y3mdNk2m24GSd/x0FY3kFiBWu91YbVtqcRPApLPHLfW+pTXSXgBLVDdN3yG6SpYLpKrq0N9Hj9FtlJIEfHTRRF7xG27PYthpPi+md+KURmk8nS+fqJoR8MvPMrRu52LW1I42DBr9X7U/PqNiTnkh61QAAAAASUVORK5CYII=
|
---|
28 | // ==/UserScript==
|
---|
29 |
|
---|
30 | // Based on :
|
---|
31 | // @ name Download YouTube Videos as MP4
|
---|
32 | // @ description Adds a button that lets you download YouTube videos.
|
---|
33 | // @ homepageURL https://github.com/gantt/downloadyoutube
|
---|
34 | // @ author Gantt
|
---|
35 | // @ version 1.8.1
|
---|
36 |
|
---|
37 | function parseQueryString(queryString) {
|
---|
38 |
|
---|
39 | var vars = queryString.split('&');
|
---|
40 |
|
---|
41 | var hashmap = {};
|
---|
42 | for (var i = 0; i < vars.length; i++) {
|
---|
43 | var pair = vars[i].split('=');
|
---|
44 | var key = decodeURIComponent(pair[0]);
|
---|
45 | var val = decodeURIComponent(pair[1]);
|
---|
46 | hashmap[key] = val;
|
---|
47 | }
|
---|
48 |
|
---|
49 | return hashmap;
|
---|
50 | }
|
---|
51 |
|
---|
52 | function respoolme(downloadURL) {
|
---|
53 | //alert("before ajax call: " + downloadURL);
|
---|
54 | var paramMap = parseQueryString(downloadURL);
|
---|
55 | var id = paramMap.id;
|
---|
56 | var title = paramMap.title;
|
---|
57 | var mime = paramMap.mime;
|
---|
58 |
|
---|
59 | var base_url = "http://localhost:8383/greenstone3/respoolme-downloader.jsp";
|
---|
60 | var url = base_url + "?downloadURL="+ encodeURIComponent(downloadURL) + "&id=" + id + "&title=" + title + "&mime=" + mime;
|
---|
61 |
|
---|
62 | //console.log("#### Downloading: http://localhost:8383/greenstone3/respoolme-downloader.jsp?downloadURL="+ encodeURIComponent(downloadURL));
|
---|
63 | console.log("#### Downloading: " + url);
|
---|
64 | var busyIcon = document.getElementById("busy-icon");
|
---|
65 | busyIcon.setAttribute("style","display:block;");
|
---|
66 |
|
---|
67 | GM_xmlhttpRequest({
|
---|
68 | method: "GET",
|
---|
69 | //url: "http://localhost:8383/greenstone3/respoolme-downloader.jsp?downloadURL="+ encodeURIComponent(downloadURL),
|
---|
70 | url: url,
|
---|
71 | onprogress: function(response) {
|
---|
72 | console.log("*** onprogress()");
|
---|
73 | },
|
---|
74 | onreadystatechange: function(response) {
|
---|
75 | console.log("*** onreadystatechange()");
|
---|
76 | },
|
---|
77 | onload: function(response) {
|
---|
78 | console.log("**** response text from calling index.jsp: " + response.responseText);
|
---|
79 | busyIcon.setAttribute("style","display:none;");
|
---|
80 | }
|
---|
81 | });
|
---|
82 | }
|
---|
83 |
|
---|
84 |
|
---|
85 | (function () {
|
---|
86 | var FORMAT_LABEL={'5':'FLV 240p','18':'MP4 360p','22':'MP4 720p','34':'FLV 360p','35':'FLV 480p','37':'MP4 1080p','38':'MP4 2160p','43':'WebM 360p','44':'WebM 480p','45':'WebM 720p','46':'WebM 1080p','135':'MP4 480p - no audio','137':'MP4 1080p - no audio','138':'MP4 2160p - no audio','139':'M4A 48kbps - audio','140':'M4A 128kbps - audio','141':'M4A 256kbps - audio','264':'MP4 1440p - no audio','298':'MP4 720p60 - no audio','299':'MP4 1080p60 - no audio'};
|
---|
87 | var FORMAT_TYPE={'5':'flv','18':'mp4','22':'mp4','34':'flv','35':'flv','37':'mp4','38':'mp4','43':'webm','44':'webm','45':'webm','46':'webm','135':'mp4','137':'mp4','138':'mp4','139':'m4a','140':'m4a','141':'m4a','264':'mp4','298':'mp4','299':'mp4'};
|
---|
88 | var FORMAT_ORDER=['5','18','34','43','35','135','44','22','298','45','37','299','46','264','38','139','140','141'];
|
---|
89 | var FORMAT_RULE={'flv':'max','mp4':'all','webm':'none','m4a':'max'};
|
---|
90 | // all=display all versions, max=only highest quality version, none=no version
|
---|
91 | // the default settings show all MP4 videos, the highest quality FLV and no WebM
|
---|
92 | var SHOW_DASH_FORMATS=false;
|
---|
93 | var BUTTON_TEXT={'ar':'تÙزÙÙ','cs':'Stáhnout','de':'Herunterladen','en':'Respool Me!','es':'Descargar','fr':'Télécharger','hi':'à€¡à€Ÿà€à€šà€²à¥à€¡','hu':'Letöltés','id':'Unduh','it':'Scarica','ja':'ããŠã³ããŒã','ko':'ëŽë €ë°êž°','pl':'Pobierz','pt':'Baixar','ro':'DescÄrcaÈi','ru':'СкаÑаÑÑ','tr':'Ä°ndir','zh':'äžèœœ','zh-TW':'äžèŒ'};
|
---|
94 | var BUTTON_TOOLTIP={'ar':'تÙزÙÙ Ùذا اÙÙÙدÙÙ','cs':'Stáhnout toto video','de':'Dieses Video herunterladen','en':'Wire this video to Popup Videos Respooled','es':'Descargar este vÃdeo','fr':'Télécharger cette vidéo','hi':'à€µà¥à€¡à€¿à€¯à¥ à€¡à€Ÿà€à€šà€²à¥à€¡ à€à€°à¥à€','hu':'Videó letöltése','id':'Unduh video ini','it':'Scarica questo video','ja':'ãã®ãããªãããŠã³ããŒããã','ko':'ìŽ ë¹ëì€ë¥Œ ëŽë €ë°êž°','pl':'Pobierz plik wideo','pt':'Baixar este vÃdeo','ro':'DescÄrcaÈi acest videoclip','ru':'СкаÑаÑÑ ÑÑП вОЎеП','tr': 'Bu videoyu indir','zh':'äžèœœæ€è§é¢','zh-TW':'äžèŒæ€åœ±ç'};
|
---|
95 | var DECODE_RULE=[];
|
---|
96 | var RANDOM=7489235179; // Math.floor(Math.random()*1234567890);
|
---|
97 | var CONTAINER_ID='download-youtube-video'+RANDOM;
|
---|
98 | var LISTITEM_ID='download-youtube-video-fmt'+RANDOM;
|
---|
99 | var BUTTON_ID='download-youtube-video-button'+RANDOM;
|
---|
100 | var DEBUG_ID='download-youtube-video-debug-info';
|
---|
101 | var STORAGE_URL='download-youtube-script-url';
|
---|
102 | var STORAGE_CODE='download-youtube-signature-code';
|
---|
103 | var STORAGE_DASH='download-youtube-dash-enabled';
|
---|
104 | var isDecodeRuleUpdated=false;
|
---|
105 |
|
---|
106 | start();
|
---|
107 |
|
---|
108 | function start() {
|
---|
109 | var pagecontainer=document.getElementById('page-container');
|
---|
110 | if (!pagecontainer) return;
|
---|
111 | if (/^https?:\/\/www\.youtube.com\/watch\?/.test(window.location.href)) run();
|
---|
112 | var isAjax=/class[\w\s"'-=]+spf\-link/.test(pagecontainer.innerHTML);
|
---|
113 | var content=document.getElementById('content');
|
---|
114 | if (isAjax && content) { // Ajax UI
|
---|
115 | var mo=window.MutationObserver||window.WebKitMutationObserver;
|
---|
116 | if(typeof mo!=='undefined') {
|
---|
117 | var observer=new mo(function(mutations) {
|
---|
118 | mutations.forEach(function(mutation) {
|
---|
119 | if(mutation.addedNodes!==null) {
|
---|
120 | for (var i=0; i<mutation.addedNodes.length; i++) {
|
---|
121 | if (mutation.addedNodes[i].id=='watch7-container') { // old value: movie_player
|
---|
122 | run();
|
---|
123 | break;
|
---|
124 | }
|
---|
125 | }
|
---|
126 | }
|
---|
127 | });
|
---|
128 | });
|
---|
129 | observer.observe(content, {childList: true, subtree: true}); // old value: pagecontainer
|
---|
130 | } else { // MutationObserver fallback for old browsers
|
---|
131 | // supressed the YouTube downloader menu // ****
|
---|
132 | // pagecontainer.addEventListener('DOMNodeInserted', onNodeInserted, false);
|
---|
133 | }
|
---|
134 | }
|
---|
135 | }
|
---|
136 |
|
---|
137 | function onNodeInserted(e) {
|
---|
138 | if (e && e.target && e.target.id=='watch7-container') { // old value: movie_player
|
---|
139 | run();
|
---|
140 | }
|
---|
141 | }
|
---|
142 |
|
---|
143 | function run() {
|
---|
144 | if (document.getElementById(CONTAINER_ID)) return; // check download container
|
---|
145 | if (document.getElementById('p') && document.getElementById('vo')) return; // Feather not supported
|
---|
146 |
|
---|
147 | var videoID, videoFormats, videoAdaptFormats, videoManifestURL, scriptURL=null;
|
---|
148 | var isSignatureUpdatingStarted=false;
|
---|
149 | var operaTable=new Array();
|
---|
150 | var language=document.documentElement.getAttribute('lang');
|
---|
151 | var textDirection='left';
|
---|
152 | if (document.body.getAttribute('dir')=='rtl') {
|
---|
153 | textDirection='right';
|
---|
154 | }
|
---|
155 | if (document.getElementById('watch7-action-buttons')) { // old UI
|
---|
156 | fixTranslations(language, textDirection);
|
---|
157 | }
|
---|
158 |
|
---|
159 | // obtain video ID, formats map
|
---|
160 |
|
---|
161 | var args=null;
|
---|
162 | var usw=(typeof this.unsafeWindow !== 'undefined')?this.unsafeWindow:window; // Firefox, Opera<15
|
---|
163 | if (usw.ytplayer && usw.ytplayer.config && usw.ytplayer.config.args) {
|
---|
164 | args=usw.ytplayer.config.args;
|
---|
165 | }
|
---|
166 | if (args) {
|
---|
167 | videoID=args['video_id'];
|
---|
168 | videoFormats=args['url_encoded_fmt_stream_map'];
|
---|
169 | videoAdaptFormats=args['adaptive_fmts'];
|
---|
170 | videoManifestURL=args['dashmpd'];
|
---|
171 | debug('DYVAM - Info: Standard mode. videoID '+(videoID?videoID:'none')+'; ');
|
---|
172 | }
|
---|
173 | if (usw.ytplayer && usw.ytplayer.config && usw.ytplayer.config.assets) {
|
---|
174 | scriptURL=usw.ytplayer.config.assets.js;
|
---|
175 | }
|
---|
176 |
|
---|
177 | if (videoID==null) { // unsafeWindow workaround (Chrome, Opera 15+)
|
---|
178 | var buffer=document.getElementById(DEBUG_ID+'2')
|
---|
179 | if (buffer) {
|
---|
180 | while (buffer.firstChild) {
|
---|
181 | buffer.removeChild(buffer.firstChild);
|
---|
182 | }
|
---|
183 | } else {
|
---|
184 | buffer=createHiddenElem('pre', DEBUG_ID+'2');
|
---|
185 | }
|
---|
186 | injectScript ('document.getElementById("'+DEBUG_ID+'2").appendChild(document.createTextNode(\'"video_id":"\'+ytplayer.config.args.video_id+\'", "js":"\'+ytplayer.config.assets.js+\'", "dashmpd":"\'+ytplayer.config.args.dashmpd+\'", "url_encoded_fmt_stream_map":"\'+ytplayer.config.args.url_encoded_fmt_stream_map+\'", "adaptive_fmts":"\'+ytplayer.config.args.adaptive_fmts+\'"\'));');
|
---|
187 | var code=buffer.innerHTML;
|
---|
188 | if (code) {
|
---|
189 | videoID=findMatch(code, /\"video_id\":\s*\"([^\"]+)\"/);
|
---|
190 | videoFormats=findMatch(code, /\"url_encoded_fmt_stream_map\":\s*\"([^\"]+)\"/);
|
---|
191 | videoFormats=videoFormats.replace(/&/g,'\\u0026');
|
---|
192 | videoAdaptFormats=findMatch(code, /\"adaptive_fmts\":\s*\"([^\"]+)\"/);
|
---|
193 | videoAdaptFormats=videoAdaptFormats.replace(/&/g,'\\u0026');
|
---|
194 | videoManifestURL=findMatch(code, /\"dashmpd\":\s*\"([^\"]+)\"/);
|
---|
195 | scriptURL=findMatch(code, /\"js\":\s*\"([^\"]+)\"/);
|
---|
196 | }
|
---|
197 | debug('DYVAM - Info: Injection mode. videoID '+(videoID?videoID:'none')+'; ');
|
---|
198 | }
|
---|
199 |
|
---|
200 | if (videoID==null) { // if all else fails
|
---|
201 | var bodyContent=document.body.innerHTML;
|
---|
202 | if (bodyContent!=null) {
|
---|
203 | videoID=findMatch(bodyContent, /\"video_id\":\s*\"([^\"]+)\"/);
|
---|
204 | videoFormats=findMatch(bodyContent, /\"url_encoded_fmt_stream_map\":\s*\"([^\"]+)\"/);
|
---|
205 | videoAdaptFormats=findMatch(bodyContent, /\"adaptive_fmts\":\s*\"([^\"]+)\"/);
|
---|
206 | videoManifestURL=findMatch(bodyContent, /\"dashmpd\":\s*\"([^\"]+)\"/);
|
---|
207 | if (scriptURL==null) {
|
---|
208 | scriptURL=findMatch(bodyContent, /\"js\":\s*\"([^\"]+)\"/);
|
---|
209 | scriptURL=scriptURL.replace(/\\/g,'');
|
---|
210 | }
|
---|
211 | }
|
---|
212 | debug('DYVAM - Info: Brute mode. videoID '+(videoID?videoID:'none')+'; ');
|
---|
213 | }
|
---|
214 |
|
---|
215 | debug('DYVAM - Info: url '+window.location.href+'; useragent '+window.navigator.userAgent);
|
---|
216 |
|
---|
217 | if (videoID==null || videoFormats==null || videoID.length==0 || videoFormats.length==0) {
|
---|
218 | debug('DYVAM - Error: No config information found. YouTube must have changed the code.');
|
---|
219 | return;
|
---|
220 | }
|
---|
221 |
|
---|
222 | // Opera 12 extension message handler
|
---|
223 | if (typeof window.opera !== 'undefined' && window.opera && typeof opera.extension !== 'undefined') {
|
---|
224 | opera.extension.onmessage = function(event) {
|
---|
225 | var index=findMatch(event.data.action, /xhr\-([0-9]+)\-response/);
|
---|
226 | if (index && operaTable[parseInt(index,10)]) {
|
---|
227 | index=parseInt(index,10);
|
---|
228 | var trigger=(operaTable[index])['onload'];
|
---|
229 | if (typeof trigger === 'function' && event.data.readyState == 4) {
|
---|
230 | if (trigger) {
|
---|
231 | trigger(event.data);
|
---|
232 | }
|
---|
233 | }
|
---|
234 | }
|
---|
235 | }
|
---|
236 | }
|
---|
237 |
|
---|
238 | if (!isDecodeRuleUpdated) {
|
---|
239 | DECODE_RULE=getDecodeRules(DECODE_RULE);
|
---|
240 | isDecodeRuleUpdated=true;
|
---|
241 | }
|
---|
242 | if (scriptURL) {
|
---|
243 | if (scriptURL.indexOf('//')==0) {
|
---|
244 | var protocol=(document.location.protocol=='http:')?'http:':'https:';
|
---|
245 | scriptURL=protocol+scriptURL;
|
---|
246 | }
|
---|
247 | fetchSignatureScript(scriptURL);
|
---|
248 | }
|
---|
249 |
|
---|
250 | // video title
|
---|
251 | var videoTitle=document.title || 'video';
|
---|
252 | videoTitle=videoTitle.replace(/\s*\-\s*YouTube$/i,'').replace(/[#"\?:\*]/g,'').replace(/[&\|\\\/]/g,'_').replace(/'/g,'\'').replace(/^\s+|\s+$/g,'').replace(/\.+$/g,'');
|
---|
253 |
|
---|
254 | // parse the formats map
|
---|
255 | var sep1='%2C', sep2='%26', sep3='%3D';
|
---|
256 | if (videoFormats.indexOf(',')>-1) {
|
---|
257 | sep1=',';
|
---|
258 | sep2=(videoFormats.indexOf('&')>-1)?'&':'\\u0026';
|
---|
259 | sep3='=';
|
---|
260 | }
|
---|
261 | var videoURL=new Array();
|
---|
262 | var videoSignature=new Array();
|
---|
263 | if (videoAdaptFormats) {
|
---|
264 | videoFormats=videoFormats+sep1+videoAdaptFormats;
|
---|
265 | }
|
---|
266 | var videoFormatsGroup=videoFormats.split(sep1);
|
---|
267 | for (var i=0;i<videoFormatsGroup.length;i++) {
|
---|
268 | var videoFormatsElem=videoFormatsGroup[i].split(sep2);
|
---|
269 | var videoFormatsPair=new Array();
|
---|
270 | for (var j=0;j<videoFormatsElem.length;j++) {
|
---|
271 | var pair=videoFormatsElem[j].split(sep3);
|
---|
272 | if (pair.length==2) {
|
---|
273 | videoFormatsPair[pair[0]]=pair[1];
|
---|
274 | }
|
---|
275 | }
|
---|
276 | if (videoFormatsPair['url']==null) continue;
|
---|
277 | var url=unescape(unescape(videoFormatsPair['url'])).replace(/\\\//g,'/').replace(/\\u0026/g,'&');
|
---|
278 | if (videoFormatsPair['itag']==null) continue;
|
---|
279 | var itag=videoFormatsPair['itag'];
|
---|
280 | var sig=videoFormatsPair['sig']||videoFormatsPair['signature'];
|
---|
281 | if (sig) {
|
---|
282 | url=url+'&signature='+sig;
|
---|
283 | videoSignature[itag]=null;
|
---|
284 | } else if (videoFormatsPair['s']) {
|
---|
285 | url=url+'&signature='+decryptSignature(videoFormatsPair['s']);
|
---|
286 | videoSignature[itag]=videoFormatsPair['s'];
|
---|
287 | }
|
---|
288 | if (url.toLowerCase().indexOf('ratebypass')==-1) { // speed up download for dash
|
---|
289 | url=url+'&ratebypass=yes';
|
---|
290 | }
|
---|
291 | if (url.toLowerCase().indexOf('http')==0) { // validate URL
|
---|
292 | videoURL[itag]=url+'&title='+videoTitle;
|
---|
293 | }
|
---|
294 | }
|
---|
295 |
|
---|
296 | var showFormat=new Array();
|
---|
297 | for (var category in FORMAT_RULE) {
|
---|
298 | var rule=FORMAT_RULE[category];
|
---|
299 | for (var index in FORMAT_TYPE){
|
---|
300 | if (FORMAT_TYPE[index]==category) {
|
---|
301 | showFormat[index]=(rule=='all');
|
---|
302 | }
|
---|
303 | }
|
---|
304 | if (rule=='max') {
|
---|
305 | for (var i=FORMAT_ORDER.length-1;i>=0;i--) {
|
---|
306 | var format=FORMAT_ORDER[i];
|
---|
307 | if (FORMAT_TYPE[format]==category && videoURL[format]!=undefined) {
|
---|
308 | showFormat[format]=true;
|
---|
309 | break;
|
---|
310 | }
|
---|
311 | }
|
---|
312 | }
|
---|
313 | }
|
---|
314 |
|
---|
315 | var dashPref=getPref(STORAGE_DASH);
|
---|
316 | if (dashPref=='1') {
|
---|
317 | SHOW_DASH_FORMATS=true;
|
---|
318 | } else if (dashPref!='0') {
|
---|
319 | setPref(STORAGE_DASH,'0');
|
---|
320 | }
|
---|
321 |
|
---|
322 | var downloadCodeList=[];
|
---|
323 | for (var i=0;i<FORMAT_ORDER.length;i++) {
|
---|
324 | var format=FORMAT_ORDER[i];
|
---|
325 | if (format=='37' && videoURL[format]==undefined) { // hack for dash 1080p
|
---|
326 | if (videoURL['137']) {
|
---|
327 | format='137';
|
---|
328 | }
|
---|
329 | showFormat[format]=showFormat['37'];
|
---|
330 | } else if (format=='38' && videoURL[format]==undefined) { // hack for dash 4K
|
---|
331 | if (videoURL['138']) {
|
---|
332 | format='138';
|
---|
333 | }
|
---|
334 | showFormat[format]=showFormat['38'];
|
---|
335 | }
|
---|
336 | if (!SHOW_DASH_FORMATS && format.length>2) continue;
|
---|
337 | if (videoURL[format]!=undefined && FORMAT_LABEL[format]!=undefined && showFormat[format]) {
|
---|
338 | downloadCodeList.push({url:videoURL[format],sig:videoSignature[format],format:format,label:FORMAT_LABEL[format]});
|
---|
339 | debug('DYVAM - Info: itag'+format+' url:'+videoURL[format]);
|
---|
340 | }
|
---|
341 | }
|
---|
342 |
|
---|
343 | if (downloadCodeList.length==0) {
|
---|
344 | debug('DYVAM - Error: No download URL found. Probably YouTube uses encrypted streams.');
|
---|
345 | return; // no format
|
---|
346 | }
|
---|
347 |
|
---|
348 | // find parent container
|
---|
349 | var newWatchPage=false;
|
---|
350 | var parentElement=document.getElementById('watch7-action-buttons');
|
---|
351 | if (parentElement==null) {
|
---|
352 | parentElement=document.getElementById('watch8-secondary-actions');
|
---|
353 | if (parentElement==null) {
|
---|
354 | debug('DYVAM Error - No container for adding the download button. YouTube must have changed the code.');
|
---|
355 | return;
|
---|
356 | } else {
|
---|
357 | newWatchPage=true;
|
---|
358 | }
|
---|
359 | }
|
---|
360 |
|
---|
361 | // get button labels
|
---|
362 | var buttonText=(BUTTON_TEXT[language])?BUTTON_TEXT[language]:BUTTON_TEXT['en'];
|
---|
363 | var buttonLabel=(BUTTON_TOOLTIP[language])?BUTTON_TOOLTIP[language]:BUTTON_TOOLTIP['en'];
|
---|
364 |
|
---|
365 | // generate download code for regular interface
|
---|
366 | var mainSpan=document.createElement('span');
|
---|
367 |
|
---|
368 | if (newWatchPage) {
|
---|
369 | var spanIcon=document.createElement('span');
|
---|
370 | spanIcon.setAttribute('class', 'yt-uix-button-icon-wrapper');
|
---|
371 | spanIcon.setAttribute('style', 'opacity: 1.0; color: white');
|
---|
372 | var imageIcon=document.createElement('img');
|
---|
373 | imageIcon.setAttribute('src', '//s.ytimg.com/yt/img/pixel-vfl3z5WfW.gif');
|
---|
374 | imageIcon.setAttribute('class', 'yt-uix-button-icon');
|
---|
375 | 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==);'); // ****
|
---|
376 |
|
---|
377 | var imageBusyIcon=document.createElement('img');
|
---|
378 | imageBusyIcon.setAttribute('class', 'yt-uix-button-icon');
|
---|
379 | imageBusyIcon.setAttribute('id', 'busy-icon');
|
---|
380 | imageBusyIcon.setAttribute('width', '90');
|
---|
381 | imageBusyIcon.setAttribute('style', 'display:none;');
|
---|
382 | imageBusyIcon.setAttribute('src', 'data:image/gif;base64,R0lGODlh3AATAPQAAG4Ar////5JAwp9YyqVizZVGxJlMxow2v4Mmuo46wYUqvIEiuX8euHwat5pOx5NCw3oWtXgStIs0v3QMsnMKsokwvXIIsY04wIguvXcQs4Qou5A8wZ1UyXEGsKNezKhozyH/C05FVFNDQVBFMi4wAwEAAAAh/hpDcmVhdGVkIHdpdGggYWpheGxvYWQuaW5mbwAh+QQJCgAAACwAAAAA3AATAAAF/yAgjmRpnmiqrmzrvnAsz3Rt33iu73zv/8CgcEgECAaEpHLJbDqf0Kh0Sq1ar9isdjoQtAQFg8PwKIMHnLF63N2438f0mv1I2O8buXjvaOPtaHx7fn96goR4hmuId4qDdX95c4+RG4GCBoyAjpmQhZN0YGYFXitdZBIVGAoKoq4CG6Qaswi1CBtkcG6ytrYJubq8vbfAcMK9v7q7D8O1ycrHvsW6zcTKsczNz8HZw9vG3cjTsMIYqQgDLAQGCQoLDA0QCwUHqfYSFw/xEPz88/X38Onr14+Bp4ADCco7eC8hQYMAEe57yNCew4IVBU7EGNDiRn8Z831cGLHhSIgdE/9chIeBgDoB7gjaWUWTlYAFE3LqzDCTlc9WOHfm7PkTqNCh54rePDqB6M+lR536hCpUqs2gVZM+xbrTqtGoWqdy1emValeXKwgcWABB5y1acFNZmEvXwoJ2cGfJrTv3bl69Ffj2xZt3L1+/fw3XRVw4sGDGcR0fJhxZsF3KtBTThZxZ8mLMgC3fRatCLYMIFCzwLEprg84OsDus/tvqdezZf13Hvr2B9Szdu2X3pg18N+68xXn7rh1c+PLksI/Dhe6cuO3ow3NfV92bdArTqC2Ebc3A8vjf5QWf15Bg7Nz17c2fj69+fnq+8N2Lty+fuP78/eV2X13neIcCeBRwxorbZrAxAJoCDHbgoG8RTshahQ9iSKEEzUmYIYfNWViUhheCGJyIP5E4oom7WWjgCeBBAJNv1DVV01MZdJhhjdkplWNzO/5oXI846njjVEIqR2OS2B1pE5PVscajkxhMycqLJgxQCwT40PjfAV4GqNSXYdZXJn5gSkmmmmJu1aZYb14V51do+pTOCmA00AqVB4hG5IJ9PvYnhIFOxmdqhpaI6GeHCtpooisuutmg+Eg62KOMKuqoTaXgicQWoIYq6qiklmoqFV0UoeqqrLbq6quwxirrrLTWauutJ4QAACH5BAkKAAAALAAAAADcABMAAAX/ICCOZGmeaKqubOu+cCzPdG3feK7vfO//wKBwSAQIBoSkcslsOp/QqHRKrVqv2Kx2OhC0BAXHx/EoCzboAcdhcLDdgwJ6nua03YZ8PMFPoBMca215eg98G36IgYNvDgOGh4lqjHd7fXOTjYV9nItvhJaIfYF4jXuIf4CCbHmOBZySdoOtj5eja59wBmYFXitdHhwSFRgKxhobBgUPAmdoyxoI0tPJaM5+u9PaCQZzZ9gP2tPcdM7L4tLVznPn6OQb18nh6NV0fu3i5OvP8/nd1qjwaasHcIPAcf/gBSyAAMMwBANYEAhWYQGDBhAyLihwYJiEjx8fYMxIcsGDAxVA/yYIOZIkBAaGPIK8INJlRpgrPeasaRPmx5QgJfB0abLjz50tSeIM+pFmUo0nQQIV+vRlTJUSnNq0KlXCSq09ozIFexEBAYkeNiwgOaEtn2LFpGEQsKCtXbcSjOmVlqDuhAx3+eg1Jo3u37sZBA9GoMAw4MB5FyMwfLht4sh7G/utPGHlYAV8Nz9OnOBz4c2VFWem/Pivar0aKCP2LFn2XwhnVxBwsPbuBAQbEGiIFg1BggoWkidva5z4cL7IlStfkED48OIYoiufYIH68+cKPkqfnsB58ePjmZd3Dj199/XE20tv6/27XO3S6z9nPCz9BP3FISDefL/Bt192/uWmAv8BFzAQAQUWWFaaBgqA11hbHWTIXWIVXifNhRlq6FqF1sm1QQYhdiAhbNEYc2KKK1pXnAIvhrjhBh0KxxiINlqQAY4UXjdcjSJyeAx2G2BYJJD7NZQkjCPKuCORKnbAIXsuKhlhBxEomAIBBzgIYXIfHfmhAAyMR2ZkHk62gJoWlNlhi33ZJZ2cQiKTJoG05Wjcm3xith9dcOK5X51tLRenoHTuud2iMnaolp3KGXrdBo7eKYF5p/mXgJcogClmcgzAR5gCKymXYqlCgmacdhp2UCqL96mq4nuDBTmgBasaCFp4sHaQHHUsGvNRiiGyep1exyIra2mS7dprrtA5++z/Z8ZKYGuGsy6GqgTIDvupRGE+6CO0x3xI5Y2mOTkBjD4ySeGU79o44mcaSEClhglgsKyJ9S5ZTGY0Bnzrj+3SiKK9Rh5zjAALCywZBk/ayCWO3hYM5Y8Dn6qxxRFsgAGoJwwgDQRtYXAAragyQOmaLKNZKGaEuUlpyiub+ad/KtPqpntypvvnzR30DBtjMhNodK6Eqrl0zU0/GjTUgG43wdN6Ra2pAhGtAAZGE5Ta8TH6wknd2IytNKaiZ+Or79oR/tcvthIcAPe7DGAs9Edwk6r3qWoTaNzY2fb9HuHh2S343Hs1VIHhYtOt+Hh551rh24vP5YvXSGzh+eeghy76GuikU9FFEainrvrqrLfu+uuwxy777LTXfkIIACH5BAkKAAAALAAAAADcABMAAAX/ICCOZGmeaKqubOu+cCzPdG3feK7vfO//wKBwSAQIBoSkcslsOp/QqHRKrVqv2Kx2OhC0BAWHB2l4CDZo9IDjcBja7UEhTV+3DXi3PJFA8xMcbHiDBgMPG31pgHBvg4Z9iYiBjYx7kWocb26OD398mI2EhoiegJlud4UFiZ5sm6Kdn2mBr5t7pJ9rlG0cHg5gXitdaxwFGArIGgoaGwYCZ3QFDwjU1AoIzdCQzdPV1c0bZ9vS3tUJBmjQaGXl1OB0feze1+faiBvk8wjnimn55e/o4OtWjp+4NPIKogsXjaA3g/fiGZBQAcEAFgQGOChgYEEDCCBBLihwQILJkxIe/3wMKfJBSQkJYJpUyRIkgwcVUJq8QLPmTYoyY6ZcyfJmTp08iYZc8MBkhZgxk9aEcPOlzp5FmwI9KdWn1qASurJkClRoWKwhq6IUqpJBAwQEMBYroAHkhLt3+RyzhgCDgAV48Wbgg+waAnoLMgTOm6DwQ8CLBzdGdvjw38V5JTg2lzhyTMeUEwBWHPgzZc4TSOM1bZia6LuqJxCmnOxv7NSsl1mGHHiw5tOuIWeAEHcFATwJME/ApgFBc3MVLEgPvE+Ddb4JokufPmFBAuvPXWu3MIF89wTOmxvOvp179evQtwf2nr6aApPyzVd3jn089e/8xdfeXe/xdZ9/d1ngHf98lbHH3V0LMrgPgsWpcFwBEFBgHmyNXWeYAgLc1UF5sG2wTHjIhNjBiIKZCN81GGyQwYq9uajeMiBOQGOLJ1KjTI40kmfBYNfc2NcGIpI4pI0vyrhjiT1WFqOOLEIZnjVOVpmajYfBiCSNLGbA5YdOkjdihSkQwIEEEWg4nQUmvYhYe+bFKaFodN5lp3rKvJYfnBKAJ+gGDMi3mmbwWYfng7IheuWihu5p32XcSWdSj+stkF95dp64jJ+RBipocHkCCp6PCiRQ6INookCAAwy0yd2CtNET3Yo7RvihBjFZAOaKDHT43DL4BQnsZMo8xx6uI1oQrHXXhHZrB28G62n/YSYxi+uzP2IrgbbHbiaer7hCiOxDFWhrbmGnLVuus5NFexhFuHLX6gkEECorlLpZo0CWJG4pLjIACykmBsp0eSSVeC15TDJeUhlkowlL+SWLNJpW2WEF87urXzNWSZ6JOEb7b8g1brZMjCg3ezBtWKKc4MvyEtwybPeaMAA1ECRoAQYHYLpbeYYCLfQ+mtL5c9CnfQpYpUtHOSejEgT9ogZ/GSqd0f2m+LR5WzOtHqlQX1pYwpC+WbXKqSYtpJ5Mt4a01lGzS3akF60AxkcTaLgAyRBPWCoDgHfJqwRuBuzdw/1ml3iCwTIeLUWJN0v4McMe7uasCTxseNWPSxc5RbvIgD7geZLbGrqCG3jepUmbbze63Y6fvjiOylbwOITPfIHEFsAHL/zwxBdvPBVdFKH88sw37/zz0Ecv/fTUV2/99SeEAAAh+QQJCgAAACwAAAAA3AATAAAF/yAgjmRpnmiqrmzrvnAsz3Rt33iu73zv/8CgcEgECAaEpHLJbDqf0Kh0Sq1ar9isdjoQtAQFh2cw8BQEm3T6yHEYHHD4oKCuD9qGvNsxT6QTgAkcHHmFeX11fm17hXwPG35qgnhxbwMPkXaLhgZ9gWp3bpyegX4DcG+inY+Qn6eclpiZkHh6epetgLSUcBxlD2csXXdvBQrHGgoaGhsGaIkFDwjTCArTzX+QadHU3c1ofpHc3dcGG89/4+TYktvS1NYI7OHu3fEJ5tpqBu/k+HX7+nXDB06SuoHm0KXhR65cQT8P3FRAMIAFgVMPwDCAwLHjggIHJIgceeFBg44eC/+ITCCBZYKSJ1FCWPBgpE2YMmc+qNCypwScMmnaXAkUJYOaFVyKLOqx5tCXJnMelcBzJNSYKIX2ZPkzqsyjPLku9Zr1QciVErYxaICAgEUOBRJIgzChbt0MLOPFwyBggV27eCUcmxZvg9+/dfPGo5bg8N/Ag61ZM4w4seDF1fpWhizZmoa+GSortgcaMWd/fkP/HY0MgWbTipVV++wY8GhvqSG4XUEgoYTKE+Qh0OCvggULiBckWEZ4Ggbjx5HXVc58IPQJ0idQJ66XanTpFraTe348+XLizRNcz658eHMN3rNPT+C+G/nodqk3t6a+fN3j+u0Xn3nVTQPfdRPspkL/b+dEIN8EeMm2GAYbTNABdrbJ1hyFFv5lQYTodSZABhc+loCEyhxTYYkZopdMMiNeiBxyIFajV4wYHpfBBspUl8yKHu6ooV5APsZjQxyyeNeJ3N1IYod38cgdPBUid6GCKfRWgAYU4IccSyHew8B3doGJHmMLkGkZcynKk2Z50Ym0zJzLbDCmfBbI6eIyCdyJmJmoqZmnBAXy9+Z/yOlZDZpwYihnj7IZpuYEevrYJ5mJEuqiof4l+NYDEXQpXQcMnNjZNDx1oGqJ4S2nF3EsqWrhqqVWl6JIslpAK5MaIqDeqjJq56qN1aTaQaPbHTPYr8Be6Gsyyh6Da7OkmmqP/7GyztdrNVQBm5+pgw3X7aoYKhfZosb6hyUKBHCgQKij1rghkOAJuZg1SeYIIY+nIpDvf/sqm4yNG5CY64f87qdAwSXKGqFkhPH1ZHb2EgYtw3bpKGVkPz5pJAav+gukjB1UHE/HLNJobWcSX8jiuicMMBFd2OmKwQFs2tjXpDfnPE1j30V3c7iRHlrzBD2HONzODyZtsQJMI4r0AUNaE3XNHQw95c9GC001MpIxDacFQ+ulTNTZlU3O1eWVHa6vb/pnQUUrgHHSBKIuwG+bCPyEqbAg25gMVV1iOB/IGh5YOKLKIQ6xBAcUHmzjIcIqgajZ+Ro42DcvXl7j0U4WOUd+2IGu7DWjI1pt4DYq8BPm0entuGSQY/4tBi9Ss0HqfwngBQtHbCH88MQXb/zxyFfRRRHMN+/889BHL/301Fdv/fXYZ39CCAAh+QQJCgAAACwAAAAA3AATAAAF/yAgjmRpnmiqrmzrvnAsz3Rt33iu73zv/8CgcEgECAaEpHLJbDqf0Kh0Sq1ar9isdjoQtAQFh2fAKXsKm7R6Q+Y43vABep0mGwwOPH7w2CT+gHZ3d3lyagl+CQNvg4yGh36LcHoGfHR/ZYOElQ9/a4ocmoRygIiRk5p8pYmZjXePaYBujHoOqp5qZHBlHAUFXitddg8PBg8KGsgayxvGkAkFDwgICtPTzX2mftHW3QnOpojG3dbYkNjk1waxsdDS1N7ga9zw1t/aifTk35fu6Qj3numL14fOuHTNECHqU4DDgQEsCCwidiHBAwYQMmpcUOCAhI8gJVzUuLGThAQnP/9abEAyI4MCIVOKZNnyJUqUJxNcGNlywYOQgHZirGkSJ8gHNEky+AkS58qWEJYC/bMzacmbQHkqNdlUJ1KoSz2i9COhmQYCEXtVrCBgwYS3cCf8qTcNQ9u4cFFOq2bPLV65Cf7dxZthbjW+CgbjnWtNgWPFcAsHdoxgWWK/iyV045sAc2S96SDn1exYw17REwpLQEYt2eW/qtPZRQAB7QoC61RW+GsBwYZ/CXb/XRCYLsAKFizEtUAc+G7lcZsjroscOvTmsoUvx15PwccJ0N8yL17N9PG/E7jv9S4hOV7pdIPDdZ+ePDzv2qMXn2b5+wTbKuAWnF3oZbABZY0lVmD/ApQd9thybxno2GGuCVDggaUpoyBsB1bGGgIYbJCBcuFJiOAyGohIInQSmmdeiBnMF2GHfNUlIoc1rncjYRjW6NgGf3VQGILWwNjBfxEZcAFbC7gHXQcfUYOYdwzQNxo5yUhQZXhvRYlMeVSuSOJHKJa5AQMQThBlZWZ6Bp4Fa1qzTAJbijcBlJrtxeaZ4lnnpZwpukWieGQmYx5ATXIplwTL8DdNZ07CtWYybNIJF4Ap4NZHe0920AEDk035kafieQrqXofK5ympn5JHKYjPrfoWcR8WWQGp4Ul32KPVgXdnqxM6OKqspjIYrGPDrlrsZtRIcOuR86nHFwbPvmes/6PH4frrqbvySh+mKGhaAARPzjjdhCramdoGGOhp44i+zogBkSDuWC5KlE4r4pHJkarXrj++Raq5iLmWLlxHBteavjG+6amJrUkJJI4Ro5sBv9AaOK+jAau77sbH7nspCwNIYIACffL7J4JtWQnen421nNzMcB6AqpRa9klonmBSiR4GNi+cJZpvwgX0ejj71W9yR+eIgaVvQgf0l/A8nWjUFhwtZYWC4hVnkZ3p/PJqNQ5NnwUQrQCGBBBMQIGTtL7abK+5JjAv1fi9bS0GLlJHgdjEgYzzARTwC1fgEWdJuKKBZzj331Y23qB3i9v5aY/rSUC4w7PaLeWXmr9NszMFoN79eeiM232o33EJAIzaSGwh++y012777bhT0UURvPfu++/ABy/88MQXb/zxyCd/QggAIfkECQoAAAAsAAAAANwAEwAABf8gII5kaZ5oqq5s675wLM90bd94ru987//AoHBIBAgGhKRyyWw6n9CodEqtWq/YrHY6ELQEBY5nwCk7xIWNer0hO95wziC9Ttg5b4ND/+Y87IBqZAaEe29zGwmJigmDfHoGiImTjXiQhJEPdYyWhXwDmpuVmHwOoHZqjI6kZ3+MqhyemJKAdo6Ge3OKbEd4ZRwFBV4rc4MPrgYPChrMzAgbyZSJBcoI1tfQoYsJydfe2amT3d7W0OGp1OTl0YtqyQrq0Lt11PDk3KGoG+nxBpvTD9QhwCctm0BzbOyMIwdOUwEDEgawIOCB2oMLgB4wgMCx44IHBySIHClBY0ePfyT/JCB5weRJCAwejFw58kGDlzBTqqTZcuPLmCIBiWx58+VHmiRLFj0JVCVLl0xl7qSZwCbOo0lFWv0pdefQrVFDJtr5gMBEYBgxqBWwYILbtxPsqMPAFu7blfa81bUbN4HAvXAzyLWnoDBguHIRFF6m4LBbwQngMYPXuC3fldbyPrMcGLM3w5wRS1iWWUNlvnElKDZtz/EEwaqvYahQoexEfyILi4RrYYKFZwJ3810QWZ2ECrx9Ew+O3K6F5Yq9zXbb+y30a7olJJ+wnLC16W97Py+uwdtx1NcLWzs/3G9e07stVPc9kHJ0BcLtQp+c3ewKAgYkUAFpCaAmmHqKLSYA/18WHEiZPRhsQF1nlLFWmIR8ZbDBYs0YZuCGpGXWmG92aWiPMwhEOOEEHXRwIALlwXjhio+BeE15IzpnInaLbZBBhhti9x2GbnVQo2Y9ZuCfCgBeMCB+DJDIolt4iVhOaNSJdCOBUfIlkmkyMpPAAvKJ59aXzTQzJo0WoJnmQF36Jp6W1qC4gWW9GZladCiyJd+KnsHImgRRVjfnaDEKuiZvbcYWo5htzefbl5LFWNeSKQAo1QXasdhiiwwUl2B21H3aQaghXnPcp1NagCqYslXAqnV+zYWcpNwVp9l5eepJnHqL4SdBi56CGlmw2Zn6aaiZjZqfb8Y2m+Cz1O0n3f+tnvrGbF6kToApCgAWoNWPeh754JA0vmajiAr4iOuOW7abQXVGNriBWoRdOK8FxNqLwX3oluubhv8yluRbegqGb536ykesuoXhyJqPQJIGbLvQhkcwjKs1zBvBwSZIsbcsDCCBAAf4ya+UEhyQoIiEJtfoZ7oxUOafE2BwgMWMqUydfC1LVtiArk0QtGkWEopzlqM9aJrKHfw5c6wKjFkmXDrbhwFockodtMGFLWpXy9JdiXN1ZDNszV4WSLQCGBKoQYHUyonqrHa4ErewAgMmcAAF7f2baIoVzC2p3gUvJtLcvIWqloy6/R04mIpLwDhciI8qLOB5yud44pHPLbA83hFDWPjNbuk9KnySN57Av+TMBvgEAgzzNhJb5K777rz37vvvVHRRxPDEF2/88cgnr/zyzDfv/PPQnxACACH5BAkKAAAALAAAAADcABMAAAX/ICCOZGmeaKqubOu+cCzPdG3feK7vfO//wKBwSAQIBoSkcslsOp/QqHRKrVqv2Kx2OhC0BIUCwcMpO84OT2HDbm8GHLQjnn6wE3g83SA3DB55G3llfHxnfnZ4gglvew6Gf4ySgmYGlpCJknochWiId3kJcZZyDn93i6KPl4eniopwq6SIoZKxhpenbhtHZRxhXisDopwPgHkGDxrLGgjLG8mC0gkFDwjX2AgJ0bXJ2djbgNJsAtbfCNB2oOnn6MmKbeXt226K1fMGi6j359D69ua+QZskjd+3cOvY9XNgp4ABCQNYEDBl7EIeCQkeMIDAseOCBwckiBSZ4ILGjh4B/40kaXIjSggMHmBcifHky5gYE6zM2OAlzGM6Z5rs+fIjTZ0tfcYMSlLCUJ8fL47kCVXmTjwPiKJkUCDnyqc3CxzQmYeAxAEGLGJYiwCDgAUT4sqdgOebArdw507IUNfuW71xdZ7DC5iuhGsKErf9CxhPYgUaEhPWyzfBMgUIJDPW6zhb5M1y+R5GjFkBaLmCM0dOfHqvztXYJnMejaFCBQlmVxAYsEGkYnQV4lqYMNyCtnYSggNekAC58uJxmTufW5w55mwKkg+nLp105uTC53a/nhg88fMTmDfDVl65Xum/IZt/3/zaag3a5W63nll1dvfiWbaaZLmpQIABCVQA2f9lAhTG112PQWYadXE9+FtmEwKWwQYQJrZagxomsOCAGVImInsSbpCBhhwug6KKcXXQQYUcYuDMggrASFmNzjjzzIrh7cUhhhHqONeGpSEW2QYxHsmjhxpgUGAKB16g4IIbMNCkXMlhaJ8GWVJo2I3NyKclYF1GxgyYDEAnXHJrMpNAm/rFBSczPiYAlwXF8ZnmesvoOdyMbx7m4o0S5LWdn4bex2Z4xYmEzaEb5EUcnxbA+WWglqIn6aHPTInCgVbdlZyMqMrIQHMRSiaBBakS1903p04w434n0loBoQFOt1yu2YAnY68RXiNsqh2s2qqxuyKb7Imtmgcrqsp6h8D/fMSpapldx55nwayK/SfqCQd2hcFdAgDp5GMvqhvakF4mZuS710WGIYy30khekRkMu92GNu6bo7r/ttjqwLaua5+HOdrKq5Cl3dcwi+xKiLBwwwom4b0E6xvuYyqOa8IAEghwQAV45VvovpkxBl2mo0W7AKbCZXoAhgMmWnOkEqx2JX5nUufbgJHpXCfMOGu2QAd8eitpW1eaNrNeMGN27mNz0swziYnpSbXN19gYtstzfXrdYjNHtAIYGFVwwAEvR1dfxdjKxVzAP0twAAW/ir2w3nzTd3W4yQWO3t0DfleB4XYnEHCEhffdKgaA29p0eo4fHLng9qoG+OVyXz0gMeWGY7qq3xhiRIEAwayNxBawxy777LTXbjsVXRSh++689+7778AHL/zwxBdv/PEnhAAAIfkECQoAAAAsAAAAANwAEwAABf8gII5kaZ5oqq5s675wLM90bd94ru987//AoHBIBAgGhKRyyWw6n9CodEqtWq/YrHY6ELQEhYLD4BlwHGg0ubBpuzdm9Dk9eCTu+MTZkDb4PXYbeIIcHHxqf4F3gnqGY2kOdQmCjHCGfpCSjHhmh2N+knmEkJmKg3uHfgaaeY2qn6t2i4t7sKAPbwIJD2VhXisDCQZgDrKDBQ8aGgjKyhvDlJMJyAjV1gjCunkP1NfVwpRtk93e2ZVt5NfCk27jD97f0LPP7/Dr4pTp1veLgvrx7AL+Q/BM25uBegoYkDCABYFhEobhkUBRwoMGEDJqXPDgQMUEFC9c1LjxQUUJICX/iMRIEgIDkycrjmzJMSXFlDNJvkwJsmdOjQwKfDz5M+PLoSGLQqgZU6XSoB/voHxawGbFlS2XGktAwKEADB0xiEWAodqGBRPSqp1wx5qCamDRrp2Qoa3bagLkzrULF4GCvHPTglRAmKxZvWsHayBcliDitHUlvGWM97FgCdYWVw4c2e/kw4HZJlCwmDBhwHPrjraGYTHqtaoxVKggoesKAgd2SX5rbUMFCxOAC8cGDwHFwBYWJCgu4XfwtcqZV0grPHj0u2SnqwU+IXph3rK5b1fOu7Bx5+K7L6/2/Xhg8uyXnQ8dvfRiDe7TwyfNuzlybKYpgIFtKhAgwEKkKcOf/wChZbBBgMucRh1so5XH3wbI1WXafRJy9iCErmX4IWHNaIAhZ6uxBxeGHXQA24P3yYfBBhmgSBozESpwongWOBhggn/N1aKG8a1YY2oVAklgCgQUUwGJ8iXAgItrWUARbwpqIOWEal0ZoYJbzmWlZCWSlsAC6VkwZonNbMAAl5cpg+NiZwpnJ0Xylegmlc+tWY1mjnGnZnB4QukMA9UJRxGOf5r4ppqDjjmnfKilh2ejGiyJAgF1XNmYbC2GmhZ5AcJVgajcXecNqM9Rx8B6bingnlotviqdkB3YCg+rtOaapFsUhSrsq6axJ6sEwoZK7I/HWpCsr57FBxJ1w8LqV/81zbkoXK3LfVeNpic0KRQG4NHoIW/XEmZuaiN6tti62/moWbk18uhjqerWS6GFpe2YVotskVssWfBOAHACrZHoWcGQwQhlvmsdXBZ/F9YLMF2jzUuYBP4a7CLCnoEHrgkDSCDAARUILAGaVVqAwQHR8pZXomm9/ONhgjrbgc2lyYxmpIRK9uSNjrXs8gEbTrYyl2ryTJmsLCdKkWzFQl1lWlOXGmifal6p9VnbQfpyY2SZyXKVV7JmZkMrgIFSyrIeUJ2r7YKnXdivUg1kAgdQ8B7IzJjGsd9zKSdwyBL03WpwDGxwuOASEP5vriO2F3nLjQdIrpaRDxqcBdgIHGA74pKrZXiR2ZWuZt49m+o3pKMC3p4Av7SNxBa456777rz37jsVXRQh/PDEF2/88cgnr/zyzDfv/PMnhAAAIfkECQoAAAAsAAAAANwAEwAABf8gII5kaZ5oqq5s675wLM90bd94ru987//AoHBIBAgGhKRyyWw6n9CodEqtWq/YrHY6ELQEhYLDUPAMHGi0weEpbN7wI8cxTzsGj4R+n+DUxwaBeBt7hH1/gYIPhox+Y3Z3iwmGk36BkIN8egOIl3h8hBuOkAaZhQlna4BrpnyWa4mleZOFjrGKcXoFA2ReKwMJBgISDw6abwUPGggazc0bBqG0G8kI1tcIwZp51djW2nC03d7BjG8J49jl4cgP3t/RetLp1+vT6O7v5fKhAvnk0UKFogeP3zmCCIoZkDCABQFhChQYuKBHgkUJkxpA2MhxQYEDFhNcvPBAI8eNCx7/gMQYckPJkxsZPLhIM8FLmDJrYiRp8mTKkCwT8IQJwSPQkENhpgQpEunNkzlpWkwKdSbGihKocowqVSvKWQkIOBSgQOYFDBgQpI0oYMGEt3AzTLKm4BqGtnDjirxW95vbvG/nWlub8G9euRsiqqWLF/AEkRoiprX2wLDeDQgkW9PQGLDgyNc665WguK8C0XAnRY6oGPUEuRLsgk5g+a3cCxUqSBC7gsCBBXcVq6swwULx4hayvctGPK8FCwsSLE9A3Hje6NOrHzeOnW695sffRi/9HfDz7sIVSNB+XXrmugo0rHcM3X388o6jr44ceb51uNjF1xcC8zk3wXiS8aYC/wESaLABBs7ch0ECjr2WAGvLsLZBeHqVFl9kGxooV0T81TVhBo6NiOEyJ4p4IYnNRBQiYCN6x4wCG3ZAY2If8jXjYRcyk2FmG/5nXAY8wqhWAii+1YGOSGLoY4VRfqiAgikwmIeS1gjAgHkWYLQZf9m49V9gDWYWY5nmTYCRM2TS5pxxb8IZGV5nhplmhJyZadxzbrpnZ2d/6rnZgHIid5xIMDaDgJfbLdrgMkKW+Rygz1kEZz1mehabkBpgiQIByVikwGTqVfDkk2/Vxxqiqur4X3fksHccre8xlxerDLiHjQIVUAgXr77yFeyuOvYqXGbMrbrqBMqaFpFFzhL7qv9i1FX7ZLR0LUNdcc4e6Cus263KbV+inkAAHhJg0BeITR6WmHcaxhvXg/AJiKO9R77ILF1FwmVdAu6WBu+ZFua72mkZWMfqBElKu0G8rFZ5n4ATp5jkmvsOq+Nj7u63ZMMPv4bveyYy6fDH+C6brgnACHBABQUrkGirz2FwAHnM4Mmhzq9yijOrOi/MKabH6VwBiYwZdukEQAvILKTWXVq0ZvH5/CfUM7M29Zetthp1eht0eqkFYw8IKXKA6mzXfTeH7fZg9zW0AhgY0TwthUa6Ch9dBeIsbsFrYkRBfgTfiG0FhwMWnbsoq3cABUYOnu/ejU/A6uNeT8u4wMb1WnBCyJJTLjjnr8o3OeJrUcpc5oCiPqAEkz8tXuLkPeDL3Uhs4fvvwAcv/PDEU9FFEcgnr/zyzDfv/PPQRy/99NRXf0IIACH5BAkKAAAALAAAAADcABMAAAX/ICCOZGmeaKqubOu+cCzPdG3feK7vfO//wKBwSAQIBoSkcslsOp/QqHRKrVqv2Kx2OhC0BIWCw/AoDziOtCHt8BQ28PjmzK57Hom8fo42+P8DeAkbeYQcfX9+gYOFg4d1bIGEjQmPbICClI9/YwaLjHAJdJeKmZOViGtpn3qOqZineoeJgG8CeWUbBV4rAwkGAhIVGL97hGACGsrKCAgbBoTRhLvN1c3PepnU1s2/oZO6AtzdBoPf4eMI3tIJyOnF0YwFD+nY8e3z7+Xfefnj9uz8cVsXCh89axgk7BrAggAwBQsYIChwQILFixIeNIDAseOCBwcSXMy2sSPHjxJE/6a0eEGjSY4MQGK86PIlypUJEmYsaTKmyJ8JW/Ls6HMkzaEn8YwMWtPkx4pGd76E4DMPRqFTY860OGhogwYagBFoKEABA46DEGBAoEBB0AUT4sqdIFKBNbcC4M6dkEEk22oYFOTdG9fvWrtsBxM23MytYL17666t9phwXwlum2lIDHmuSA2IGyuOLOHv38qLMbdFjHruZbWgRXeOe1nC2BUEDiyAMMHZuwoTLAQX3nvDOAUW5Vogru434d4JnAsnPmFB9NBshQXfa9104+Rxl8e13rZxN+CEydtVsFkd+vDjE7C/q52wOvb4s7+faz025frbxefWbSoQIAEDEUCwgf9j7bUlwHN9ZVaegxDK1xYzFMJH24L5saXABhlYxiEzHoKoIV8LYqAMaw9aZqFmJUK4YHuNfRjiXhmk+NcyJgaIolvM8BhiBx3IleN8lH1IWAcRgkZgCgYiaBGJojGgHHFTgtagAFYSZhF7/qnTpY+faVlNAnqJN0EHWa6ozAZjBtgmmBokwMB01LW5jAZwbqfmlNips4B4eOqJgDJ2+imXRZpthuigeC6XZTWIxilXmRo8iYKBCwiWmWkJVEAkfB0w8KI1IvlIpKnOkVpqdB5+h96o8d3lFnijrgprjbfGRSt0lH0nAZG5vsprWxYRW6Suq4UWqrLEsspWg8Io6yv/q6EhK0Fw0GLbjKYn5CZYBYht1laPrnEY67kyrhYbuyceiR28Pso7bYwiXjihjWsWuWF5p/H765HmNoiur3RJsGKNG/jq748XMrwmjhwCfO6QD9v7LQsDxPTAMKsFpthyJCdkmgYiw0VdXF/Om9dyv7YMWGXTLYpZg5wNR11C78oW3p8HSGgul4qyrJppgllJHJZHn0Y0yUwDXCXUNquFZNLKyYXBAVZvxtAKYIQEsmPgDacr0tltO1y/DMwYpkgUpJfTasLGzd3cdCN3gN3UWRcY3epIEPevfq+3njBxq/kqBoGBduvea8f393zICS63ivRBTqgFpgaWZEIUULdcK+frIfAAL2AjscXqrLfu+uuwx05FF0XUbvvtuOeu++689+7778AHL/wJIQAAOwAAAAAAAAAAAA==');
|
---|
383 |
|
---|
384 | spanIcon.appendChild(imageIcon);
|
---|
385 | spanIcon.appendChild(imageBusyIcon);
|
---|
386 | mainSpan.appendChild(spanIcon);
|
---|
387 | }
|
---|
388 |
|
---|
389 | var spanButton=document.createElement('span');
|
---|
390 | spanButton.setAttribute('class', 'yt-uix-button-content');
|
---|
391 | spanButton.setAttribute('style', 'opacity: 1.0; color: white')
|
---|
392 | spanButton.appendChild(document.createTextNode(buttonText+' '));
|
---|
393 | mainSpan.appendChild(spanButton);
|
---|
394 |
|
---|
395 | if (!newWatchPage) { // old UI
|
---|
396 | var imgButton=document.createElement('img');
|
---|
397 | imgButton.setAttribute('class', 'yt-uix-button-arrow');
|
---|
398 | imgButton.setAttribute('src', '//s.ytimg.com/yt/img/pixel-vfl3z5WfW.gif');
|
---|
399 | mainSpan.appendChild(imgButton);
|
---|
400 | }
|
---|
401 |
|
---|
402 | var listItems=document.createElement('ol');
|
---|
403 | listItems.setAttribute('style', 'display:none;');
|
---|
404 | listItems.setAttribute('class', 'yt-uix-button-menu');
|
---|
405 | for (var i=0;i<downloadCodeList.length;i++) {
|
---|
406 | var listItem=document.createElement('li');
|
---|
407 | var listLink=document.createElement('a');
|
---|
408 | listLink.setAttribute('style', 'text-decoration:none;');
|
---|
409 | listLink.setAttribute('href', downloadCodeList[i].url);
|
---|
410 | listLink.setAttribute('download', videoTitle+'.'+FORMAT_TYPE[downloadCodeList[i].format]);
|
---|
411 | var listButton=document.createElement('span');
|
---|
412 | listButton.setAttribute('class', 'yt-uix-button-menu-item');
|
---|
413 | listButton.setAttribute('loop', i+'');
|
---|
414 | listButton.setAttribute('id', LISTITEM_ID+downloadCodeList[i].format);
|
---|
415 | listButton.appendChild(document.createTextNode(downloadCodeList[i].label));
|
---|
416 | listLink.appendChild(listButton);
|
---|
417 | listItem.appendChild(listLink);
|
---|
418 | listItems.appendChild(listItem);
|
---|
419 | }
|
---|
420 | //mainSpan.appendChild(listItems); // ****
|
---|
421 | var buttonElement=document.createElement('button');
|
---|
422 | buttonElement.setAttribute('id', BUTTON_ID);
|
---|
423 | if (newWatchPage) {
|
---|
424 | buttonElement.setAttribute('class', 'yt-uix-button yt-uix-button-size-default yt-uix-button-opacity yt-uix-tooltip');
|
---|
425 | buttonElement.setAttribute('style', 'background-color:#6E00AF; opacity: 1.0;'); // ****
|
---|
426 | } else { // old UI
|
---|
427 | buttonElement.setAttribute('class', 'yt-uix-button yt-uix-tooltip yt-uix-button-empty yt-uix-button-text');
|
---|
428 | buttonElement.setAttribute('style', 'background-color:#6E00AF; opacity: 1.0; margin-top:4px; margin-left:'+((textDirection=='left')?5:10)+'px;'); // ****
|
---|
429 | }
|
---|
430 | buttonElement.setAttribute('data-tooltip-text', buttonLabel);
|
---|
431 | buttonElement.setAttribute('type', 'button');
|
---|
432 | buttonElement.setAttribute('role', 'button');
|
---|
433 | //buttonElement.addEventListener('click', function(){return false;}, false);
|
---|
434 | buttonElement.addEventListener("click", function() { console.log("*** videoURL = " + JSON.stringify(videoURL)); respoolme(videoURL['18']) }, false);
|
---|
435 |
|
---|
436 | buttonElement.appendChild(mainSpan);
|
---|
437 | var containerSpan=document.createElement('span');
|
---|
438 | containerSpan.setAttribute('id', CONTAINER_ID);
|
---|
439 | containerSpan.appendChild(document.createTextNode(' '));
|
---|
440 | containerSpan.appendChild(buttonElement);
|
---|
441 |
|
---|
442 | // add the button
|
---|
443 | if (!newWatchPage) { // watch7
|
---|
444 | parentElement.appendChild(containerSpan);
|
---|
445 | } else { // watch8
|
---|
446 | parentElement.insertBefore(containerSpan, parentElement.firstChild);
|
---|
447 | //document.getElementById("early-body").appendChild(containerSpan);
|
---|
448 |
|
---|
449 | }
|
---|
450 |
|
---|
451 | // REPLACEWITH if (!isSignatureUpdatingStarted) {
|
---|
452 | for (var i=0;i<downloadCodeList.length;i++) {
|
---|
453 | addFileSize(downloadCodeList[i].url, downloadCodeList[i].format);
|
---|
454 | }
|
---|
455 | // }
|
---|
456 |
|
---|
457 | if (typeof GM_download !== 'undefined') {
|
---|
458 | for (var i=0;i<downloadCodeList.length;i++) {
|
---|
459 | var downloadFMT=document.getElementById(LISTITEM_ID+downloadCodeList[i].format);
|
---|
460 | var url=(downloadCodeList[i].url).toLowerCase();
|
---|
461 | if (url.indexOf('clen=')>0 && url.indexOf('dur=')>0 && url.indexOf('gir=')>0
|
---|
462 | && url.indexOf('lmt=')>0) {
|
---|
463 | // supressed the YouTube downloader menu // ****
|
---|
464 | //downloadFMT.addEventListener('click', downloadVideoNatively, false);
|
---|
465 | }
|
---|
466 | }
|
---|
467 | }
|
---|
468 |
|
---|
469 | addFromManifest('140', '141'); // replace fmt140 with fmt141 if found in manifest
|
---|
470 |
|
---|
471 | function downloadVideoNatively(e) {
|
---|
472 | var elem=e.currentTarget;
|
---|
473 | e.returnValue=false;
|
---|
474 | if (e.preventDefault) {
|
---|
475 | e.preventDefault();
|
---|
476 | }
|
---|
477 | var loop=elem.getAttribute('loop');
|
---|
478 | if (loop) {
|
---|
479 | GM_download(downloadCodeList[loop].url, videoTitle+'.'+FORMAT_TYPE[downloadCodeList[loop].format]);
|
---|
480 | }
|
---|
481 | return false;
|
---|
482 | }
|
---|
483 |
|
---|
484 | function addFromManifest(oldFormat, newFormat) { // find newFormat URL in manifest
|
---|
485 | if (videoManifestURL && videoURL[newFormat]==undefined && SHOW_DASH_FORMATS && FORMAT_RULE['m4a']=='max') {
|
---|
486 | var matchSig=findMatch(videoManifestURL, /\/s\/([a-zA-Z0-9\.]+)\//i);
|
---|
487 | if (matchSig) {
|
---|
488 | var decryptedSig=decryptSignature(matchSig);
|
---|
489 | if (decryptedSig) {
|
---|
490 | videoManifestURL=videoManifestURL.replace('/s/'+matchSig+'/','/signature/'+decryptedSig+'/');
|
---|
491 | }
|
---|
492 | }
|
---|
493 | if (videoManifestURL.indexOf('//')==0) {
|
---|
494 | var protocol=(document.location.protocol=='http:')?'http:':'https:';
|
---|
495 | videoManifestURL=protocol+videoManifestURL;
|
---|
496 | }
|
---|
497 | debug('DYVAM - Info: manifestURL '+videoManifestURL);
|
---|
498 | crossXmlHttpRequest({
|
---|
499 | method:'GET',
|
---|
500 | url:videoManifestURL, // check if URL exists
|
---|
501 | onload:function(response) {
|
---|
502 | if (response.readyState === 4 && response.status === 200 && response.responseText) {
|
---|
503 | var regexp = new RegExp('<BaseURL.+>(http[^<]+itag='+newFormat+'[^<]+)<\\/BaseURL>','i');
|
---|
504 | var matchURL=findMatch(response.responseText, regexp);
|
---|
505 | debug('DYVAM - Info: matchURL '+matchURL);
|
---|
506 | if (!matchURL) return;
|
---|
507 | matchURL=matchURL.replace(/&\;/g,'&');
|
---|
508 | for (var i=0;i<downloadCodeList.length;i++) {
|
---|
509 | if (downloadCodeList[i].format==oldFormat) {
|
---|
510 | downloadCodeList[i].format==newFormat;
|
---|
511 | var downloadFMT=document.getElementById(LISTITEM_ID+oldFormat);
|
---|
512 | downloadFMT.setAttribute('id', LISTITEM_ID+newFormat);
|
---|
513 | downloadFMT.parentNode.setAttribute('href', matchURL);
|
---|
514 | downloadCodeList[i].url=matchURL;
|
---|
515 | downloadFMT.firstChild.nodeValue=FORMAT_LABEL[newFormat];
|
---|
516 | addFileSize(matchURL, newFormat);
|
---|
517 | }
|
---|
518 | }
|
---|
519 | }
|
---|
520 | }
|
---|
521 | });
|
---|
522 | }
|
---|
523 | }
|
---|
524 |
|
---|
525 | function injectStyle(code) {
|
---|
526 | var style=document.createElement('style');
|
---|
527 | style.type='text/css';
|
---|
528 | style.appendChild(document.createTextNode(code));
|
---|
529 | document.getElementsByTagName('head')[0].appendChild(style);
|
---|
530 | }
|
---|
531 |
|
---|
532 | function injectScript(code) {
|
---|
533 | var script=document.createElement('script');
|
---|
534 | script.type='application/javascript';
|
---|
535 | script.textContent=code;
|
---|
536 | document.body.appendChild(script);
|
---|
537 | document.body.removeChild(script);
|
---|
538 | }
|
---|
539 |
|
---|
540 | function debug(str) {
|
---|
541 | var debugElem=document.getElementById(DEBUG_ID);
|
---|
542 | if (!debugElem) {
|
---|
543 | debugElem=createHiddenElem('div', DEBUG_ID);
|
---|
544 | }
|
---|
545 | debugElem.appendChild(document.createTextNode(str+' '));
|
---|
546 | }
|
---|
547 |
|
---|
548 | function createHiddenElem(tag, id) {
|
---|
549 | var elem=document.createElement(tag);
|
---|
550 | elem.setAttribute('id', id);
|
---|
551 | elem.setAttribute('style', 'display:none;');
|
---|
552 | document.body.appendChild(elem);
|
---|
553 | return elem;
|
---|
554 | }
|
---|
555 |
|
---|
556 | function fixTranslations(language, textDirection) {
|
---|
557 | if (/^af|bg|bn|ca|cs|de|el|es|et|eu|fa|fi|fil|fr|gl|hi|hr|hu|id|it|iw|kn|lv|lt|ml|mr|ms|nl|pl|ro|ru|sl|sk|sr|sw|ta|te|th|uk|ur|vi|zu$/.test(language)) { // fix international UI
|
---|
558 | var likeButton=document.getElementById('watch-like');
|
---|
559 | if (likeButton) {
|
---|
560 | var spanElements=likeButton.getElementsByClassName('yt-uix-button-content');
|
---|
561 | if (spanElements) {
|
---|
562 | spanElements[0].style.display='none'; // hide like text
|
---|
563 | }
|
---|
564 | }
|
---|
565 | var marginPixels=10;
|
---|
566 | if (/^bg|ca|cs|el|eu|hr|it|ml|ms|pl|sl|sw|te$/.test(language)) {
|
---|
567 | marginPixels=1;
|
---|
568 | }
|
---|
569 | injectStyle('#watch7-secondary-actions .yt-uix-button{margin-'+textDirection+':'+marginPixels+'px!important}');
|
---|
570 | }
|
---|
571 | }
|
---|
572 |
|
---|
573 | function findMatch(text, regexp) {
|
---|
574 | var matches=text.match(regexp);
|
---|
575 | return (matches)?matches[1]:null;
|
---|
576 | }
|
---|
577 |
|
---|
578 | function isString(s) {
|
---|
579 | return (typeof s==='string' || s instanceof String);
|
---|
580 | }
|
---|
581 |
|
---|
582 | function isInteger(n) {
|
---|
583 | return (typeof n==='number' && n%1==0);
|
---|
584 | }
|
---|
585 |
|
---|
586 | function getPref(name) { // cross-browser GM_getValue
|
---|
587 | var a='', b='';
|
---|
588 | try {a=typeof GM_getValue.toString; b=GM_getValue.toString()} catch(e){}
|
---|
589 | if (typeof GM_getValue === 'function' &&
|
---|
590 | (a === 'undefined' || b.indexOf('not supported') === -1)) {
|
---|
591 | return GM_getValue(name, null); // Greasemonkey, Tampermonkey, Firefox extension
|
---|
592 | } else {
|
---|
593 | var ls=null;
|
---|
594 | try {ls=window.localStorage||null} catch(e){}
|
---|
595 | if (ls) {
|
---|
596 | return ls.getItem(name); // Chrome script, Opera extensions
|
---|
597 | }
|
---|
598 | }
|
---|
599 | return;
|
---|
600 | }
|
---|
601 |
|
---|
602 | function setPref(name, value) { // cross-browser GM_setValue
|
---|
603 | var a='', b='';
|
---|
604 | try {a=typeof GM_setValue.toString; b=GM_setValue.toString()} catch(e){}
|
---|
605 | if (typeof GM_setValue === 'function' &&
|
---|
606 | (a === 'undefined' || b.indexOf('not supported') === -1)) {
|
---|
607 | GM_setValue(name, value); // Greasemonkey, Tampermonkey, Firefox extension
|
---|
608 | } else {
|
---|
609 | var ls=null;
|
---|
610 | try {ls=window.localStorage||null} catch(e){}
|
---|
611 | if (ls) {
|
---|
612 | return ls.setItem(name, value); // Chrome script, Opera extensions
|
---|
613 | }
|
---|
614 | }
|
---|
615 | }
|
---|
616 |
|
---|
617 | function crossXmlHttpRequest(details) { // cross-browser GM_xmlhttpRequest
|
---|
618 | if (typeof GM_xmlhttpRequest === 'function') { // Greasemonkey, Tampermonkey, Firefox extension, Chrome script
|
---|
619 | GM_xmlhttpRequest(details);
|
---|
620 | } else if (typeof window.opera !== 'undefined' && window.opera && typeof opera.extension !== 'undefined' &&
|
---|
621 | typeof opera.extension.postMessage !== 'undefined') { // Opera 12 extension
|
---|
622 | var index=operaTable.length;
|
---|
623 | opera.extension.postMessage({'action':'xhr-'+index, 'url':details.url, 'method':details.method});
|
---|
624 | operaTable[index]=details;
|
---|
625 | } else if (typeof window.opera === 'undefined' && typeof XMLHttpRequest === 'function') { // Opera 15+ extension
|
---|
626 | var xhr=new XMLHttpRequest();
|
---|
627 | xhr.onreadystatechange = function() {
|
---|
628 | if (xhr.readyState == 4) {
|
---|
629 | if (details['onload']) {
|
---|
630 | details['onload'](xhr);
|
---|
631 | }
|
---|
632 | }
|
---|
633 | }
|
---|
634 | xhr.open(details.method, details.url, true);
|
---|
635 | xhr.send();
|
---|
636 | }
|
---|
637 | }
|
---|
638 |
|
---|
639 | function addFileSize(url, format) {
|
---|
640 |
|
---|
641 | function updateVideoLabel(size, format) {
|
---|
642 | var elem=document.getElementById(LISTITEM_ID+format);
|
---|
643 | if (elem) {
|
---|
644 | size=parseInt(size,10);
|
---|
645 | if (size>=1073741824) {
|
---|
646 | size=parseFloat((size/1073741824).toFixed(1))+' GB';
|
---|
647 | } else if (size>=1048576) {
|
---|
648 | size=parseFloat((size/1048576).toFixed(1))+' MB';
|
---|
649 | } else {
|
---|
650 | size=parseFloat((size/1024).toFixed(1))+' KB';
|
---|
651 | }
|
---|
652 | if (elem.childNodes.length>1) {
|
---|
653 | elem.lastChild.nodeValue=' ('+size+')';
|
---|
654 | } else if (elem.childNodes.length==1) {
|
---|
655 | elem.appendChild(document.createTextNode(' ('+size+')'));
|
---|
656 | }
|
---|
657 | }
|
---|
658 | }
|
---|
659 |
|
---|
660 | var matchSize=findMatch(url, /[&\?]clen=([0-9]+)&/i);
|
---|
661 | if (matchSize) {
|
---|
662 | updateVideoLabel(matchSize, format);
|
---|
663 | } else {
|
---|
664 | try {
|
---|
665 | crossXmlHttpRequest({
|
---|
666 | method:'HEAD',
|
---|
667 | url:url,
|
---|
668 | onload:function(response) {
|
---|
669 | if (response.readyState == 4 && response.status == 200) { // add size
|
---|
670 | var size=0;
|
---|
671 | if (typeof response.getResponseHeader === 'function') {
|
---|
672 | size=response.getResponseHeader('Content-length');
|
---|
673 | } else if (response.responseHeaders) {
|
---|
674 | var regexp = new RegExp('^Content\-length: (.*)$','im');
|
---|
675 | var match = regexp.exec(response.responseHeaders);
|
---|
676 | if (match) {
|
---|
677 | size=match[1];
|
---|
678 | }
|
---|
679 | }
|
---|
680 | if (size) {
|
---|
681 | updateVideoLabel(size, format);
|
---|
682 | }
|
---|
683 | }
|
---|
684 | }
|
---|
685 | });
|
---|
686 | } catch(e) { }
|
---|
687 | }
|
---|
688 | }
|
---|
689 |
|
---|
690 | function findSignatureCode(sourceCode) {
|
---|
691 | debug('DYVAM - Info: signature start '+getPref(STORAGE_CODE));
|
---|
692 | var signatureFunctionName =
|
---|
693 | findMatch(sourceCode,
|
---|
694 | /\.set\s*\("signature"\s*,\s*([a-zA-Z0-9_$][\w$]*)\(/)
|
---|
695 | || findMatch(sourceCode,
|
---|
696 | /\.sig\s*\|\|\s*([a-zA-Z0-9_$][\w$]*)\(/)
|
---|
697 | || findMatch(sourceCode,
|
---|
698 | /\.signature\s*=\s*([a-zA-Z_$][\w$]*)\([a-zA-Z_$][\w$]*\)/); //old
|
---|
699 | if (signatureFunctionName == null) return setPref(STORAGE_CODE, 'error');
|
---|
700 | signatureFunctionName=signatureFunctionName.replace('$','\\$');
|
---|
701 | var regCode = new RegExp('function \\s*' + signatureFunctionName +
|
---|
702 | '\\s*\\([\\w$]*\\)\\s*{[\\w$]*=[\\w$]*\\.split\\(""\\);(.+);return [\\w$]*\\.join');
|
---|
703 | var functionCode = findMatch(sourceCode, regCode);
|
---|
704 | debug('DYVAM - Info: signaturefunction ' + signatureFunctionName + ' -- ' + functionCode);
|
---|
705 | if (functionCode == null) return setPref(STORAGE_CODE, 'error');
|
---|
706 |
|
---|
707 | var reverseFunctionName = findMatch(sourceCode,
|
---|
708 | /([\w$]*)\s*:\s*function\s*\(\s*[\w$]*\s*\)\s*{\s*(?:return\s*)?[\w$]*\.reverse\s*\(\s*\)\s*}/);
|
---|
709 | debug('DYVAM - Info: reversefunction ' + reverseFunctionName);
|
---|
710 | if (reverseFunctionName) reverseFunctionName=reverseFunctionName.replace('$','\\$');
|
---|
711 | var sliceFunctionName = findMatch(sourceCode,
|
---|
712 | /([\w$]*)\s*:\s*function\s*\(\s*[\w$]*\s*,\s*[\w$]*\s*\)\s*{\s*(?:return\s*)?[\w$]*\.(?:slice|splice)\(.+\)\s*}/);
|
---|
713 | debug('DYVAM - Info: slicefunction ' + sliceFunctionName);
|
---|
714 | if (sliceFunctionName) sliceFunctionName=sliceFunctionName.replace('$','\\$');
|
---|
715 |
|
---|
716 | var regSlice = new RegExp('\\.(?:'+'slice'+(sliceFunctionName?'|'+sliceFunctionName:'')+
|
---|
717 | ')\\s*\\(\\s*(?:[a-zA-Z_$][\\w$]*\\s*,)?\\s*([0-9]+)\\s*\\)'); // .slice(5) sau .Hf(a,5)
|
---|
718 | var regReverse = new RegExp('\\.(?:'+'reverse'+(reverseFunctionName?'|'+reverseFunctionName:'')+
|
---|
719 | ')\\s*\\([^\\)]*\\)'); // .reverse() sau .Gf(a,45)
|
---|
720 | var regSwap = new RegExp('[\\w$]+\\s*\\(\\s*[\\w$]+\\s*,\\s*([0-9]+)\\s*\\)');
|
---|
721 | var regInline = new RegExp('[\\w$]+\\[0\\]\\s*=\\s*[\\w$]+\\[([0-9]+)\\s*%\\s*[\\w$]+\\.length\\]');
|
---|
722 | var functionCodePieces=functionCode.split(';');
|
---|
723 | var decodeArray=[];
|
---|
724 | for (var i=0; i<functionCodePieces.length; i++) {
|
---|
725 | functionCodePieces[i]=functionCodePieces[i].trim();
|
---|
726 | var codeLine=functionCodePieces[i];
|
---|
727 | if (codeLine.length>0) {
|
---|
728 | var arrSlice=codeLine.match(regSlice);
|
---|
729 | var arrReverse=codeLine.match(regReverse);
|
---|
730 | debug(i+': '+codeLine+' --'+(arrSlice?' slice length '+arrSlice.length:'') +' '+(arrReverse?'reverse':''));
|
---|
731 | if (arrSlice && arrSlice.length >= 2) { // slice
|
---|
732 | var slice=parseInt(arrSlice[1], 10);
|
---|
733 | if (isInteger(slice)){
|
---|
734 | decodeArray.push(-slice);
|
---|
735 | } else return setPref(STORAGE_CODE, 'error');
|
---|
736 | } else if (arrReverse && arrReverse.length >= 1) { // reverse
|
---|
737 | decodeArray.push(0);
|
---|
738 | } else if (codeLine.indexOf('[0]') >= 0) { // inline swap
|
---|
739 | if (i+2<functionCodePieces.length &&
|
---|
740 | functionCodePieces[i+1].indexOf('.length') >= 0 &&
|
---|
741 | functionCodePieces[i+1].indexOf('[0]') >= 0) {
|
---|
742 | var inline=findMatch(functionCodePieces[i+1], regInline);
|
---|
743 | inline=parseInt(inline, 10);
|
---|
744 | decodeArray.push(inline);
|
---|
745 | i+=2;
|
---|
746 | } else return setPref(STORAGE_CODE, 'error');
|
---|
747 | } else if (codeLine.indexOf(',') >= 0) { // swap
|
---|
748 | var swap=findMatch(codeLine, regSwap);
|
---|
749 | swap=parseInt(swap, 10);
|
---|
750 | if (isInteger(swap) && swap>0){
|
---|
751 | decodeArray.push(swap);
|
---|
752 | } else return setPref(STORAGE_CODE, 'error');
|
---|
753 | } else return setPref(STORAGE_CODE, 'error');
|
---|
754 | }
|
---|
755 | }
|
---|
756 |
|
---|
757 | if (decodeArray) {
|
---|
758 | setPref(STORAGE_URL, scriptURL);
|
---|
759 | setPref(STORAGE_CODE, decodeArray.toString());
|
---|
760 | DECODE_RULE=decodeArray;
|
---|
761 | debug('DYVAM - Info: signature '+decodeArray.toString()+' '+scriptURL);
|
---|
762 | // update download links and add file sizes
|
---|
763 | for (var i=0;i<downloadCodeList.length;i++) {
|
---|
764 | var elem=document.getElementById(LISTITEM_ID+downloadCodeList[i].format);
|
---|
765 | var url=downloadCodeList[i].url;
|
---|
766 | var sig=downloadCodeList[i].sig;
|
---|
767 | if (elem && url && sig) {
|
---|
768 | url=url.replace(/\&signature=[\w\.]+/, '&signature='+decryptSignature(sig));
|
---|
769 | elem.parentNode.setAttribute('href', url);
|
---|
770 | addFileSize(url, downloadCodeList[i].format);
|
---|
771 | }
|
---|
772 | }
|
---|
773 | }
|
---|
774 | }
|
---|
775 |
|
---|
776 | function isValidSignatureCode(arr) { // valid values: '5,-3,0,2,5', 'error'
|
---|
777 | if (!arr) return false;
|
---|
778 | if (arr=='error') return true;
|
---|
779 | arr=arr.split(',');
|
---|
780 | for (var i=0;i<arr.length;i++) {
|
---|
781 | if (!isInteger(parseInt(arr[i],10))) return false;
|
---|
782 | }
|
---|
783 | return true;
|
---|
784 | }
|
---|
785 |
|
---|
786 | function fetchSignatureScript(scriptURL) {
|
---|
787 | var storageURL=getPref(STORAGE_URL);
|
---|
788 | var storageCode=getPref(STORAGE_CODE);
|
---|
789 | if (!(/,0,|^0,|,0$|\-/.test(storageCode))) storageCode=null; // hack for only positive items
|
---|
790 | if (storageCode && isValidSignatureCode(storageCode) && storageURL &&
|
---|
791 | scriptURL.replace(/^https?/i,'')==storageURL.replace(/^https?/i,'')) return;
|
---|
792 | try {
|
---|
793 | debug('DYVAM fetch '+scriptURL);
|
---|
794 | isSignatureUpdatingStarted=true;
|
---|
795 | crossXmlHttpRequest({
|
---|
796 | method:'GET',
|
---|
797 | url:scriptURL,
|
---|
798 | onload:function(response) {
|
---|
799 | debug('DYVAM fetch status '+response.status);
|
---|
800 | if (response.readyState === 4 && response.status === 200 && response.responseText) {
|
---|
801 | findSignatureCode(response.responseText);
|
---|
802 | }
|
---|
803 | }
|
---|
804 | });
|
---|
805 | } catch(e) { }
|
---|
806 | }
|
---|
807 |
|
---|
808 | function getDecodeRules(rules) {
|
---|
809 | var storageCode=getPref(STORAGE_CODE);
|
---|
810 | if (storageCode && storageCode!='error' && isValidSignatureCode(storageCode)) {
|
---|
811 | var arr=storageCode.split(',');
|
---|
812 | for (var i=0; i<arr.length; i++) {
|
---|
813 | arr[i]=parseInt(arr[i], 10);
|
---|
814 | }
|
---|
815 | rules=arr;
|
---|
816 | debug('DYVAM - Info: signature '+arr.toString()+' '+scriptURL);
|
---|
817 | }
|
---|
818 | return rules;
|
---|
819 | }
|
---|
820 |
|
---|
821 | function decryptSignature(sig) {
|
---|
822 | function swap(a,b){var c=a[0];a[0]=a[b%a.length];a[b]=c;return a};
|
---|
823 | function decode(sig, arr) { // encoded decryption
|
---|
824 | if (!isString(sig)) return null;
|
---|
825 | var sigA=sig.split('');
|
---|
826 | for (var i=0;i<arr.length;i++) {
|
---|
827 | var act=arr[i];
|
---|
828 | if (!isInteger(act)) return null;
|
---|
829 | sigA=(act>0)?swap(sigA, act):((act==0)?sigA.reverse():sigA.slice(-act));
|
---|
830 | }
|
---|
831 | var result=sigA.join('');
|
---|
832 | return result;
|
---|
833 | }
|
---|
834 |
|
---|
835 | if (sig==null) return '';
|
---|
836 | var arr=DECODE_RULE;
|
---|
837 | if (arr) {
|
---|
838 | var sig2=decode(sig, arr);
|
---|
839 | if (sig2) return sig2;
|
---|
840 | } else {
|
---|
841 | setPref(STORAGE_URL, '');
|
---|
842 | setPref(STORAGE_CODE, '');
|
---|
843 | }
|
---|
844 | return sig;
|
---|
845 | }
|
---|
846 |
|
---|
847 | }
|
---|
848 |
|
---|
849 | })();
|
---|
850 |
|
---|