唱吧下载器

在个人主页添加下载按钮

当前为 2020-12-26 提交的版本,查看 最新版本

您需要先安装一个扩展,例如 篡改猴Greasemonkey暴力猴,之后才能安装此脚本。

您需要先安装一个扩展,例如 篡改猴暴力猴,之后才能安装此脚本。

您需要先安装一个扩展,例如 篡改猴暴力猴,之后才能安装此脚本。

您需要先安装一个扩展,例如 篡改猴Userscripts ,之后才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。

您需要先安装用户脚本管理器扩展后才能安装此脚本。

(我已经安装了用户脚本管理器,让我安装!)

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

(我已经安装了用户样式管理器,让我安装!)

// ==UserScript==
// @name         唱吧下载器
// @namespace    http://tampermonkey.net/
// @version      0.1
// @description  在个人主页添加下载按钮
// @author       cw2012
// @match        http*://changba.com/u/*
// @match        http*://changba.com/s/*
// @icon         http://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==

(function() {
    'use strict';

    let isUserPage = location.href.split('/')[3] == 'u';
    let userId, userName;
    let pageIndex = 0, curSongIndex = 0;
    let songList = [], songCount, zip;
    if(isUserPage){
        userName = document.querySelector('.userPage-user-name.twemoji').innerText;
        let tmp = document.querySelectorAll('script');
        for(var i=0;i<tmp.length;i++){
            if(tmp[i].innerText!=''){
                let datas = tmp[i].innerText.split('\'');
                userId = datas[1];
                songCount = parseInt(datas[5]);
                let btnBox = document.querySelector('.userPage-tab');
                let btn = document.createElement('li');
                btn.style.position = 'absolute';
                btn.style.left = '10px';
                btn.innerText = '下载所有歌曲';
                btn.style.color = 'rgb(255 115 78)';
                btn.style.paddingLeft = '21px';
                btn.style.fontSize = '14px';
                btn.style.cursor = 'pointer';
                btnBox.insertBefore(btn, document.querySelector('li[data-name]'));
                btn.addEventListener('click',downloadSongList);
                updateSongList();
                break;
            }
        }
    }else{
        $('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',()=>{
            GM_download({
                url: document.getElementById('audio').src,
                name: `${$('.title').html()}.mp3`
        });
        });
    }

    // download btn ico
    // http://cb.cdn.changbaimg.com/images/views/export-hover.png

    // 歌曲页的歌曲列表获取
    function updateSongList(){
        zip = new JSZip();
        GM_xmlhttpRequest({
            url: `http://changba.com/member/personcenter/loadmore.php?ver=1&pageNum=${pageIndex++}&type=0&userid=${userId}`,
            method: 'get',
            timeout: 5000,
            responseType : 'json',
            onload: res=>{
                const data = res.response;
                if(data.length>0){
                    for(var i = 0; i< data.length;i++){
                        songList.push(newSong(data[i].workid, data[i].songname, data[i].enworkid));
                    }
                    if(songList.length<songCount){
                        updateSongList();
                    }
                }
            },
            onerror: err=>{
                alert(`获取歌曲列表失败`);
            }
        });
    }
    // 列表加载完成,下载打包
    function downloadSongList(){
        if(songCount > 1){
            let item = songList[curSongIndex];
            loopDownload(item);
        }
    }
    function loopDownload(song){
        GM_xmlhttpRequest({
            url: `http://upscuw.changba.com/${song.id}.mp3`,
            method: 'get',
            timeout: 5000,
            responseType : 'blob',
            onload: res =>{
                if(res.response.size>1024){
                    const mp3Data = new File([res.response], song.name);
                    zip.file(`${song.name}.mp3`, mp3Data, { base64: true });
                    zip.generateAsync({type: 'blob'}).then(
                        contentWithTxt=> {
                            if(++curSongIndex == songCount){
                                downloadFileByBlob(contentWithTxt, userName);
                            }else{
                                progress();
                                console.log(`歌曲《${song.name}》下载成功`);
                                song = songList[curSongIndex];
                                loopDownload(song);
                            }
                        }
                    );
                }else{
                    retryDownload(song);
                }
            }
        });
    }
    // 地址不太一样的歌曲,需要重试
    function retryDownload(song){
        GM_xmlhttpRequest({
            url: `http://changba.com/s/${song.enworkid}`,
            method: 'get',
            timeout: 5000,
            onload: res1 =>{
                let html = res1.responseText;
                let urls = html.match(/http*:\/\/[\d\w-.\/]+\.mp3/g);
                if(urls.length>0){
                    GM_xmlhttpRequest({
                        url: urls[0],
                        method: 'get',
                        timeout: 5000,
                        responseType : 'blob',
                        onload: res2 =>{
                            if(res2.response.size>1024){
                                const mp3Data = new File([res2.response], song.name);
                                zip.file(`${song.name}.mp3`, mp3Data, { base64: true });
                                zip.generateAsync({type: 'blob'}).then(contentWithTxt=> {
                                    if(++curSongIndex == songCount){
                                        downloadFileByBlob(contentWithTxt, userName)
                                    }else{
                                        progress();
                                        let song = songList[curSongIndex];
                                        loopDownload(song);
                                    }
                                });
                            }else{
                                ++curSongIndex;
                                console.log(`歌曲《${song.name}》下载失败`);
                            }
                        }
                    });
                }
            },
            onerror: err=>{
                console.log(`歌曲《${song.name}》下载失败`);
            }
        });
    }
    // 显示下载进度
    function progress(){
        let bar = document.getElementById('progressBar');
        if(bar){
            document.getElementById('prog-num').innerText = `正在下载:${curSongIndex}/${songCount}`;
            document.getElementById('song-name').innerText = songList[curSongIndex].name;
            if(curSongIndex == 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 = `0/${songCount}`;
        let downName = document.createElement('p');
        downName.id = 'song-name';
        downName.innerText='正在下载...';
        progressBox.append(progNum);
        progressBox.append(downName);
        document.body.appendChild(progressBox);
    }
})();

function newSong(id, name,enworkid){
    let song = new Object();
    song.id = id;
    song.name = name;
    // song.singleDownload = singleDownload;
    song.enworkid = enworkid;
    // song.download = download;
    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();
}