본문 바로가기

카테고리 없음

Download Youtube Videos As Mp4 Gantt

Download youtube videos as mp4 gantt free

Download YouTube MP4 Downloader for Firefox. View and Download YouTube videos in raw MP4 format. Get notifications about available videos and formats. // ==UserScript== // @name Download YouTube Videos as MP4 // @description Adds a button that lets you download YouTube videos. // @homepageURL https://github.com. Sep 22, 2017 - Yesterday I tried to use 'Download YouTube videos as mp4' extension by only to find it wasn't. Download32 is source for free xnxx videos downloader shareware, freeware download - free music videos finder, SHAREAZA, WinX Free AVI to MP4 Converter, WinX Video Converter, Meditation Videos - Relaxation, etc. Freeware Keywords: Convert Video To Iphone Xs Free - Free Audio Converter - Free Download Youtube Videos - Free Mkv Converter.

Free Youtube To Mp4 Download

Download youtube videos as mp4 firefox gantt

Download Free Youtube Videos Mp4

  1. // @name Download YouTube Videos as MP4
  2. // @description Adds a button that lets you download YouTube videos.
  3. // @homepageURL https://github.com/gantt/downloadyoutube
  4. // @version 1.8.8
  5. // @namespace http://googlesystem.blogspot.com
  6. // @include https://www.youtube.com/*
  7. // @exclude https://www.youtube.com/embed/*
  8. // @match https://www.youtube.com/*
  9. // @match http://s.ytimg.com/yts/jsbin/html5player*
  10. // @match https://s.ytimg.com/yts/jsbin/html5player*
  11. // @match https://manifest.googlevideo.com/*
  12. // @match https://*.googlevideo.com/videoplayback*
  13. // @match https://*.youtube.com/videoplayback*
  14. // @connect ytimg.com
  15. // @grant GM_getValue
  16. // @run-at document-end
  17. // @icon data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAEAAAABACAMAAACdt4HsAAAAB3RJTUUH2wMOCgIoGUYEAQAAAAlwSFlzAAALEgAACxIB0t1+/AAAAARnQU1BAACxjwv8YQUAAAGSUExURfi/JO/v797e3sbGxq2traWlpZSUlJycnNbW1oyEhIRaWow5OZQhIZwYGKUQEKUICK0ICJQxMYxKSoxzc4x7e4RCQpQYGKUAAK0AALUAAL0AAK0QEIxra5QpKa0YGIxSUsYAAKUhIZR7e87Ozr0ICJRSUr29vYxjY6U5OaUpKa0hIb21tZwAALUICO/Ozu/GxqUxMZSEhLUYGO/W1r0YGKVCQpQQEL0pKffe3vfW1pxra5Q5OcZCQvfn585CQr2trZx7e8ZSUs5SUq05Oc5jY9ZjY84AAKWMjM5zc957e60pKdaMjOelpbWcnLWUlLVCQsYYGMYICNbOzpQICMYhIbV7e5xaWt6cnPfv79bGxt6lpe+9vc5KSs6lpb0xMc6EhM69vbUxMbUhIb1aWs61tcZaWuecnMYxMb1KSsZjY96UlNa1td7W1r17e9a9vZwQEN6trb1jY8YQENZra+fOzr1zc85aWufe3t6MjMY5OdZaWt61tdZ7e+/n5+e9vc6MjMZra+/e3ue1tdalpd7GxrUpKalL4aAAAAABdFJOUwBA5thmAAACxklEQVR42uXX/1/SQBgH8NuAoEQ2ijgbBivJLznBAiUUKiyJSgOVAk0tKZKw75mRRt/7v4MBY8ezjW39Vs8v8rqHz/u1jbvbidC/XL8KmcpOqVT6nSjXjooGw8WfFd+QWGfE4oLbtbr++PdMOy0BDYLjEj/0xevfWIyVAI7b/aIj/9WHsRrA8Yf9bqSexVgD4Lic9kWE/LgPwPGfNfJHDO4P8Iuq+S2M9QD8oUp+nxEAcFCtfgIA/14x/9ElAKDQbNQAwN9VAiYEABy0OgsAWAnB/AcBAtVWawkAfJ4CD0BQADZavYcQgI9h3CCQjpD5PcEgwG+SwLRhIL0vz78SjAPEU3hrHODfyX4I6rUJIP0G3oExoNwFXpoB+HwXmDEFpF9IwKA5YK+Tp9fMAdUOsC6YA553gKcmgdTfAhV1oMQqADndQDmJ0AZLAsFnCIV3VYDHJLAjDkZKciAaFz/lCeBJB1glgXBrNLndBWLJ9uZGAI+keTBLANL8SnWAzWRniAC2pG+6lQF0hfjTqCIBrEvjDwiggFSLuIUoLY0vEwAbUcsnc/LlnO02HGvEz+hXEeJ5Yj+4L2vNkxOJDSnlQzliIq2synr3embiUBjmw0FyU83KX04Ob+9aAK/Ppd5deZloz4HFlCHzt3sX0x2a6LcvQb4ab8r7i+DVdqvnCq/D5ZzqdhfAcr5B9wD0PNwPEu0ZnLwK9oPgNfCQJ2fhhhITJ3E8BjeUOXA+QNQlBh5xLjemVCgKjzgzNIJFjWF4yJoKhafgIWt6VHGmjgR0HvMuTipPdWQJ6AImbBRSE8aY/sC4er5xFx5vHyB4YRRpFWUf0AL4c+dHkHZRFo9TDeB9Aa3Llwjr8FlFwB+wO/rHm0VbPae9mPini/O5h/XGxatw2I6fGHAOuhiGZVxO98lTdgutP94yaIvVdqxZdpvFYTT9X9UfqQQlTXlm8wkAAAAASUVORK5CYII=
  18. (function () {
  19. var FORMAT_LABEL={'18':'MP4 360p','22':'MP4 720p','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','140':'M4A 128kbps - audio','264':'MP4 1440p - no audio','266':'MP4 2160p - no audio','298':'MP4 720p60 - no audio','299':'MP4 1080p60 - no audio'};
  20. var FORMAT_TYPE={'18':'mp4','22':'mp4','43':'webm','44':'webm','45':'webm','46':'webm','135':'mp4','137':'mp4','138':'mp4','140':'m4a','264':'mp4','266':'mp4','298':'mp4','299':'mp4'};
  21. var FORMAT_ORDER=['18','43','135','44','22','298','45','137','299','46','264','138','266','140'];
  22. var FORMAT_RULE={'mp4':'all','webm':'none','m4a':'all'};
  23. // all=display all versions, max=only highest quality version, none=no version
  24. var SHOW_DASH_FORMATS=false;
  25. var BUTTON_TEXT={'ar':'تنزيل','cs':'Stáhnout','de':'Herunterladen','en':'Download','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':'下載'};
  26. var BUTTON_TOOLTIP={'ar':'تنزيل هذا الفيديو','cs':'Stáhnout toto video','de':'Dieses Video herunterladen','en':'Download this video','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':'下載此影片'};
  27. var RANDOM=7489235179; // Math.floor(Math.random()*1234567890);
  28. var CONTAINER_ID='download-youtube-video'+RANDOM;
  29. var LISTITEM_ID='download-youtube-video-fmt'+RANDOM;
  30. var BUTTON_ID='download-youtube-video-button'+RANDOM;
  31. var DEBUG_ID='download-youtube-video-debug-info';
  32. var STORAGE_CODE='download-youtube-signature-code';
  33. var STORAGE_DASH='download-youtube-dash-enabled';
  34. var pagecontainer=document.getElementById('page-container');
  35. if (/^https?://www.youtube.com/watch?/.test(window.location.href)) run();
  36. var isAjax=/class[ws'-=]+spf-link/.test(pagecontainer.innerHTML);
  37. var logocontainer=document.getElementById('logo-container');
  38. if (logocontainer && !isAjax) { // fix for blocked videos
  39. isAjax=(' '+logocontainer.className+' ').indexOf(' spf-link ')>=0;
  40. var content=document.getElementById('content');
  41. var mo=window.MutationObserver||window.WebKitMutationObserver;
  42. var observer=new mo(function(mutations) {
  43. if(mutation.addedNodes!null) {
  44. for (var i=0; i<mutation.addedNodes.length; i++) {
  45. if (mutation.addedNodes[i].id'watch7-container' ||
  46. mutation.addedNodes[i].id'watch7-main-container') { // old value: movie_player
  47. break;
  48. }
  49. });
  50. observer.observe(content, {childList: true, subtree: true}); // old value: pagecontainer
  51. } else { // MutationObserver fallback for old browsers
  52. pagecontainer.addEventListener('DOMNodeInserted', onNodeInserted, false);
  53. }
  54. if (e && e.target && (e.target.id'watch7-container' ||
  55. e.target.id'watch7-main-container')) { // old value: movie_player
  56. }
  57. if (document.getElementById(CONTAINER_ID)) return; // check download container
  58. if (document.getElementById('p') && document.getElementById('vo')) return; // Feather not supported
  59. var videoID, videoFormats, videoAdaptFormats, videoManifestURL, scriptURL=null;
  60. var operaTable=new Array();
  61. var language=document.documentElement.getAttribute('lang');
  62. if (document.body.getAttribute('dir')'rtl') {
  63. }
  64. if (document.getElementById('watch7-action-buttons')) { // old UI
  65. }
  66. // obtain video ID, formats map
  67. var args=null;
  68. var usw=(typeof this.unsafeWindow ! 'undefined')?this.unsafeWindow:window; // Firefox, Opera<15
  69. if (usw.ytplayer && usw.ytplayer.config && usw.ytplayer.config.args) {
  70. }
  71. videoID=args['video_id'];
  72. videoAdaptFormats=args['adaptive_fmts'];
  73. debug('DYVAM - Info: Standard mode. videoID '+(videoID?videoID:'none')+'; ');
  74. if (usw.ytplayer && usw.ytplayer.config && usw.ytplayer.config.assets) {
  75. }
  76. if (videoIDnull) { // unsafeWindow workaround (Chrome, Opera 15+)
  77. var buffer=document.getElementById(DEBUG_ID+'2');
  78. while (buffer.firstChild) {
  79. }
  80. buffer=createHiddenElem('pre', DEBUG_ID+'2');
  81. injectScript ('if(ytplayer&&ytplayer.config&&ytplayer.config.args){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+''));}');
  82. if (code) {
  83. videoID=findMatch(code, /'video_id':s*'([^']+)'/);
  84. videoFormats=findMatch(code, /'url_encoded_fmt_stream_map':s*'([^']+)'/);
  85. videoFormats=videoFormats.replace(/&amp;/g,'u0026');
  86. videoAdaptFormats=findMatch(code, /'adaptive_fmts':s*'([^']+)'/);
  87. videoAdaptFormats=videoAdaptFormats.replace(/&amp;/g,'u0026');
  88. videoManifestURL=findMatch(code, /'dashmpd':s*'([^']+)'/);
  89. scriptURL=findMatch(code, /'js':s*'([^']+)'/);
  90. debug('DYVAM - Info: Injection mode. videoID '+(videoID?videoID:'none')+'; ');
  91. var bodyContent=document.body.innerHTML;
  92. videoID=findMatch(bodyContent, /'video_id':s*'([^']+)'/);
  93. videoFormats=findMatch(bodyContent, /'url_encoded_fmt_stream_map':s*'([^']+)'/);
  94. videoAdaptFormats=findMatch(bodyContent, /'adaptive_fmts':s*'([^']+)'/);
  95. videoManifestURL=findMatch(bodyContent, /'dashmpd':s*'([^']+)'/);
  96. scriptURL=findMatch(bodyContent, /'js':s*'([^']+)'/);
  97. scriptURL=scriptURL.replace(//g,');
  98. }
  99. debug('DYVAM - Info: Brute mode. videoID '+(videoID?videoID:'none')+'; ');
  100. debug('DYVAM - Info: url '+window.location.href+'; useragent '+window.navigator.userAgent);
  101. if (videoIDnull || videoFormatsnull || videoID.length0 || videoFormats.length0) {
  102. debug('DYVAM - Error: No config information found. YouTube must have changed the code.');
  103. }
  104. // Opera 12 extension message handler
  105. if (typeof window.opera ! 'undefined' && window.opera && typeof opera.extension ! 'undefined') {
  106. var index=findMatch(event.data.action, /xhr-([0-9]+)-response/);
  107. index=parseInt(index,10);
  108. if (typeof trigger 'function' && event.data.readyState 4) {
  109. trigger(event.data);
  110. }
  111. }
  112. DECODE_RULE=getDecodeRules(DECODE_RULE);
  113. }
  114. if (scriptURL.indexOf('//')0) {
  115. var protocol=(document.location.protocol'http:')?'http:':'https:';
  116. }
  117. }
  118. // video title
  119. videoTitle=videoTitle.replace(/s*-s*YouTube$/i, ').replace(/'/g, '').replace(/^s+|s+$/g, ').replace(/.+$/g, ');
  120. videoTitle=videoTitle.replace(/[:'?*]/g, ').replace(/[|/]/g, '_'); // Mac, Linux, Windows
  121. if (((window.navigator.userAgent || ').toLowerCase()).indexOf('windows') >= 0) {
  122. videoTitle=videoTitle.replace(/#/g, ').replace(/&/g, '_'); // Windows
  123. videoTitle=videoTitle.replace(/#/g, '%23').replace(/&/g, '%26'); // Mac, Linux
  124. var sep1='%2C', sep2='%26', sep3='%3D';
  125. sep1=',';
  126. sep2=(videoFormats.indexOf('&')>-1)?'&':'u0026';
  127. }
  128. var videoSignature=new Array();
  129. videoFormats=videoFormats+sep1+videoAdaptFormats;
  130. var videoFormatsGroup=videoFormats.split(sep1);
  131. var videoFormatsElem=videoFormatsGroup[i].split(sep2);
  132. for (var j=0;j<videoFormatsElem.length;j++) {
  133. if (pair.length2) {
  134. }
  135. if (videoFormatsPair['url']null) continue;
  136. var url=unescape(unescape(videoFormatsPair['url'])).replace(///g,'/').replace(/u0026/g,'&');
  137. var itag=videoFormatsPair['itag'];
  138. var sig=videoFormatsPair['sig']||videoFormatsPair['signature'];
  139. url=url+'&signature='+sig;
  140. } else if (videoFormatsPair['s']) {
  141. url=url+'&signature='+decryptSignature(videoFormatsPair['s']);
  142. }
  143. if (url.toLowerCase().indexOf('ratebypass')-1) { // speed up download for dash
  144. }
  145. if (url.toLowerCase().indexOf('http')0) { // validate URL
  146. }
  147. for (var category in FORMAT_RULE) {
  148. for (var index in FORMAT_TYPE){
  149. showFormat[index]=(rule'all');
  150. }
  151. for (var i=FORMAT_ORDER.length-1;i>=0;i--) {
  152. if (FORMAT_TYPE[format]category && videoURL[format]!=undefined) {
  153. break;
  154. }
  155. }
  156. var dashPref=getPref(STORAGE_DASH);
  157. SHOW_DASH_FORMATS=true;
  158. setPref(STORAGE_DASH,'0');
  159. for (var i=0;i<FORMAT_ORDER.length;i++) {
  160. if (format'37' && videoURL[format]undefined) { // hack for dash 1080p
  161. format='137';
  162. showFormat[format]=showFormat['37'];
  163. } else if (format'38' && videoURL[format]undefined) { // hack for dash 4K
  164. format='138';
  165. showFormat[format]=showFormat['38'];
  166. if (!SHOW_DASH_FORMATS && format.length>2) continue;
  167. if (videoURL[format]!=undefined && FORMAT_LABEL[format]!=undefined && showFormat[format]) {
  168. downloadCodeList.push({url:videoURL[format],sig:videoSignature[format],format:format,label:FORMAT_LABEL[format]});
  169. debug('DYVAM - Info: itag'+format+' url:'+videoURL[format]);
  170. }
  171. if (downloadCodeList.length0) {
  172. debug('DYVAM - Error: No download URL found. Probably YouTube uses encrypted streams.');
  173. }
  174. // find parent container
  175. var parentElement=document.getElementById('watch7-action-buttons');
  176. parentElement=document.getElementById('watch8-secondary-actions');
  177. debug('DYVAM Error - No container for adding the download button. YouTube must have changed the code.');
  178. } else {
  179. }
  180. var buttonText=(BUTTON_TEXT[language])?BUTTON_TEXT[language]:BUTTON_TEXT['en'];
  181. var buttonLabel=(BUTTON_TOOLTIP[language])?BUTTON_TOOLTIP[language]:BUTTON_TOOLTIP['en'];
  182. // generate download code for regular interface
  183. var spanIcon=document.createElement('span');
  184. spanIcon.setAttribute('class', 'yt-uix-button-icon-wrapper');
  185. imageIcon.setAttribute('src', '//s.ytimg.com/yt/img/pixel-vfl3z5WfW.gif');
  186. imageIcon.setAttribute('class', 'yt-uix-button-icon');
  187. 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);');
  188. mainSpan.appendChild(spanIcon);
  189. spanButton.setAttribute('class', 'yt-uix-button-content');
  190. spanButton.appendChild(document.createTextNode(buttonText+' '));
  191. var imgButton=document.createElement('img');
  192. imgButton.setAttribute('class', 'yt-uix-button-arrow');
  193. imgButton.setAttribute('src', '//s.ytimg.com/yt/img/pixel-vfl3z5WfW.gif');
  194. }
  195. var listItems=document.createElement('ol');
  196. listItems.setAttribute('style', 'display:none;');
  197. listItems.setAttribute('class', 'yt-uix-button-menu');
  198. var listItem=document.createElement('li');
  199. listLink.setAttribute('style', 'text-decoration:none;');
  200. listLink.setAttribute('href', downloadCodeList[i].url);
  201. listLink.setAttribute('download', videoTitle+'.'+FORMAT_TYPE[downloadCodeList[i].format]);
  202. listButton.setAttribute('class', 'yt-uix-button-menu-item');
  203. listButton.setAttribute('id', LISTITEM_ID+downloadCodeList[i].format);
  204. listButton.appendChild(document.createTextNode(downloadCodeList[i].label));
  205. listItem.appendChild(listLink);
  206. }
  207. var buttonElement=document.createElement('button');
  208. if (newWatchPage) {
  209. buttonElement.setAttribute('class', 'yt-uix-button yt-uix-button-size-default yt-uix-button-opacity yt-uix-tooltip');
  210. buttonElement.setAttribute('class', 'yt-uix-button yt-uix-tooltip yt-uix-button-empty yt-uix-button-text');
  211. buttonElement.setAttribute('style', 'margin-top:4px; margin-left:'+((textDirection'left')?5:10)+'px;');
  212. buttonElement.setAttribute('data-tooltip-text', buttonLabel);
  213. buttonElement.setAttribute('role', 'button');
  214. buttonElement.addEventListener('click', function(){return false;}, false);
  215. var containerSpan=document.createElement('span');
  216. containerSpan.appendChild(document.createTextNode(' '));
  217. if (!newWatchPage) { // watch7
  218. } else { // watch8
  219. parentElement.insertBefore(containerSpan, parentElement.firstChild);
  220. // REPLACEWITH if (!isSignatureUpdatingStarted) {
  221. addFileSize(downloadCodeList[i].url, downloadCodeList[i].format);
  222. // }
  223. if (typeof GM_download ! 'undefined') {
  224. var downloadFMT=document.getElementById(LISTITEM_ID+downloadCodeList[i].format);
  225. if (url.indexOf('clen=')>0 && url.indexOf('dur=')>0 && url.indexOf('gir=')>0
  226. downloadFMT.addEventListener('click', downloadVideoNatively, false);
  227. }
  228. var elem=e.currentTarget;
  229. if (e.preventDefault) {
  230. }
  231. if (loop) {
  232. GM_download(downloadCodeList[loop].url, videoTitle+'.'+FORMAT_TYPE[downloadCodeList[loop].format]);
  233. return false;
  234. function addFromManifest() { // add Dash URLs from manifest file
  235. var formats=['137', '138', '140']; // 137=1080p, 138=4k, 140=m4a
  236. for (var i=0;i<formats.length;i++) {
  237. isNecessary=false;
  238. }
  239. if (videoManifestURL && SHOW_DASH_FORMATS && isNecessary) {
  240. var matchSig=findMatch(videoManifestURL, //s/([a-zA-Z0-9.]+)//i);
  241. var decryptedSig=decryptSignature(matchSig);
  242. videoManifestURL=videoManifestURL.replace('/s/'+matchSig+'/','/signature/'+decryptedSig+'/');
  243. }
  244. var protocol=(document.location.protocol'http:')?'http:':'https:';
  245. }
  246. debug('DYVAM - Info: manifestURL '+videoManifestURL);
  247. method:'GET',
  248. onload:function(response) {
  249. if (response.readyState 4 && response.status 200 && response.responseText) {
  250. debug('DYVAM - Info: maniestFileContents '+response.responseText);
  251. var lastFormatFromList=downloadCodeList[downloadCodeList.length-1].format;
  252. debug('DYVAM - Info: lastformat: '+lastFormatFromList);
  253. k=formats[i];
  254. if (videoURL[k] || showFormat[k]false) continue;
  255. var regexp = new RegExp('<BaseURL>(http[^<]+itag/'+k+'[^<]+)</BaseURL>','i');
  256. var matchURL=findMatch(response.responseText, regexp);
  257. debug('DYVAM - Info: matchURL itag= '+k+' url= '+matchURL);
  258. matchURL=matchURL.replace(/&amp;/g,'&');
  259. downloadCodeList.push(
  260. {url:matchURL,sig:videoSignature[k],format:k,label:FORMAT_LABEL[k]});
  261. var downloadFMT=document.getElementById(LISTITEM_ID+lastFormatFromList);
  262. var clone=downloadFMT.parentNode.parentNode.cloneNode(true);
  263. clone.firstChild.firstChild.setAttribute('id', LISTITEM_ID+k);
  264. downloadFMT.parentNode.parentNode.parentNode.appendChild(clone);
  265. downloadFMT=document.getElementById(LISTITEM_ID+k);
  266. downloadFMT.firstChild.nodeValue=FORMAT_LABEL[k];
  267. lastFormatFromList=k;
  268. }
  269. });
  270. }
  271. function injectStyle(code) {
  272. style.type='text/css';
  273. style.appendChild(document.createTextNode(code));
  274. document.getElementsByTagName('head')[0].appendChild(style);
  275. var script=document.createElement('script');
  276. script.textContent=code;
  277. document.body.removeChild(script);
  278. var debugElem=document.getElementById(DEBUG_ID);
  279. debugElem=createHiddenElem('div', DEBUG_ID);
  280. debugElem.appendChild(document.createTextNode(str+' '));
  281. var elem=document.createElement(tag);
  282. elem.setAttribute('style', 'display:none;');
  283. return elem;
  284. function fixTranslations(language, textDirection) {
  285. 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
  286. var likeButton=document.getElementById('watch-like');
  287. var spanElements=likeButton.getElementsByClassName('yt-uix-button-content');
  288. spanElements[0].style.display='none'; // hide like text
  289. }
  290. if (/^bg|ca|cs|el|eu|hr|it|ml|ms|pl|sl|sw|te$/.test(language)) {
  291. }
  292. injectStyle('#watch7-secondary-actions .yt-uix-button{margin-'+textDirection+':'+marginPixels+'px!important}');
  293. }
  294. function findMatch(text, regexp) {
  295. return (matches)?matches[1]:null;
  296. return (typeof s'string' || s instanceof String);
  297. return (typeof n'number' && n%10);
  298. function getPref(name) { // cross-browser GM_getValue
  299. try {a=typeof GM_getValue.toString; b=GM_getValue.toString()} catch(e){}
  300. (a 'undefined' || b.indexOf('not supported') -1)) {
  301. return GM_getValue(name, null); // Greasemonkey, Tampermonkey, Firefox extension
  302. var ls=null;
  303. if (ls) {
  304. return ls.getItem(name); // Chrome script, Opera extensions
  305. }
  306. }
  307. function setPref(name, value) { // cross-browser GM_setValue
  308. try {a=typeof GM_setValue.toString; b=GM_setValue.toString()} catch(e){}
  309. (a 'undefined' || b.indexOf('not supported') -1)) {
  310. GM_setValue(name, value); // Greasemonkey, Tampermonkey, Firefox extension
  311. var ls=null;
  312. if (ls) {
  313. return ls.setItem(name, value); // Chrome script, Opera extensions
  314. }
  315. function crossXmlHttpRequest(details) { // cross-browser GM_xmlhttpRequest
  316. if (typeof GM_xmlhttpRequest 'function') { // Greasemonkey, Tampermonkey, Firefox extension, Chrome script
  317. } else if (typeof window.opera ! 'undefined' && window.opera && typeof opera.extension ! 'undefined' &&
  318. typeof opera.extension.postMessage ! 'undefined') { // Opera 12 extension
  319. opera.extension.postMessage({'action':'xhr-'+index, 'url':details.url, 'method':details.method});
  320. } else if (typeof window.opera 'undefined' && typeof XMLHttpRequest 'function') { // Opera 15+ extension
  321. xhr.onreadystatechange = function() {
  322. if (details['onload']) {
  323. }
  324. }
  325. xhr.send();
  326. }
  327. function addFileSize(url, format) {
  328. function updateVideoLabel(size, format) {
  329. var elem=document.getElementById(LISTITEM_ID+format);
  330. size=parseInt(size,10);
  331. size=parseFloat((size/1073741824).toFixed(1))+' GB';
  332. size=parseFloat((size/1048576).toFixed(1))+' MB';
  333. size=parseFloat((size/1024).toFixed(1))+' KB';
  334. if (elem.childNodes.length>1) {
  335. } else if (elem.childNodes.length1) {
  336. elem.appendChild(document.createTextNode(' ('+size+')'));
  337. }
  338. var matchSize=findMatch(url, /[&?]clen=([0-9]+)&/i);
  339. updateVideoLabel(matchSize, format);
  340. try {
  341. method:'HEAD',
  342. onload:function(response) {
  343. if (response.readyState 4 && response.status 200) { // add size
  344. if (typeof response.getResponseHeader 'function') {
  345. size=response.getResponseHeader('Content-length');
  346. var regexp = new RegExp('^Content-length: (.*)$','im');
  347. var match = regexp.exec(response.responseHeaders);
  348. size=match[1];
  349. }
  350. updateVideoLabel(size, format);
  351. }
  352. });
  353. }
  354. debug('DYVAM - Info: signature start '+getPref(STORAGE_CODE));
  355. findMatch(sourceCode,
  356. /.sets*('signature's*,s*([a-zA-Z0-9_$][w$]*)(/)
  357. /.sigs*||s*([a-zA-Z0-9_$][w$]*)(/)
  358. /.signatures*=s*([a-zA-Z_$][w$]*)([a-zA-Z_$][w$]*)/); //old
  359. if (signatureFunctionName null) return setPref(STORAGE_CODE, 'error');
  360. signatureFunctionName=signatureFunctionName.replace('$','$');
  361. var regCode = new RegExp(signatureFunctionName + 's*=s*function' +
  362. 's*([w$]*)s*{[w$]*=[w$]*.split(');n*(.+);return [w$]*.join');
  363. var regCode2 = new RegExp('function s*' + signatureFunctionName +
  364. 's*([w$]*)s*{[w$]*=[w$]*.split(');n*(.+);return [w$]*.join');
  365. var functionCode = findMatch(sourceCode, regCode) || findMatch(sourceCode, regCode2);
  366. debug('DYVAM - Info: signaturefunction ' + signatureFunctionName + ' -- ' + functionCode);
  367. if (functionCode null) return setPref(STORAGE_CODE, 'error');
  368. var reverseFunctionName = findMatch(sourceCode,
  369. /([w$]*)s*:s*functions*(s*[w$]*s*)s*{s*(?:returns*)?[w$]*.reverses*(s*)s*}/);
  370. debug('DYVAM - Info: reversefunction ' + reverseFunctionName);
  371. if (reverseFunctionName) reverseFunctionName=reverseFunctionName.replace('$','$');
  372. /([w$]*)s*:s*functions*(s*[w$]*s*,s*[w$]*s*)s*{s*(?:returns*)?[w$]*.(?:slice|splice)(.+)s*}/);
  373. debug('DYVAM - Info: slicefunction ' + sliceFunctionName);
  374. if (sliceFunctionName) sliceFunctionName=sliceFunctionName.replace('$','$');
  375. var regSlice = new RegExp('.(?:'+'slice'+(sliceFunctionName?'|'+sliceFunctionName:')+
  376. ')s*(s*(?:[a-zA-Z_$][w$]*s*,)?s*([0-9]+)s*)'); // .slice(5) sau .Hf(a,5)
  377. var regReverse = new RegExp('.(?:'+'reverse'+(reverseFunctionName?'|'+reverseFunctionName:')+
  378. ')s*([^)]*)'); // .reverse() sau .Gf(a,45)
  379. var regSwap = new RegExp('[w$]+s*(s*[w$]+s*,s*([0-9]+)s*)');
  380. var regInline = new RegExp('[w$]+[0]s*=s*[w$]+[([0-9]+)s*%s*[w$]+.length]');
  381. var decodeArray=[];
  382. for (var i=0; i<functionCodePieces.length; i++) {
  383. functionCodePieces[i]=functionCodePieces[i].trim();
  384. if (codeLine.length>0) {
  385. var arrReverse=codeLine.match(regReverse);
  386. debug(i+': '+codeLine+' --'+(arrSlice?' slice length '+arrSlice.length:') +' '+(arrReverse?'reverse':'));
  387. var slice=parseInt(arrSlice[1], 10);
  388. decodeArray.push(-slice);
  389. } else if (arrReverse && arrReverse.length >= 1) { // reverse
  390. } else if (codeLine.indexOf('[0]') >= 0) { // inline swap
  391. functionCodePieces[i+1].indexOf('.length') >= 0 &&
  392. var inline=findMatch(functionCodePieces[i+1], regInline);
  393. decodeArray.push(inline);
  394. } else return setPref(STORAGE_CODE, 'error');
  395. var swap=findMatch(codeLine, regSwap);
  396. if (isInteger(swap) && swap>0){
  397. } else return setPref(STORAGE_CODE, 'error');
  398. }
  399. setPref(STORAGE_URL, scriptURL);
  400. DECODE_RULE=decodeArray;
  401. debug('DYVAM - Info: signature '+decodeArray.toString()+' '+scriptURL);
  402. for (var i=0;i<downloadCodeList.length;i++) {
  403. var elem=document.getElementById(LISTITEM_ID+downloadCodeList[i].format);
  404. var sig=downloadCodeList[i].sig;
  405. url=url.replace(/&signature=[w.]+/, '&signature='+decryptSignature(sig));
  406. addFileSize(url, downloadCodeList[i].format);
  407. }
  408. }
  409. function isValidSignatureCode(arr) { // valid values: '5,-3,0,2,5', 'error'
  410. if (arr'error') return true;
  411. for (var i=0;i<arr.length;i++) {
  412. if (!isInteger(parseInt(arr[i],10))) return false;
  413. return true;
  414. var storageURL=getPref(STORAGE_URL);
  415. if (!(/,0,|^0,|,0$|-/.test(storageCode))) storageCode=null; // hack for only positive items
  416. if (storageCode && isValidSignatureCode(storageCode) && storageURL &&
  417. scriptURL.replace(/^https?/i,')storageURL.replace(/^https?/i,')) return;
  418. debug('DYVAM fetch '+scriptURL);
  419. crossXmlHttpRequest({
  420. url:scriptURL,
  421. debug('DYVAM fetch status '+response.status);
  422. if (response.readyState 4 && response.status 200 && response.responseText) {
  423. }
  424. });
  425. }
  426. function getDecodeRules(rules) {
  427. if (storageCode && storageCode!='error' && isValidSignatureCode(storageCode)) {
  428. for (var i=0; i<arr.length; i++) {
  429. }
  430. debug('DYVAM - Info: signature '+arr.toString()+' '+scriptURL);
  431. return rules;
  432. function swap(a,b){var c=a[0];a[0]=a[b%a.length];a[b]=c;return a};
  433. function decode(sig, arr) { // encoded decryption
  434. var sigA=sig.split(');
  435. var act=arr[i];
  436. sigA=(act>0)?swap(sigA, act):((act0)?sigA.reverse():sigA.slice(-act));
  437. var result=sigA.join(');
  438. }
  439. if (signull) return ';
  440. if (arr) {
  441. if (sig2) return sig2;
  442. setPref(STORAGE_URL, ');
  443. }
  444. }
  445. }
  446. })();
  1. // @name Download YouTube Videos as MP4
  2. // @description Adds a button that lets you download YouTube videos.
  3. // @homepageURL https://github.com/gantt/downloadyoutube
  4. // @version 1.8.8
  5. // @namespace http://googlesystem.blogspot.com
  6. // @include https://www.youtube.com/*
  7. // @exclude https://www.youtube.com/embed/*
  8. // @match https://www.youtube.com/*
  9. // @match http://s.ytimg.com/yts/jsbin/html5player*
  10. // @match https://s.ytimg.com/yts/jsbin/html5player*
  11. // @match https://manifest.googlevideo.com/*
  12. // @match https://*.googlevideo.com/videoplayback*
  13. // @match https://*.youtube.com/videoplayback*
  14. // @connect ytimg.com
  15. // @grant GM_getValue
  16. // @run-at document-end
  17. // @icon data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAEAAAABACAMAAACdt4HsAAAAB3RJTUUH2wMOCgIoGUYEAQAAAAlwSFlzAAALEgAACxIB0t1+/AAAAARnQU1BAACxjwv8YQUAAAGSUExURfi/JO/v797e3sbGxq2traWlpZSUlJycnNbW1oyEhIRaWow5OZQhIZwYGKUQEKUICK0ICJQxMYxKSoxzc4x7e4RCQpQYGKUAAK0AALUAAL0AAK0QEIxra5QpKa0YGIxSUsYAAKUhIZR7e87Ozr0ICJRSUr29vYxjY6U5OaUpKa0hIb21tZwAALUICO/Ozu/GxqUxMZSEhLUYGO/W1r0YGKVCQpQQEL0pKffe3vfW1pxra5Q5OcZCQvfn585CQr2trZx7e8ZSUs5SUq05Oc5jY9ZjY84AAKWMjM5zc957e60pKdaMjOelpbWcnLWUlLVCQsYYGMYICNbOzpQICMYhIbV7e5xaWt6cnPfv79bGxt6lpe+9vc5KSs6lpb0xMc6EhM69vbUxMbUhIb1aWs61tcZaWuecnMYxMb1KSsZjY96UlNa1td7W1r17e9a9vZwQEN6trb1jY8YQENZra+fOzr1zc85aWufe3t6MjMY5OdZaWt61tdZ7e+/n5+e9vc6MjMZra+/e3ue1tdalpd7GxrUpKalL4aAAAAABdFJOUwBA5thmAAACxklEQVR42uXX/1/SQBgH8NuAoEQ2ijgbBivJLznBAiUUKiyJSgOVAk0tKZKw75mRRt/7v4MBY8ezjW39Vs8v8rqHz/u1jbvbidC/XL8KmcpOqVT6nSjXjooGw8WfFd+QWGfE4oLbtbr++PdMOy0BDYLjEj/0xevfWIyVAI7b/aIj/9WHsRrA8Yf9bqSexVgD4Lic9kWE/LgPwPGfNfJHDO4P8Iuq+S2M9QD8oUp+nxEAcFCtfgIA/14x/9ElAKDQbNQAwN9VAiYEABy0OgsAWAnB/AcBAtVWawkAfJ4CD0BQADZavYcQgI9h3CCQjpD5PcEgwG+SwLRhIL0vz78SjAPEU3hrHODfyX4I6rUJIP0G3oExoNwFXpoB+HwXmDEFpF9IwKA5YK+Tp9fMAdUOsC6YA553gKcmgdTfAhV1oMQqADndQDmJ0AZLAsFnCIV3VYDHJLAjDkZKciAaFz/lCeBJB1glgXBrNLndBWLJ9uZGAI+keTBLANL8SnWAzWRniAC2pG+6lQF0hfjTqCIBrEvjDwiggFSLuIUoLY0vEwAbUcsnc/LlnO02HGvEz+hXEeJ5Yj+4L2vNkxOJDSnlQzliIq2synr3embiUBjmw0FyU83KX04Ob+9aAK/Ppd5deZloz4HFlCHzt3sX0x2a6LcvQb4ab8r7i+DVdqvnCq/D5ZzqdhfAcr5B9wD0PNwPEu0ZnLwK9oPgNfCQJ2fhhhITJ3E8BjeUOXA+QNQlBh5xLjemVCgKjzgzNIJFjWF4yJoKhafgIWt6VHGmjgR0HvMuTipPdWQJ6AImbBRSE8aY/sC4er5xFx5vHyB4YRRpFWUf0AL4c+dHkHZRFo9TDeB9Aa3Llwjr8FlFwB+wO/rHm0VbPae9mPini/O5h/XGxatw2I6fGHAOuhiGZVxO98lTdgutP94yaIvVdqxZdpvFYTT9X9UfqQQlTXlm8wkAAAAASUVORK5CYII=
  18. (function () {
  19. var FORMAT_LABEL={'18':'MP4 360p','22':'MP4 720p','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','140':'M4A 128kbps - audio','264':'MP4 1440p - no audio','266':'MP4 2160p - no audio','298':'MP4 720p60 - no audio','299':'MP4 1080p60 - no audio'};
  20. var FORMAT_TYPE={'18':'mp4','22':'mp4','43':'webm','44':'webm','45':'webm','46':'webm','135':'mp4','137':'mp4','138':'mp4','140':'m4a','264':'mp4','266':'mp4','298':'mp4','299':'mp4'};
  21. var FORMAT_ORDER=['18','43','135','44','22','298','45','137','299','46','264','138','266','140'];
  22. var FORMAT_RULE={'mp4':'all','webm':'none','m4a':'all'};
  23. // all=display all versions, max=only highest quality version, none=no version
  24. var SHOW_DASH_FORMATS=false;
  25. var BUTTON_TEXT={'ar':'تنزيل','cs':'Stáhnout','de':'Herunterladen','en':'Download','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':'下載'};
  26. var BUTTON_TOOLTIP={'ar':'تنزيل هذا الفيديو','cs':'Stáhnout toto video','de':'Dieses Video herunterladen','en':'Download this video','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':'下載此影片'};
  27. var RANDOM=7489235179; // Math.floor(Math.random()*1234567890);
  28. var CONTAINER_ID='download-youtube-video'+RANDOM;
  29. var LISTITEM_ID='download-youtube-video-fmt'+RANDOM;
  30. var BUTTON_ID='download-youtube-video-button'+RANDOM;
  31. var DEBUG_ID='download-youtube-video-debug-info';
  32. var STORAGE_CODE='download-youtube-signature-code';
  33. var STORAGE_DASH='download-youtube-dash-enabled';
  34. var pagecontainer=document.getElementById('page-container');
  35. if (/^https?://www.youtube.com/watch?/.test(window.location.href)) run();
  36. var isAjax=/class[ws'-=]+spf-link/.test(pagecontainer.innerHTML);
  37. var logocontainer=document.getElementById('logo-container');
  38. if (logocontainer && !isAjax) { // fix for blocked videos
  39. isAjax=(' '+logocontainer.className+' ').indexOf(' spf-link ')>=0;
  40. var content=document.getElementById('content');
  41. var mo=window.MutationObserver||window.WebKitMutationObserver;
  42. var observer=new mo(function(mutations) {
  43. if(mutation.addedNodes!null) {
  44. for (var i=0; i<mutation.addedNodes.length; i++) {
  45. if (mutation.addedNodes[i].id'watch7-container' ||
  46. mutation.addedNodes[i].id'watch7-main-container') { // old value: movie_player
  47. break;
  48. }
  49. });
  50. observer.observe(content, {childList: true, subtree: true}); // old value: pagecontainer
  51. } else { // MutationObserver fallback for old browsers
  52. pagecontainer.addEventListener('DOMNodeInserted', onNodeInserted, false);
  53. }
  54. if (e && e.target && (e.target.id'watch7-container' ||
  55. e.target.id'watch7-main-container')) { // old value: movie_player
  56. }
  57. if (document.getElementById(CONTAINER_ID)) return; // check download container
  58. if (document.getElementById('p') && document.getElementById('vo')) return; // Feather not supported
  59. var videoID, videoFormats, videoAdaptFormats, videoManifestURL, scriptURL=null;
  60. var operaTable=new Array();
  61. var language=document.documentElement.getAttribute('lang');
  62. if (document.body.getAttribute('dir')'rtl') {
  63. }
  64. if (document.getElementById('watch7-action-buttons')) { // old UI
  65. }
  66. // obtain video ID, formats map
  67. var args=null;
  68. var usw=(typeof this.unsafeWindow ! 'undefined')?this.unsafeWindow:window; // Firefox, Opera<15
  69. if (usw.ytplayer && usw.ytplayer.config && usw.ytplayer.config.args) {
  70. }
  71. videoID=args['video_id'];
  72. videoAdaptFormats=args['adaptive_fmts'];
  73. debug('DYVAM - Info: Standard mode. videoID '+(videoID?videoID:'none')+'; ');
  74. if (usw.ytplayer && usw.ytplayer.config && usw.ytplayer.config.assets) {
  75. }
  76. if (videoIDnull) { // unsafeWindow workaround (Chrome, Opera 15+)
  77. var buffer=document.getElementById(DEBUG_ID+'2');
  78. while (buffer.firstChild) {
  79. }
  80. buffer=createHiddenElem('pre', DEBUG_ID+'2');
  81. injectScript ('if(ytplayer&&ytplayer.config&&ytplayer.config.args){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+''));}');
  82. if (code) {
  83. videoID=findMatch(code, /'video_id':s*'([^']+)'/);
  84. videoFormats=findMatch(code, /'url_encoded_fmt_stream_map':s*'([^']+)'/);
  85. videoFormats=videoFormats.replace(/&amp;/g,'u0026');
  86. videoAdaptFormats=findMatch(code, /'adaptive_fmts':s*'([^']+)'/);
  87. videoAdaptFormats=videoAdaptFormats.replace(/&amp;/g,'u0026');
  88. videoManifestURL=findMatch(code, /'dashmpd':s*'([^']+)'/);
  89. scriptURL=findMatch(code, /'js':s*'([^']+)'/);
  90. debug('DYVAM - Info: Injection mode. videoID '+(videoID?videoID:'none')+'; ');
  91. var bodyContent=document.body.innerHTML;
  92. videoID=findMatch(bodyContent, /'video_id':s*'([^']+)'/);
  93. videoFormats=findMatch(bodyContent, /'url_encoded_fmt_stream_map':s*'([^']+)'/);
  94. videoAdaptFormats=findMatch(bodyContent, /'adaptive_fmts':s*'([^']+)'/);
  95. videoManifestURL=findMatch(bodyContent, /'dashmpd':s*'([^']+)'/);
  96. scriptURL=findMatch(bodyContent, /'js':s*'([^']+)'/);
  97. scriptURL=scriptURL.replace(//g,');
  98. }
  99. debug('DYVAM - Info: Brute mode. videoID '+(videoID?videoID:'none')+'; ');
  100. debug('DYVAM - Info: url '+window.location.href+'; useragent '+window.navigator.userAgent);
  101. if (videoIDnull || videoFormatsnull || videoID.length0 || videoFormats.length0) {
  102. debug('DYVAM - Error: No config information found. YouTube must have changed the code.');
  103. }
  104. // Opera 12 extension message handler
  105. if (typeof window.opera ! 'undefined' && window.opera && typeof opera.extension ! 'undefined') {
  106. var index=findMatch(event.data.action, /xhr-([0-9]+)-response/);
  107. index=parseInt(index,10);
  108. if (typeof trigger 'function' && event.data.readyState 4) {
  109. trigger(event.data);
  110. }
  111. }
  112. DECODE_RULE=getDecodeRules(DECODE_RULE);
  113. }
  114. if (scriptURL.indexOf('//')0) {
  115. var protocol=(document.location.protocol'http:')?'http:':'https:';
  116. }
  117. }
  118. // video title
  119. videoTitle=videoTitle.replace(/s*-s*YouTube$/i, ').replace(/'/g, '').replace(/^s+|s+$/g, ').replace(/.+$/g, ');
  120. videoTitle=videoTitle.replace(/[:'?*]/g, ').replace(/[|/]/g, '_'); // Mac, Linux, Windows
  121. if (((window.navigator.userAgent || ').toLowerCase()).indexOf('windows') >= 0) {
  122. videoTitle=videoTitle.replace(/#/g, ').replace(/&/g, '_'); // Windows
  123. videoTitle=videoTitle.replace(/#/g, '%23').replace(/&/g, '%26'); // Mac, Linux
  124. var sep1='%2C', sep2='%26', sep3='%3D';
  125. sep1=',';
  126. sep2=(videoFormats.indexOf('&')>-1)?'&':'u0026';
  127. }
  128. var videoSignature=new Array();
  129. videoFormats=videoFormats+sep1+videoAdaptFormats;
  130. var videoFormatsGroup=videoFormats.split(sep1);
  131. var videoFormatsElem=videoFormatsGroup[i].split(sep2);
  132. for (var j=0;j<videoFormatsElem.length;j++) {
  133. if (pair.length2) {
  134. }
  135. if (videoFormatsPair['url']null) continue;
  136. var url=unescape(unescape(videoFormatsPair['url'])).replace(///g,'/').replace(/u0026/g,'&');
  137. var itag=videoFormatsPair['itag'];
  138. var sig=videoFormatsPair['sig']||videoFormatsPair['signature'];
  139. url=url+'&signature='+sig;
  140. } else if (videoFormatsPair['s']) {
  141. url=url+'&signature='+decryptSignature(videoFormatsPair['s']);
  142. }
  143. if (url.toLowerCase().indexOf('ratebypass')-1) { // speed up download for dash
  144. }
  145. if (url.toLowerCase().indexOf('http')0) { // validate URL
  146. }
  147. for (var category in FORMAT_RULE) {
  148. for (var index in FORMAT_TYPE){
  149. showFormat[index]=(rule'all');
  150. }
  151. for (var i=FORMAT_ORDER.length-1;i>=0;i--) {
  152. if (FORMAT_TYPE[format]category && videoURL[format]!=undefined) {
  153. break;
  154. }
  155. }
  156. var dashPref=getPref(STORAGE_DASH);
  157. SHOW_DASH_FORMATS=true;
  158. setPref(STORAGE_DASH,'0');
  159. for (var i=0;i<FORMAT_ORDER.length;i++) {
  160. if (format'37' && videoURL[format]undefined) { // hack for dash 1080p
  161. format='137';
  162. showFormat[format]=showFormat['37'];
  163. } else if (format'38' && videoURL[format]undefined) { // hack for dash 4K
  164. format='138';
  165. showFormat[format]=showFormat['38'];
  166. if (!SHOW_DASH_FORMATS && format.length>2) continue;
  167. if (videoURL[format]!=undefined && FORMAT_LABEL[format]!=undefined && showFormat[format]) {
  168. downloadCodeList.push({url:videoURL[format],sig:videoSignature[format],format:format,label:FORMAT_LABEL[format]});
  169. debug('DYVAM - Info: itag'+format+' url:'+videoURL[format]);
  170. }
  171. if (downloadCodeList.length0) {
  172. debug('DYVAM - Error: No download URL found. Probably YouTube uses encrypted streams.');
  173. }
  174. // find parent container
  175. var parentElement=document.getElementById('watch7-action-buttons');
  176. parentElement=document.getElementById('watch8-secondary-actions');
  177. debug('DYVAM Error - No container for adding the download button. YouTube must have changed the code.');
  178. } else {
  179. }
  180. var buttonText=(BUTTON_TEXT[language])?BUTTON_TEXT[language]:BUTTON_TEXT['en'];
  181. var buttonLabel=(BUTTON_TOOLTIP[language])?BUTTON_TOOLTIP[language]:BUTTON_TOOLTIP['en'];
  182. // generate download code for regular interface
  183. var spanIcon=document.createElement('span');
  184. spanIcon.setAttribute('class', 'yt-uix-button-icon-wrapper');
  185. imageIcon.setAttribute('src', '//s.ytimg.com/yt/img/pixel-vfl3z5WfW.gif');
  186. imageIcon.setAttribute('class', 'yt-uix-button-icon');
  187. 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);');
  188. mainSpan.appendChild(spanIcon);
  189. spanButton.setAttribute('class', 'yt-uix-button-content');
  190. spanButton.appendChild(document.createTextNode(buttonText+' '));
  191. var imgButton=document.createElement('img');
  192. imgButton.setAttribute('class', 'yt-uix-button-arrow');
  193. imgButton.setAttribute('src', '//s.ytimg.com/yt/img/pixel-vfl3z5WfW.gif');
  194. }
  195. var listItems=document.createElement('ol');
  196. listItems.setAttribute('style', 'display:none;');
  197. listItems.setAttribute('class', 'yt-uix-button-menu');
  198. var listItem=document.createElement('li');
  199. listLink.setAttribute('style', 'text-decoration:none;');
  200. listLink.setAttribute('href', downloadCodeList[i].url);
  201. listLink.setAttribute('download', videoTitle+'.'+FORMAT_TYPE[downloadCodeList[i].format]);
  202. listButton.setAttribute('class', 'yt-uix-button-menu-item');
  203. listButton.setAttribute('id', LISTITEM_ID+downloadCodeList[i].format);
  204. listButton.appendChild(document.createTextNode(downloadCodeList[i].label));
  205. listItem.appendChild(listLink);
  206. }
  207. var buttonElement=document.createElement('button');
  208. if (newWatchPage) {
  209. buttonElement.setAttribute('class', 'yt-uix-button yt-uix-button-size-default yt-uix-button-opacity yt-uix-tooltip');
  210. buttonElement.setAttribute('class', 'yt-uix-button yt-uix-tooltip yt-uix-button-empty yt-uix-button-text');
  211. buttonElement.setAttribute('style', 'margin-top:4px; margin-left:'+((textDirection'left')?5:10)+'px;');
  212. buttonElement.setAttribute('data-tooltip-text', buttonLabel);
  213. buttonElement.setAttribute('role', 'button');
  214. buttonElement.addEventListener('click', function(){return false;}, false);
  215. var containerSpan=document.createElement('span');
  216. containerSpan.appendChild(document.createTextNode(' '));
  217. if (!newWatchPage) { // watch7
  218. } else { // watch8
  219. parentElement.insertBefore(containerSpan, parentElement.firstChild);
  220. // REPLACEWITH if (!isSignatureUpdatingStarted) {
  221. addFileSize(downloadCodeList[i].url, downloadCodeList[i].format);
  222. // }
  223. if (typeof GM_download ! 'undefined') {
  224. var downloadFMT=document.getElementById(LISTITEM_ID+downloadCodeList[i].format);
  225. if (url.indexOf('clen=')>0 && url.indexOf('dur=')>0 && url.indexOf('gir=')>0
  226. downloadFMT.addEventListener('click', downloadVideoNatively, false);
  227. }
  228. var elem=e.currentTarget;
  229. if (e.preventDefault) {
  230. }
  231. if (loop) {
  232. GM_download(downloadCodeList[loop].url, videoTitle+'.'+FORMAT_TYPE[downloadCodeList[loop].format]);
  233. return false;
  234. function addFromManifest() { // add Dash URLs from manifest file
  235. var formats=['137', '138', '140']; // 137=1080p, 138=4k, 140=m4a
  236. for (var i=0;i<formats.length;i++) {
  237. isNecessary=false;
  238. }
  239. if (videoManifestURL && SHOW_DASH_FORMATS && isNecessary) {
  240. var matchSig=findMatch(videoManifestURL, //s/([a-zA-Z0-9.]+)//i);
  241. var decryptedSig=decryptSignature(matchSig);
  242. videoManifestURL=videoManifestURL.replace('/s/'+matchSig+'/','/signature/'+decryptedSig+'/');
  243. }
  244. var protocol=(document.location.protocol'http:')?'http:':'https:';
  245. }
  246. debug('DYVAM - Info: manifestURL '+videoManifestURL);
  247. method:'GET',
  248. onload:function(response) {
  249. if (response.readyState 4 && response.status 200 && response.responseText) {
  250. debug('DYVAM - Info: maniestFileContents '+response.responseText);
  251. var lastFormatFromList=downloadCodeList[downloadCodeList.length-1].format;
  252. debug('DYVAM - Info: lastformat: '+lastFormatFromList);
  253. k=formats[i];
  254. if (videoURL[k] || showFormat[k]false) continue;
  255. var regexp = new RegExp('<BaseURL>(http[^<]+itag/'+k+'[^<]+)</BaseURL>','i');
  256. var matchURL=findMatch(response.responseText, regexp);
  257. debug('DYVAM - Info: matchURL itag= '+k+' url= '+matchURL);
  258. matchURL=matchURL.replace(/&amp;/g,'&');
  259. downloadCodeList.push(
  260. {url:matchURL,sig:videoSignature[k],format:k,label:FORMAT_LABEL[k]});
  261. var downloadFMT=document.getElementById(LISTITEM_ID+lastFormatFromList);
  262. var clone=downloadFMT.parentNode.parentNode.cloneNode(true);
  263. clone.firstChild.firstChild.setAttribute('id', LISTITEM_ID+k);
  264. downloadFMT.parentNode.parentNode.parentNode.appendChild(clone);
  265. downloadFMT=document.getElementById(LISTITEM_ID+k);
  266. downloadFMT.firstChild.nodeValue=FORMAT_LABEL[k];
  267. lastFormatFromList=k;
  268. }
  269. });
  270. }
  271. function injectStyle(code) {
  272. style.type='text/css';
  273. style.appendChild(document.createTextNode(code));
  274. document.getElementsByTagName('head')[0].appendChild(style);
  275. var script=document.createElement('script');
  276. script.textContent=code;
  277. document.body.removeChild(script);
  278. var debugElem=document.getElementById(DEBUG_ID);
  279. debugElem=createHiddenElem('div', DEBUG_ID);
  280. debugElem.appendChild(document.createTextNode(str+' '));
  281. var elem=document.createElement(tag);
  282. elem.setAttribute('style', 'display:none;');
  283. return elem;
  284. function fixTranslations(language, textDirection) {
  285. 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
  286. var likeButton=document.getElementById('watch-like');
  287. var spanElements=likeButton.getElementsByClassName('yt-uix-button-content');
  288. spanElements[0].style.display='none'; // hide like text
  289. }
  290. if (/^bg|ca|cs|el|eu|hr|it|ml|ms|pl|sl|sw|te$/.test(language)) {
  291. }
  292. injectStyle('#watch7-secondary-actions .yt-uix-button{margin-'+textDirection+':'+marginPixels+'px!important}');
  293. }
  294. function findMatch(text, regexp) {
  295. return (matches)?matches[1]:null;
  296. return (typeof s'string' || s instanceof String);
  297. return (typeof n'number' && n%10);
  298. function getPref(name) { // cross-browser GM_getValue
  299. try {a=typeof GM_getValue.toString; b=GM_getValue.toString()} catch(e){}
  300. (a 'undefined' || b.indexOf('not supported') -1)) {
  301. return GM_getValue(name, null); // Greasemonkey, Tampermonkey, Firefox extension
  302. var ls=null;
  303. if (ls) {
  304. return ls.getItem(name); // Chrome script, Opera extensions
  305. }
  306. }
  307. function setPref(name, value) { // cross-browser GM_setValue
  308. try {a=typeof GM_setValue.toString; b=GM_setValue.toString()} catch(e){}
  309. (a 'undefined' || b.indexOf('not supported') -1)) {
  310. GM_setValue(name, value); // Greasemonkey, Tampermonkey, Firefox extension
  311. var ls=null;
  312. if (ls) {
  313. return ls.setItem(name, value); // Chrome script, Opera extensions
  314. }
  315. function crossXmlHttpRequest(details) { // cross-browser GM_xmlhttpRequest
  316. if (typeof GM_xmlhttpRequest 'function') { // Greasemonkey, Tampermonkey, Firefox extension, Chrome script
  317. } else if (typeof window.opera ! 'undefined' && window.opera && typeof opera.extension ! 'undefined' &&
  318. typeof opera.extension.postMessage ! 'undefined') { // Opera 12 extension
  319. opera.extension.postMessage({'action':'xhr-'+index, 'url':details.url, 'method':details.method});
  320. } else if (typeof window.opera 'undefined' && typeof XMLHttpRequest 'function') { // Opera 15+ extension
  321. xhr.onreadystatechange = function() {
  322. if (details['onload']) {
  323. }
  324. }
  325. xhr.send();
  326. }
  327. function addFileSize(url, format) {
  328. function updateVideoLabel(size, format) {
  329. var elem=document.getElementById(LISTITEM_ID+format);
  330. size=parseInt(size,10);
  331. size=parseFloat((size/1073741824).toFixed(1))+' GB';
  332. size=parseFloat((size/1048576).toFixed(1))+' MB';
  333. size=parseFloat((size/1024).toFixed(1))+' KB';
  334. if (elem.childNodes.length>1) {
  335. } else if (elem.childNodes.length1) {
  336. elem.appendChild(document.createTextNode(' ('+size+')'));
  337. }
  338. var matchSize=findMatch(url, /[&?]clen=([0-9]+)&/i);
  339. updateVideoLabel(matchSize, format);
  340. try {
  341. method:'HEAD',
  342. onload:function(response) {
  343. if (response.readyState 4 && response.status 200) { // add size
  344. if (typeof response.getResponseHeader 'function') {
  345. size=response.getResponseHeader('Content-length');
  346. var regexp = new RegExp('^Content-length: (.*)$','im');
  347. var match = regexp.exec(response.responseHeaders);
  348. size=match[1];
  349. }
  350. updateVideoLabel(size, format);
  351. }
  352. });
  353. }
  354. debug('DYVAM - Info: signature start '+getPref(STORAGE_CODE));
  355. findMatch(sourceCode,
  356. /.sets*('signature's*,s*([a-zA-Z0-9_$][w$]*)(/)
  357. /.sigs*||s*([a-zA-Z0-9_$][w$]*)(/)
  358. /.signatures*=s*([a-zA-Z_$][w$]*)([a-zA-Z_$][w$]*)/); //old
  359. if (signatureFunctionName null) return setPref(STORAGE_CODE, 'error');
  360. signatureFunctionName=signatureFunctionName.replace('$','$');
  361. var regCode = new RegExp(signatureFunctionName + 's*=s*function' +
  362. 's*([w$]*)s*{[w$]*=[w$]*.split(');n*(.+);return [w$]*.join');
  363. var regCode2 = new RegExp('function s*' + signatureFunctionName +
  364. 's*([w$]*)s*{[w$]*=[w$]*.split(');n*(.+);return [w$]*.join');
  365. var functionCode = findMatch(sourceCode, regCode) || findMatch(sourceCode, regCode2);
  366. debug('DYVAM - Info: signaturefunction ' + signatureFunctionName + ' -- ' + functionCode);
  367. if (functionCode null) return setPref(STORAGE_CODE, 'error');
  368. var reverseFunctionName = findMatch(sourceCode,
  369. /([w$]*)s*:s*functions*(s*[w$]*s*)s*{s*(?:returns*)?[w$]*.reverses*(s*)s*}/);
  370. debug('DYVAM - Info: reversefunction ' + reverseFunctionName);
  371. if (reverseFunctionName) reverseFunctionName=reverseFunctionName.replace('$','$');
  372. /([w$]*)s*:s*functions*(s*[w$]*s*,s*[w$]*s*)s*{s*(?:returns*)?[w$]*.(?:slice|splice)(.+)s*}/);
  373. debug('DYVAM - Info: slicefunction ' + sliceFunctionName);
  374. if (sliceFunctionName) sliceFunctionName=sliceFunctionName.replace('$','$');
  375. var regSlice = new RegExp('.(?:'+'slice'+(sliceFunctionName?'|'+sliceFunctionName:')+
  376. ')s*(s*(?:[a-zA-Z_$][w$]*s*,)?s*([0-9]+)s*)'); // .slice(5) sau .Hf(a,5)
  377. var regReverse = new RegExp('.(?:'+'reverse'+(reverseFunctionName?'|'+reverseFunctionName:')+
  378. ')s*([^)]*)'); // .reverse() sau .Gf(a,45)
  379. var regSwap = new RegExp('[w$]+s*(s*[w$]+s*,s*([0-9]+)s*)');
  380. var regInline = new RegExp('[w$]+[0]s*=s*[w$]+[([0-9]+)s*%s*[w$]+.length]');
  381. var decodeArray=[];
  382. for (var i=0; i<functionCodePieces.length; i++) {
  383. functionCodePieces[i]=functionCodePieces[i].trim();
  384. if (codeLine.length>0) {
  385. var arrReverse=codeLine.match(regReverse);
  386. debug(i+': '+codeLine+' --'+(arrSlice?' slice length '+arrSlice.length:') +' '+(arrReverse?'reverse':'));
  387. var slice=parseInt(arrSlice[1], 10);
  388. decodeArray.push(-slice);
  389. } else if (arrReverse && arrReverse.length >= 1) { // reverse
  390. } else if (codeLine.indexOf('[0]') >= 0) { // inline swap
  391. functionCodePieces[i+1].indexOf('.length') >= 0 &&
  392. var inline=findMatch(functionCodePieces[i+1], regInline);
  393. decodeArray.push(inline);
  394. } else return setPref(STORAGE_CODE, 'error');
  395. var swap=findMatch(codeLine, regSwap);
  396. if (isInteger(swap) && swap>0){
  397. } else return setPref(STORAGE_CODE, 'error');
  398. }
  399. setPref(STORAGE_URL, scriptURL);
  400. DECODE_RULE=decodeArray;
  401. debug('DYVAM - Info: signature '+decodeArray.toString()+' '+scriptURL);
  402. for (var i=0;i<downloadCodeList.length;i++) {
  403. var elem=document.getElementById(LISTITEM_ID+downloadCodeList[i].format);
  404. var sig=downloadCodeList[i].sig;
  405. url=url.replace(/&signature=[w.]+/, '&signature='+decryptSignature(sig));
  406. addFileSize(url, downloadCodeList[i].format);
  407. }
  408. }
  409. function isValidSignatureCode(arr) { // valid values: '5,-3,0,2,5', 'error'
  410. if (arr'error') return true;
  411. for (var i=0;i<arr.length;i++) {
  412. if (!isInteger(parseInt(arr[i],10))) return false;
  413. return true;
  414. var storageURL=getPref(STORAGE_URL);
  415. if (!(/,0,|^0,|,0$|-/.test(storageCode))) storageCode=null; // hack for only positive items
  416. if (storageCode && isValidSignatureCode(storageCode) && storageURL &&
  417. scriptURL.replace(/^https?/i,')storageURL.replace(/^https?/i,')) return;
  418. debug('DYVAM fetch '+scriptURL);
  419. crossXmlHttpRequest({
  420. url:scriptURL,
  421. debug('DYVAM fetch status '+response.status);
  422. if (response.readyState 4 && response.status 200 && response.responseText) {
  423. }
  424. });
  425. }
  426. function getDecodeRules(rules) {
  427. if (storageCode && storageCode!='error' && isValidSignatureCode(storageCode)) {
  428. for (var i=0; i<arr.length; i++) {
  429. }
  430. debug('DYVAM - Info: signature '+arr.toString()+' '+scriptURL);
  431. return rules;
  432. function swap(a,b){var c=a[0];a[0]=a[b%a.length];a[b]=c;return a};
  433. function decode(sig, arr) { // encoded decryption
  434. var sigA=sig.split(');
  435. var act=arr[i];
  436. sigA=(act>0)?swap(sigA, act):((act0)?sigA.reverse():sigA.slice(-act));
  437. var result=sigA.join(');
  438. }
  439. if (signull) return ';
  440. if (arr) {
  441. if (sig2) return sig2;
  442. setPref(STORAGE_URL, ');
  443. }
  444. }
  445. }
  446. })();