酷狗在线听/下载/vip/2024

无需登录在线听你想听的音乐

2024-08-18 या दिनांकाला. सर्वात नवीन आवृत्ती पाहा.

  1. // ==UserScript==
  2. // @name 酷狗在线听/下载/vip/2024
  3. // @namespace http://tampermonkey.net/
  4. // @version 2.0
  5. // @icon https://i0.hdslb.com/bfs/album/0d58ba3462659867aa46633d4a4791e93160ffb5.jpg
  6. // @description 无需登录在线听你想听的音乐
  7. // @author 今天是充满希望的一天
  8. // @match *://www.kugou.com/mixsong/*
  9. // @match *://www.kugou.com/song/*
  10. // @grant GM_xmlhttpRequest
  11. // @grant GM_download
  12. // @grant GM_addStyle
  13. // @grant GM_getResourceText
  14. // @require https://code.jquery.com/jquery-2.1.4.min.js
  15. // @require https://cdnjs.cloudflare.com/ajax/libs/jquery-confirm/3.3.2/jquery-confirm.min.js
  16. // @require https://unpkg.com/nprogress@0.2.0/nprogress.js
  17. // @resource css https://cdn.bootcdn.net/ajax/libs/jquery-confirm/3.3.4/jquery-confirm.min.css
  18. // @connect 1.94.43.52
  19. // @connect m.kugou.com
  20. // ==/UserScript==
  21. console.log("==================================插件启动成功==================================")
  22. // 2022-12-20新增批量下载,以及部分功能的优化
  23. let loc = location.href;
  24. var mp3_Name = "";
  25. var download_hash = "";
  26. var download_hash_list = "0";
  27. var mp3_ecid = "";
  28. var mp3_ecid_download = "";
  29. if (loc.indexOf("www.kugou.com/song/") > 0 || loc.indexOf("www.kugou.com/mixsong/") > 0) {
  30. // 定义变量
  31. let mp3_Hash = "";
  32. let sq_hash = "";
  33. let g_hash = "";
  34. let albumid = "";
  35. // 当前播放的最高音质url
  36. let mp3_Url = "";
  37.  
  38. // 删除加载客户端弹窗
  39. let close_div = document.getElementsByClassName("ui-dialog-grid")[0];
  40. if (close_div != undefined){
  41. close_div.style.display = "none"
  42. }
  43.  
  44. // 添加按钮选择音质
  45. let down_load_div = document.getElementsByClassName("btnArea2 clearfix")[0];
  46. down_load_div.innerHTML = "";
  47. /**
  48. // 超高音质
  49. let button_ws = document.createElement("button");
  50. button_ws.id = "down_load_ws";
  51. button_ws.textContent = "下载超高音质(需设置flac为白名单)";
  52. button_ws.style.width = "230px";
  53. button_ws.style.height = "50px";
  54. button_ws.style.color = "#FFFFFF";
  55. button_ws.style.cursor = "pointer";
  56. button_ws.style.background = "#000000";
  57. down_load_div.appendChild(button_ws);
  58. $('#down_load_ws').hover(function () {
  59. $(this).css('background', '#232020')
  60. $(this).css('color', '#BCBBBB')
  61. }, function () {
  62. $(this).css('background', '#000000')
  63. $(this).css('color', '#FFFFFF')
  64. })
  65. // 高音质
  66. let button_g = document.createElement("button");
  67. button_g.id = "button_g";
  68. button_g.textContent = "下载高音质";
  69. button_g.style.width = "230px";
  70. button_g.style.height = "50px";
  71. button_g.style.color = "#FFFFFF";
  72. button_g.style.cursor = "pointer";
  73. button_g.style.background = "#000000";
  74. button_g.style.margin = "3px 0px";
  75. down_load_div.appendChild(button_g);
  76. $('#button_g').hover(function () {
  77. $(this).css('background', '#232020')
  78. $(this).css('color', '#BCBBBB')
  79. }, function () {
  80. $(this).css('background', '#000000')
  81. $(this).css('color', '#FFFFFF')
  82. })
  83. */
  84. // 普通音质
  85. let button_mp3 = document.createElement("button");
  86. button_mp3.id = "button_mp3";
  87. button_mp3.textContent = "下载普通音质";
  88. button_mp3.style.width = "230px";
  89. button_mp3.style.height = "50px";
  90. button_mp3.style.color = "#FFFFFF";
  91. button_mp3.style.cursor = "pointer";
  92. button_mp3.style.background = "#000000";
  93. down_load_div.appendChild(button_mp3);
  94. $('#button_mp3').hover(function () {
  95. $(this).css('background', '#232020')
  96. $(this).css('color', '#BCBBBB')
  97. }, function () {
  98. $(this).css('background', '#000000')
  99. $(this).css('color', '#FFFFFF')
  100. })
  101.  
  102.  
  103. // 点击下载按钮 超高音质
  104. // button_ws.onclick = function () {
  105. // if (sq_hash == download_hash) {
  106. // alert(mp3_Name + " 已在下载中!")
  107. // } else {
  108. // download_hash = sq_hash;
  109. // downloadBySrc(mp3_Url,0);
  110. // }
  111. // };
  112. // // 点击下载按钮 高音质
  113. // button_g.onclick = function () {
  114. // if (g_hash == download_hash) {
  115. // alert(mp3_Name + " 已在下载中!");
  116. // } else {
  117. // download_hash = g_hash;
  118. // getMp3UrlSrc(g_hash, albumid, 0);
  119. // }
  120. // };
  121. // 点击下载按钮 普通音质
  122. button_mp3.onclick = function () {
  123. // if (mp3_Hash == download_hash) {
  124. // alert(mp3_Name + " 已在下载中!");
  125. // } else {
  126. // download_hash = mp3_Hash;
  127. // getMp3UrlSrc(mp3_Hash, albumid, 0);
  128. // }
  129. if (mp3_ecid == mp3_ecid_download) {
  130. alert(mp3_Name + " 已在下载中!");
  131. } else {
  132. mp3_ecid_download = mp3_ecid;
  133. getMp3UrlSrcVip();
  134. }
  135.  
  136. // getMp3UrlSrc(mp3_Hash, albumid, 0);
  137. };
  138.  
  139. // // 点击下载按钮 超高音质
  140. // document.getElementById('pb_download').onclick = function () {
  141. // if (download_url == mp3_Url) {
  142. // alert(mp3_Name + " 已在下载中!")
  143. // } else {
  144. // downloadBySrc(mp3_Url);
  145. // setTimeout(function () {
  146. // document.getElementsByClassName('ui-popup ui-popup-show ui-popup-focus')[0].style.display = "none"
  147. // }, 50)
  148. // }
  149. // };
  150. // 监听audio开始播放事件(事件在视频/音频(audio/video)开始播放时触发。)
  151. document.getElementById('myAudio').addEventListener("play", function () {
  152. let mp3_ecid_new = document.getElementById('myAudio').getAttribute("data-ecid");
  153. if (mp3_ecid != mp3_ecid_new){
  154. mp3_ecid = mp3_ecid_new;
  155. /**
  156. // 判断是否需要修改src属性
  157. if (document.getElementById('myAudio').getAttribute("data-hash") != mp3_Hash) {
  158. mp3_Hash = document.getElementById('myAudio').getAttribute("data-hash");
  159. let play_hash = mp3_Hash;
  160. let searchQualityUrl = 'http://m.kugou.com/app/i/getSongInfo.php?cmd=playInfo&hash=' + play_hash;
  161. // 查询音质
  162. GM_xmlhttpRequest({
  163. method: "get",
  164. url: searchQualityUrl,
  165. onload: function (r) {
  166. let jsonTxt = r.responseText;
  167. let json = JSON.parse(jsonTxt);
  168. albumid = json.albumid.toString();
  169. g_hash = json.extra['320hash'];
  170. if (g_hash == '') {
  171. button_g.style.display = 'none';
  172. } else {
  173. button_g.style.display = 'block';
  174. play_hash = g_hash;
  175. }
  176. sq_hash = json.extra.sqhash;
  177. if (sq_hash == '') {
  178. button_ws.style.display = 'none';
  179. } else {
  180. button_ws.style.display = 'block';
  181. play_hash = sq_hash;
  182. }
  183. // 访问第三方解析无损接口
  184. let get_sq_url = "https://xxxxx.xxx/api/tampermonkey/url/byhash?hash=" + play_hash + "&albumid=" + albumid;
  185. console.log(get_sq_url);
  186. // get请求获取无损音质的信息
  187. GM_xmlhttpRequest({
  188. method: "get",
  189. url: get_sq_url,
  190. onload: function (r) {
  191. let jsonTxt = r.responseText;
  192. let json = JSON.parse(jsonTxt);
  193. mp3_Url = json.data.play_url;
  194. mp3_Name = json.data.audio_name;
  195. document.getElementById('myAudio').src = mp3_Url;
  196. //document.getElementById('openKugou').href = mp3_Url;
  197. if (document.getElementById('myAudio').paused) {
  198. document.getElementById('myAudio').play();
  199. }
  200. console.log(mp3_Name + mp3_Url.substr(mp3_Url.lastIndexOf(".")) + " 加载完成");
  201. }
  202. })
  203. }
  204. })
  205. }
  206. */
  207. // 访问第三方解析接口
  208. let get_sq_url = "http://1.94.43.52:5001//url/newVip?ecid=" + mp3_ecid;
  209. console.log(get_sq_url);
  210. // get请求获取音乐的信息
  211. GM_xmlhttpRequest({
  212. method: "get",
  213. url: get_sq_url,
  214. onload: function (r) {
  215. let jsonTxt = r.responseText;
  216. let json = JSON.parse(jsonTxt);
  217. mp3_Url = json.data.play_url;
  218. mp3_Name = json.data.audio_name;
  219. document.getElementById('myAudio').src = mp3_Url;
  220. //document.getElementById('openKugou').href = mp3_Url;
  221. if (document.getElementById('myAudio').paused) {
  222. document.getElementById('myAudio').play();
  223. }
  224. console.log(mp3_Name + mp3_Url.substr(mp3_Url.lastIndexOf(".")) + " 加载完成");
  225. }
  226. })
  227. }
  228. })
  229. // 直接用最暴力的方法,修改id
  230. document.getElementById("bar").id = 'new_bar';
  231. $("#new_bar").off("click").on("click", function(e) {
  232. let new_pre = e.offsetX / $("#progress_middle").width();
  233. document.getElementById('myAudio').currentTime = myAudio.duration * new_pre;
  234. });
  235. } else if (loc.indexOf("/yy/rank/") > 0 || loc.indexOf("/yy/html/rank.html") > 0) {
  236. let download_div = document.getElementById("pc_temp_title");
  237.  
  238. document.getElementsByClassName("pc_temp_btn_s02 pc_temp_bicon_play")[0].style.marginTop = "0px";
  239. $(".pc_rank_title .pc_temp_title").css("font-size", "12px");
  240. let form = document.createElement("form");
  241. let radio_sq = document.createElement("input");
  242. radio_sq.type = "radio";
  243. radio_sq.name = "choose_q";
  244. radio_sq.value = "0";
  245. radio_sq.style.marginLeft = "15px";
  246. let radio_sq_label = document.createElement('label');
  247. radio_sq_label.textContent = "超高音质";
  248. radio_sq_label.id = "radio_sq_label";
  249. radio_sq.style.cursor = "pointer";
  250. radio_sq_label.style.cursor = "pointer";
  251. let radio_g = document.createElement("input");
  252. radio_g.type = "radio";
  253. radio_g.name = "choose_q";
  254. radio_g.value = "1";
  255. radio_g.style.marginLeft = "15px";
  256. let radio_g_label = document.createElement('label');
  257. radio_g_label.textContent = "高音质";
  258. radio_g_label.id = "radio_g_label";
  259. radio_g.style.cursor = "pointer";
  260. radio_g_label.style.cursor = "pointer";
  261. let radio_d = document.createElement("input");
  262. radio_d.type = "radio";
  263. radio_d.name = "choose_q";
  264. radio_d.value = "2";
  265. radio_d.style.marginLeft = "15px";
  266. radio_d.defaultChecked = true;
  267. let radio_d_label = document.createElement('label');
  268. radio_d_label.textContent = "标准音质";
  269. radio_d_label.id = "radio_d_label";
  270. radio_d.style.cursor = "pointer";
  271. radio_d_label.style.cursor = "pointer";
  272. form.style.display = "inline";
  273. form.appendChild(radio_sq);
  274. form.appendChild(radio_sq_label);
  275. form.appendChild(radio_g);
  276. form.appendChild(radio_g_label);
  277. form.appendChild(radio_d);
  278. form.appendChild(radio_d_label);
  279. download_div.appendChild(form);
  280. // 点击label,模拟点击对应的radio
  281. $("#radio_sq_label").click(function () {
  282. $('[name="choose_q"]').eq(0).trigger("click");
  283. })
  284. $("#radio_g_label").click(function () {
  285. $('[name="choose_q"]').eq(1).trigger("click");
  286. })
  287. $("#radio_d_label").click(function () {
  288. $('[name="choose_q"]').eq(2).trigger("click");
  289. })
  290. // 下载所选按钮
  291. let download_button = document.createElement("button");
  292. download_button.id = "download_select";
  293. download_button.textContent = "下载所选音乐";
  294. download_button.style.width = "100px";
  295. download_button.style.height = "34px";
  296. download_button.style.color = "#fff";
  297. download_button.style.cursor = "pointer";
  298. download_button.style.background = "#169af3";
  299. download_button.style.marginLeft = "20px";
  300. download_div.appendChild(download_button);
  301. $('#download_select').hover(function () {
  302. $(this).css('background', '#158fe1')
  303. }, function () {
  304. $(this).css('background', '#169af3')
  305. })
  306.  
  307. $('#download_select').click(function () {
  308. if (download_hash_list == "1") {
  309. alert("正在下载中,请稍后,如长时间无反应,请刷新后重试!");
  310. return;
  311. }
  312. download_hash_list = "1";
  313. // 全选
  314. if ($('.checkedAll').attr("class").indexOf("pc_temp_btn_checked") > 0) {
  315. $.confirm({
  316. title: '下载提示',
  317. content: '你确定要下载所有选中的音乐吗?',
  318. type: 'green',
  319. icon: 'glyphicon glyphicon-question-sign',
  320. buttons: {
  321. ok: {
  322. text: '确认',
  323. btnClass: 'btn-primary',
  324. action: function () {
  325. global.features.forEach(function (song, index) {
  326. if ($('[name="choose_q"]:checked').val() == 0) {
  327. // 使用同步方式
  328. (async function () {
  329. let sqhash = await getSqHashOrGHash(song.Hash, "sqhash");
  330. getMp3UrlSrc(sqhash, song.album_id, song.FileName);
  331. })()
  332. } else if ($('[name="choose_q"]:checked').val() == 1) {
  333. (async function () {
  334. let ghash = await getSqHashOrGHash(song.Hash, '320hash');
  335. getMp3UrlSrc(ghash, song.album_id, song.FileName);
  336. })()
  337. } else {
  338. getMp3UrlSrc(song.Hash, song.album_id, song.FileName);
  339. }
  340. })
  341. }
  342. },
  343. cancel: {
  344. text: '取消',
  345. btnClass: 'btn-primary',
  346. action: function() {
  347. download_hash_list = "0";
  348. }
  349. }
  350. }
  351. })
  352. } else {
  353. $.confirm({
  354. title: '下载提示',
  355. content: '你确定要下载所有选中的音乐吗?',
  356. type: 'green',
  357. icon: 'glyphicon glyphicon-question-sign',
  358. buttons: {
  359. ok: {
  360. text: '确认',
  361. btnClass: 'btn-primary',
  362. action: function () {
  363. // 获取选中的
  364. $('.pc_temp_btn_checked').each(function () {
  365. let song_index = $(this).attr("data-index");
  366. let song = global.features[song_index];
  367. mp3_Name = song.FileName;
  368. if ($('[name="choose_q"]:checked').val() == 0) {
  369. // 使用同步方式
  370. (async function () {
  371. let sqhash = await getSqHashOrGHash(song.Hash, "sqhash");
  372. getMp3UrlSrc(sqhash, song.album_id, song.FileName);
  373. })()
  374. } else if ($('[name="choose_q"]:checked').val() == 1) {
  375. (async function () {
  376. let ghash = await getSqHashOrGHash(song.Hash, '320hash');
  377. getMp3UrlSrc(ghash, song.album_id, song.FileName);
  378. })()
  379. } else {
  380. // setTimeout(function () { getMp3UrlSrc(song.Hash, song.album_id, song.FileName); }, 5000);
  381. getMp3UrlSrc(song.Hash, song.album_id, song.FileName);
  382. }
  383. });
  384. }
  385. },
  386. cancel: {
  387. text: '取消',
  388. btnClass: 'btn-primary',
  389. action: function() {
  390. download_hash_list = "0";
  391. }
  392. }
  393. }
  394. })
  395. }
  396. setTimeout(function () { download_hash_list = "0"; }, 5000);
  397. })
  398.  
  399. }
  400.  
  401. // 获取高音质或者超高音质的hash
  402. function getSqHashOrGHash(hash, quality) {
  403. let searchQualityUrl = 'http://m.kugou.com/app/i/getSongInfo.php?cmd=playInfo&hash=' + hash;
  404. let quality_hash = "";
  405. // 查询音质
  406. return new Promise((resolve, reject) => {
  407. GM_xmlhttpRequest({
  408. method: "get",
  409. url: searchQualityUrl,
  410. onload: function (r) {
  411. let jsonTxt = r.responseText;
  412. let json = JSON.parse(jsonTxt);
  413. quality_hash = json.extra[quality];
  414. if (quality_hash == "" && quality == "sqhash") {
  415. quality_hash = json.extra['320hash'];
  416. }
  417. if (quality_hash == "") {
  418. quality_hash = hash;
  419. }
  420. // 返回的值,quality_hash
  421. resolve(quality_hash);
  422. }
  423. })
  424. })
  425. }
  426.  
  427. // 获取高音质或者普通音质的MP3地址并且下载
  428. function getMp3UrlSrcVip() {
  429.  
  430. downloadBySrc(document.getElementById('myAudio').src, document.getElementsByClassName("audioName")[0].title);
  431. // let get_url = "http://xx.xxx/api/tampermonkey/url/byhash?hash=" + d_hash + "&albumid=" + albumid;
  432. // GM_xmlhttpRequest({
  433. // method: "get",
  434. // url: get_url,
  435. // onload: function (r) {
  436. // let jsonTxt = r.responseText;
  437. // let json = JSON.parse(jsonTxt);
  438. // downloadBySrc(json.data.play_url, file_name);
  439. // }
  440. // })
  441. mp3_ecid_download = ""
  442. }
  443.  
  444. // 获取高音质或者普通音质的MP3地址并且下载 此方法不再用了
  445. function getMp3UrlSrc(d_hash, albumid, file_name) {
  446. let get_url = "http://xxx.xxx/api/tampermonkey/url/byhash?hash=" + d_hash + "&albumid=" + albumid;
  447. GM_xmlhttpRequest({
  448. method: "get",
  449. url: get_url,
  450. onload: function (r) {
  451. let jsonTxt = r.responseText;
  452. let json = JSON.parse(jsonTxt);
  453. downloadBySrc(json.data.play_url, file_name);
  454. }
  455. })
  456. }
  457.  
  458. // 点击下载 by url
  459. function downloadBySrc(download_url_quality, file_name) {
  460. let down_name = file_name != 0 ? file_name : mp3_Name;
  461. let download_url = download_url_quality;
  462. let loaded = 0.0;
  463. NProgress.set(0.0);
  464. GM_download({
  465. url: download_url,
  466. name: down_name + download_url.substr(download_url.lastIndexOf(".")),
  467. saveAs: true,
  468. onerror: function (error) {
  469. //如果下载最终出现错误,则要执行的回调
  470. console.log(error)
  471. console.log(down_name + " 下载报错,请反馈!");
  472. },
  473. onprogress: (pro) => {
  474. //如果此下载取得了一些进展,则要执行的回调
  475. // console.log(pro.loaded) //文件加载量
  476. // console.log(pro.totalSize) //文件总大小
  477. let size = (pro.loaded / pro.totalSize).toFixed(1);
  478. if (loaded != size) {
  479. loaded = size;
  480. NProgress.inc(0.1);
  481. }
  482. },
  483. ontimeout: () => {
  484. //如果此下载由于超时而失败,则要执行的回调
  485. console.log(down_name + "下载超时,请反馈!");
  486. },
  487. onload: () => {
  488. //如果此下载完成,则要执行的回调
  489. console.log(down_name + " 下载完成!");
  490. download_hash = "";
  491. NProgress.done();
  492. }
  493. })
  494. }
  495. GM_addStyle(GM_getResourceText("css"));
  496. //========================================= nprogress.min.css
  497. GM_addStyle(`
  498. #nprogress{pointer-events:none}#nprogress .bar{background:#f90;position:fixed;z-index:1031;top:0;left:0;width:100%;height:5px}#nprogress .peg{display:block;position:absolute;right:0;width:100px;height:100%;box-shadow:0 0 10px #f90,0 0 5px #f90;opacity:1;-webkit-transform:rotate(3deg) translate(0,-4px);-ms-transform:rotate(3deg) translate(0,-4px);transform:rotate(3deg) translate(0,-4px)}#nprogress .spinner{display:block;position:fixed;z-index:1031;top:15px;right:15px}#nprogress .spinner-icon{width:18px;height:18px;box-sizing:border-box;border:2px solid transparent;border-top-color:#f90;border-left-color:#f90;border-radius:50%;-webkit-animation:nprogress-spinner 400ms linear infinite;animation:nprogress-spinner 400ms linear infinite}.nprogress-custom-parent{overflow:hidden;position:relative}.nprogress-custom-parent #nprogress .bar,.nprogress-custom-parent #nprogress .spinner{position:absolute}@-webkit-keyframes nprogress-spinner{0%{-webkit-transform:rotate(0deg)}100%{-webkit-transform:rotate(360deg)}}@keyframes nprogress-spinner{0%{transform:rotate(0deg)}100%{transform:rotate(360deg)}}
  499. `);
  500. //=========================================jq的confirm
  501. GM_addStyle(`
  502. .jconfirm-box-container .jconfirm-box{width: 281px;}
  503. `);