9ku.com 九酷音乐下载

九酷音乐下载工具,一键另存下载MP3文件,一键复制歌曲文件名

  1. /* eslint-disable no-extra-semi */
  2. // ==UserScript==
  3. // @name 9ku.com 九酷音乐下载
  4. // @namespace https://gf.qytechs.cn/zh-CN/users/812943
  5. // @version 0.0.4
  6. // @description 九酷音乐下载工具,一键另存下载MP3文件,一键复制歌曲文件名
  7. // @author gafish
  8. // @match https://www.9ku.com/play/*.htm
  9. // @icon https://www.google.com/s2/favicons?domain=9ku.com
  10. // @license MIT
  11. // @require https://cdn.jsdelivr.net/npm/copy-to-clipboard@3.3.1/example/index.js
  12. // @grant none
  13. // ==/UserScript==
  14.  
  15. ;(function (jQuery, copyToClipboard) {
  16. 'use strict'
  17.  
  18. const box = jQuery('.ppBox')
  19. const feifa = jQuery('#feifa')
  20.  
  21. const downloadedKey = 'chrome_plugin_downloaded'
  22.  
  23. let musicInfo
  24.  
  25. const init = () => {
  26. const { singer, musicname, song_id, meida } = window
  27. const { mp3 } = meida
  28.  
  29. musicInfo = {
  30. singer,
  31. musicName: musicname,
  32. songID: song_id,
  33. mp3URL: mp3,
  34. downloadFileName: `${singer} - ${musicname}.mp3`,
  35. }
  36.  
  37. if (!box[0]) return
  38.  
  39. box.css({ height: 340 })
  40.  
  41. addDownloadButton()
  42. addMp3FileName()
  43.  
  44. hidePalylistAd()
  45.  
  46. const downloaded = getDownloaded()
  47.  
  48. if (downloaded.includes(musicInfo.songID)) {
  49. addDownloadedTag()
  50. }
  51. }
  52. const getDownloaded = () => {
  53. const downloaded = window.localStorage[downloadedKey] || '[]'
  54. const downloadedArr = JSON.parse(downloaded)
  55.  
  56. return downloadedArr
  57. }
  58. const addDownloadButton = () => {
  59. if (!box || !musicInfo) return
  60.  
  61. const downloadBtn = jQuery(`
  62. <a
  63. href="${musicInfo.mp3URL}"
  64. download=${musicInfo.downloadFileName.replace(/\s/g, '_')}
  65. target="_blank"
  66. >
  67. 右键另存MP3文件
  68. </a>
  69. `)
  70.  
  71. downloadBtn
  72. .css({
  73. display: 'block',
  74. backgroundColor: '#f00',
  75. color: '#fff',
  76. padding: '5px 10px',
  77. borderRadius: 5,
  78. margin: 10,
  79. textAlign: 'center',
  80. height: 30,
  81. lineHeight: '30px',
  82. })
  83. .contextmenu(() => {
  84. const downloaded = getDownloaded()
  85.  
  86. if (!downloaded.includes(musicInfo.songID)) {
  87. downloaded.push(musicInfo.songID)
  88. window.localStorage[downloadedKey] = JSON.stringify(downloaded)
  89. }
  90.  
  91. addDownloadedTag()
  92. })
  93.  
  94. box.append(downloadBtn)
  95. }
  96. const addMp3FileName = () => {
  97. if (!box || !musicInfo) return
  98.  
  99. const fileNameContaner = jQuery(`
  100. <div>
  101. 点击复制文件名
  102. <b></b><br />
  103. ${musicInfo.downloadFileName}
  104. </div>
  105. `)
  106. fileNameContaner
  107. .css({
  108. display: 'block',
  109. backgroundColor: '#ccc',
  110. color: '#000',
  111. padding: '5px 10px',
  112. borderRadius: 5,
  113. margin: 10,
  114. textAlign: 'center',
  115. height: 40,
  116. lineHeight: '20px',
  117. cursor: 'pointer',
  118. })
  119. .click(() => {
  120. copyToClipboard(musicInfo.downloadFileName)
  121. fileNameContaner.find('b').text('已复制')
  122. })
  123.  
  124. box.append(fileNameContaner)
  125. }
  126. const addDownloadedTag = () => {
  127. if (box.find('#downloaded').length) return
  128.  
  129. const downloadedTag = jQuery(`
  130. <div id="downloaded">
  131. <b>已下载</b>
  132. </div>
  133. `)
  134.  
  135. downloadedTag.css({
  136. position: 'absolute',
  137. top: -10,
  138. left: -10,
  139. zIndex: 99,
  140. backgroundColor: 'yellow',
  141. color: '#f00',
  142. borderRadius: '50%',
  143. border: '1px solid #f00',
  144. textAlign: 'center',
  145. width: 50,
  146. height: 50,
  147. lineHeight: '50px',
  148. transform: 'rotate(-45deg)',
  149. })
  150. box.prepend(downloadedTag)
  151. }
  152. const hidePalylistAd = () => {
  153. let i = 0
  154. const findAdLi = () => {
  155. if (i > 1000) return
  156.  
  157. const sprr = jQuery('#songlist li[id]')
  158.  
  159. setTimeout(() => {
  160. findAdLi()
  161. i++
  162. }, 1000)
  163.  
  164. sprr.hide()
  165. }
  166.  
  167. findAdLi()
  168. }
  169. const reShowPlayer = () => {
  170. feifa.html(`
  171. <div class="playingTit" style="color: yellow;">该歌曲侵犯相关权益人权利,九酷原站不提供试听</div>
  172. <div id="lrctext" style="display: none">
  173. <textarea id="lrc_content" style="display: block">[00:00.00]</textarea>
  174. </div>
  175. <div class="oldPlayer">
  176. <div id="jp_container_1" class="jp-audio">
  177. <div class="jp-type-single">
  178. <div class="jp-interface clearfix">
  179. <div class="playerMain-01">
  180. <div class="playName">
  181. </div>
  182. <div class="jp-time-holder">
  183. <div class="jp-current-time">00:00</div>
  184. /
  185. <div class="jp-duration">00:00</div>
  186. </div>
  187. </div>
  188. <div class="playerMain-02">
  189. <div class="jp-progress">
  190. <div class="jp-seek-bar" style="width: 0%">
  191. <div class="jp-play-bar" style="width: 0%"></div>
  192. </div>
  193. </div>
  194. </div>
  195. <div class="playerMain-03">
  196. <div class="fl">
  197. <ul class="jp-controls">
  198. <li>
  199. <a
  200. href="javascript:{};"
  201. onclick="javascript:vy.z=1;downlog(song_id,2,timeupd1);pu.PlayNext(-1);"
  202. class="jp-previous"
  203. tabindex="1"
  204. title="按键盘上的‘↑’或‘←’键切换到上一首"
  205. >上一首</a
  206. >
  207. </li>
  208. <li>
  209. <a
  210. href="javascript:{};"
  211. class="jp-play"
  212. tabindex="1"
  213. title="按键盘上的‘space(空格)’键在播放与暂停之间切换"
  214. >播放</a
  215. >
  216. </li>
  217. <li>
  218. <a
  219. href="javascript:{};"
  220. class="jp-pause"
  221. tabindex="1"
  222. title="按键盘上的‘space(空格)’键在播放与暂停之间切换"
  223. >暂停</a
  224. >
  225. </li>
  226. <li>
  227. <a
  228. href="javascript:{};"
  229. onclick="javascript:vy.z=1;downlog(song_id,2,timeupd1);pu.PlayNext(1);"
  230. class="jp-next"
  231. tabindex="1"
  232. title="按键盘上的‘→’或‘↓’键切换到下一首"
  233. >下一首</a
  234. >
  235. </li>
  236. </ul>
  237. </div>
  238. <div class="fr">
  239. <ul class="ku-volume">
  240. <li>
  241. <a
  242. href="javascript:{};"
  243. class="jp-mute"
  244. tabindex="1"
  245. title="静音"
  246. >静音</a
  247. >
  248. </li>
  249. <li>
  250. <a
  251. href="javascript:{};"
  252. class="jp-unmute"
  253. style="display: none"
  254. tabindex="1"
  255. title="取消静音"
  256. >取消静音</a
  257. >
  258. </li>
  259. <li class="volume-bar-wrap">
  260. <div class="jp-volume-bar">
  261. <div class="jp-volume-bar-value" style="width: 80%"></div>
  262. </div>
  263. </li>
  264. <li>
  265. <a
  266. href="javascript:{};"
  267. class="jp-volume-max"
  268. tabindex="1"
  269. title="最大音量"
  270. >最大音量</a
  271. >
  272. </li>
  273. </ul>
  274. </div>
  275. </div>
  276. </div>
  277. </div>
  278. </div>
  279. </div>
  280. `)
  281. window.ndPlayer = new window.KuPlayer()
  282. window.musiclist()
  283. }
  284. const checkMp3 = () => {
  285. if (!window.meida.mp3) {
  286. setTimeout(checkMp3, 200)
  287. return
  288. }
  289.  
  290. init()
  291. }
  292.  
  293. // 非法音乐,重新显示播放器
  294. if (feifa) {
  295. reShowPlayer()
  296. }
  297.  
  298. checkMp3()
  299. })(window.jQuery, window.copyToClipboard)

QingJ © 2025

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