您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
在听歌页面,提供该用户的所有歌曲下载
// ==UserScript== // @name 唱吧下载器 // @namespace http://tampermonkey.net/ // @version 0.2.4 // @description 在听歌页面,提供该用户的所有歌曲下载 // @author cw2012 // @match http*://changba.com/s/* // @icon https://changba.com/favicon.ico // @connect * // @require https://cdn.bootcdn.net/ajax/libs/jszip/3.5.0/jszip.min.js // @grant GM_xmlhttpRequest // @grant GM_download // @run-at document-end // ==/UserScript== // 2021-01 歌手个人主页已不可用: http*://changba.com/u/* function newSong(id, name,enworkid, hasMV){ let song = new Object(); song.id = id; song.name = name; song.enworkid = enworkid; song.hasMV = hasMV; return song; } // 利用blob下载文件 function downloadFileByBlob(blobContent, filename) { const blobUrl = URL.createObjectURL(blobContent) const eleLink = document.createElement('a') eleLink.download = filename eleLink.style.display = 'none' eleLink.href = blobUrl eleLink.click(); } (function() { 'use strict'; //首先禁止自动播放,烦死了 let audioEle = document.getElementById('audio'); if(audioEle){ audioEle.autoplay = false; } insertCss(); let userId, userName=document.querySelector('.ulevel').innerText; let pageIndex = 0, curSongIndex = 0; let songList = [], songCount, zip, mvCount = 0; $('span.info').css('width','60px'); let sibling = document.querySelector('span.fav'); sibling.parentNode.innerHTML = '<span class="export info" style="width:60px" data-status="0" id="btn_download"><em>下载</em></span>'+ sibling.parentNode.innerHTML; document.getElementById('btn_download').addEventListener('click',()=>{ if(audioEle){ GM_download({ url: audioEle.src, name: `${userName}-${$('.title').html()}.mp3` }); }else{ GM_download({ url:document.getElementById('jp_video_0').src, name: `${userName}-${$('.title').html()}.mp4` }); } }); addListBox(); analysisSongList(); function addListBox(){ let listBox= document.createElement('div'); listBox.id = 'songListBox'; let titleDiv = document.createElement('div'); titleDiv.className ='widget-header-simple song-list-title'; titleDiv.innerHTML = '<p id="songListTitle" style="font-size:16px">正在解析用户作品列表</p>'; listBox.append(titleDiv); document.body.append(listBox); } function analysisSongList(){ userId = document.querySelector('.focus').getAttribute('data-userid'); let tmpEle = document.querySelectorAll('.ulevel>a.uname')[0]; tmpEle.onclick = ()=>{window.open('https://changba.com/wap/index.php?s='+document.querySelector('.focus').getAttribute('data-userid'),'_blank')}; updateSongList(); } function updateSongList(){ GM_xmlhttpRequest({ url: `https://changba.com/member/personcenter/loadmore.php?ver=1&pageNum=${pageIndex>0?pageIndex:''}&type=0&userid=${userId}`, method: 'get', timeout: 15000, responseType : 'json', onload: res=>{ pageIndex++; const data = res.response; if(data.length>0){ for(var i = 0; i< data.length;i++){ if(data[i].ismv ==`style='display:inline'`){ songList.push(newSong(data[i].workid, data[i].songname, data[i].enworkid, true)); mvCount++; }else{ songList.push(newSong(data[i].workid, data[i].songname, data[i].enworkid, false)); } } updateSongList(); }else{ showSongList(); } }, ontimeout:()=>{console.log('获取列表超时'+pageIndex)}, onerror: err=>{ alert(`获取歌曲列表失败`); } }); } function showSongList(){ document.getElementById('songListTitle').innerText = `该用户有${songList.length}首歌${mvCount?('(其中包含'+mvCount+'个MV)'):''}`; let songListDiv = document.createElement('div'); songListDiv.className = 'songList'; let ol = document.createElement('ol'); songList.forEach((item,index)=>{ let li = document.createElement('li'); li.className = 'song'; let a = document.createElement('a'); a.innerText = '下载'; a.href = '#'; let span = document.createElement('span'); span.innerText = item.name; if(item.hasMV){ let img = document.createElement('img'); img.className = 'mv'; img.src='https://www.zhangxinxu.com/study/image/pixel.gif'; span.append(img); } a.addEventListener('click',()=>{ downloadSingleSong(item,a); }); li.append(span); li.append(a); a = document.createElement('a'); a.innerText = '查看'; a.href = 'https://changba.com/s/' + item.enworkid; li.append(a); ol.append(li); }); songListDiv.append(ol); document.getElementById('songListBox').append(songListDiv); } function downloadSingleSong(song,a){ let id= song.id, name=song.name,enworkid=song.enworkid; let fileName = `${userName}-${name}${song.hasMV?'.mp4':'.mp3'}`; let progress = document.createElement('progress'); progress.value= 0; progress.max = 100; GM_xmlhttpRequest({ url: `https://changba.com/s/${enworkid}`, method: 'get', timeout: 5000, onload: res =>{ let html = res.responseText; let index = html.indexOf(song.hasMV?'video_url:':'commonObj.url'); if(index!=-1){ html = html.substr(index, 200); html = html.match(/'[\w/=+]+'/g)[0]; html = html.substr(1, html.length -2); let url = getMp3Url(html); if(song.hasMV) url = 'http:'+getMp4Url(url); a.parentElement.insertBefore(progress, a); GM_download({ url: url, name: fileName, onprogress: prog=>{progress.value = prog.loaded;progress.max = prog.total;}, onload: res=>{ progress.remove();}, ontimeout: res=>{alert(`下载"${fileName}"超时,请重试`); progress.remove();}, onerror:res=>{alert(`下载"${fileName}"出错,请重试`); progress.remove();} }); } } }); } function getMp3Url(html){ var km= 'a17fe74e421c2cbf3dc323f4b4f3a1af' , iv = CryptoJS.enc.Utf8.parse(km.substring(0,16)) , iv2 = CryptoJS.enc.Utf8.parse(km.substring(16)) , audio_url = ''; audio_url = CryptoJS.AES.decrypt(html, iv2, { 'iv': iv, 'padding': CryptoJS.pad.Pkcs7 })['toString'](CryptoJS.enc.Utf8); return audio_url; } function getMp4Url(origin_video_url){ var arr = new Array(-0x1,-0x1,-0x1,-0x1,-0x1,-0x1,-0x1,-0x1,-0x1,-0x1,-0x1,-0x1,-0x1,-0x1,-0x1,-0x1,-0x1,-0x1,-0x1,-0x1,-0x1,-0x1,-0x1,-0x1,-0x1,-0x1,-0x1,-0x1,-0x1,-0x1,-0x1,-0x1,-0x1,-0x1,-0x1,-0x1,-0x1,-0x1,-0x1,-0x1,-0x1,-0x1,-0x1,0x3e,-0x1,-0x1,-0x1,0x3f,0x34,0x35,0x36,0x37,0x38,0x39,0x3a,0x3b,0x3c,0x3d,-0x1,-0x1,-0x1,-0x1,-0x1,-0x1,-0x1,0x0,0x1,0x2,0x3,0x4,0x5,0x6,0x7,0x8,0x9,0xa,0xb,0xc,0xd,0xe,0xf,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,-0x1,-0x1,-0x1,-0x1,-0x1,-0x1,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f,0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29,0x2a,0x2b,0x2c,0x2d,0x2e,0x2f,0x30,0x31,0x32,0x33,-0x1,-0x1,-0x1,-0x1,-0x1); var charCode1, charCode2, charCode3, charCode4, i, length, resultStr; for (length = origin_video_url['length'], i = 0x0, resultStr = ''; i < length;) { do { charCode1 = arr[0xff & origin_video_url['charCodeAt'](i++)]; } while (i < length && -0x1 == charCode1); if (-0x1 == charCode1) break; do { charCode2 = arr[0xff & origin_video_url['charCodeAt'](i++)]; } while (i < length && -0x1 == charCode2); if (-0x1 == charCode2) break; resultStr += String['fromCharCode'](charCode1 << 0x2 | (0x30 & charCode2) >> 0x4); do { if (0x3d == (charCode3 = 0xff & origin_video_url['charCodeAt'](i++))) return resultStr; charCode3 = arr[charCode3]; } while (i < length && -0x1 == charCode3); if (-0x1 == charCode3) break; resultStr += String['fromCharCode']((0xf & charCode2) << 0x4 | (0x3c & charCode3) >> 0x2); do { if (0x3d == (charCode4 = 0xff & origin_video_url['charCodeAt'](i++))) return resultStr; charCode4 = arr[charCode4]; } while (i < length && -0x1 == charCode4); if (-0x1 == charCode4) break; resultStr += String['fromCharCode']((0x3 & charCode3) << 0x6 | charCode4); } return resultStr; } // 显示下载进度 function progress(){ let bar = document.getElementById('progressBar'); if(bar){ document.getElementById('prog-num').innerText = `正在下载:${curSongIndex + 1}/${songCount}`; document.getElementById('song-name').innerText = songList[curSongIndex].name; if(curSongIndex + 1 == songCount){ bar.remove(); } return; } let progressBox = document.createElement('div'); progressBox.id = 'progressBar'; progressBox.style.position = 'fixed'; progressBox.style.background='white'; progressBox.style.borderRadius='10px'; progressBox.style.background= `rgb(255 80 70)`; progressBox.style.border = 'solid white 1px'; progressBox.style.boxShadow='0 8px 16px 0 rgba(0,0,0,.2), 0 6px 20px 0 rgba(0,0,0,.19)'; progressBox.style.color = '#fff'; progressBox.style.bottom='200px'; // 显示的位置不能离底部太低了,会被其他元素遮挡 progressBox.style.left='2vh'; progressBox.style.transition='1.5s'; progressBox.style.padding = '10px'; let progNum = document.createElement('p'); progNum.id = 'prog-num'; progNum.innerText = `1/${songCount}`; let downName = document.createElement('p'); downName.id = 'song-name'; downName.innerText='正在下载...'; progressBox.append(progNum); progressBox.append(downName); document.body.appendChild(progressBox); } })(); function insertCss(){ var style=document.createElement('style'); const myStyle = ` #songListBox{ position:fixed; height:400px; width:400px; border-radius:0px 10px 10px 0px; box-shadow:#fba9a9 3px 4px 40px 1px; top:100px; } .widget-header-simple.song-list-title{ color:#fff; text-align:center; display:flex; align-items:center; justify-content:center; border-radius:0px 10px 0px 0px; } ol{ padding:10px; } li.song{ margin:10px 0; font-size:14px; color:black; padding: 5px; background: #ffeded; display: flex; align-items: center; justify-content: space-evenly; flex-direction: row; } li.song span{ width: 210px; } div.songList{ overflow: scroll; overflow-y: auto; overflow-x: hidden; height: 330px; } .mv{ background: url(https://greasyfork.s3.us-east-2.amazonaws.com/xv0qosox3hocgp4jni3qydurnlom) no-repeat; background-size: 100% 100%; width: 25px; height: 25px; margin-left: 4px; } li a { color: #ff142e; } /*进度条的样式*/ progress{ width:40px; height:15px; } progress::-webkit-progress-value { background-color:#ff0040; } `; style.type='text/css'; if(style.styleSheet){ style.styleSheet.cssText=myStyle; }else{ style.appendChild(document.createTextNode(myStyle)); } document.getElementsByTagName('head')[0].appendChild(style); }
QingJ © 2025
镜像随时可能失效,请加Q群300939539或关注我们的公众号极客氢云获取最新地址