[伟哥自用修改版]喜马拉雅专辑下载器@江东小霸王
// ==UserScript==
// @name [伟哥自用修改版]喜马拉雅专辑下载器@江东小霸王
// @version 1.3.1
// @description 可能是你见过最丝滑的喜马拉雅下载器啦!登录后支持VIP音频下载,支持专辑批量下载,支持添加编号,链接导出、调用aria2等功能,直接下载M4A,MP3、MP4文件。
// @author Priate
// @match *://www.ximalaya.com/*
// @grant GM_xmlhttpRequest
// @grant GM_setValue
// @grant GM_getValue
// @grant GM_addStyle
// @grant GM_setClipboard
// @grant GM_download
// @icon https://www.ximalaya.com/favicon.ico
// @require https://registry.npmmirror.com/vue/2.7.16/files/dist/vue.min.js
// @require https://cdn.jsdelivr.net/npm/sweetalert2@11
// @require https://registry.npmmirror.com/jquery/3.2.1/files/dist/jquery.min.js
// @require https://greasyfork.org/scripts/435476-priatelib/code/PriateLib.js?version=1202493
// @require https://registry.npmmirror.com/ajax-hook/2.0.3/files/dist/ajaxhook.min.js
// @require https://registry.npmmirror.com/crypto-js/4.1.1/files/crypto-js.js
// @supportURL https://greasyfork.org/zh-CN/scripts/435495/feedback
// @homepageURL https://greasyfork.org/zh-CN/scripts/435495
// @contributionURL https://afdian.net/@cyberubbish
// @license MIT
// @namespace https://greasyfork.org/users/219866
// ==/UserScript==
(function() {
'use strict';
// @require https://registry.npmmirror.com/sweetalert/2.1.2/files/dist/sweetalert.min.js
function initSetting() {
var setting;
if (!GM_getValue('priate_script_xmly_data')) {
GM_setValue('priate_script_xmly_data', {
// 多线程下载
multithreading: false,
left: 20,
top: 100,
manualMusicURL: null,
quality: 1,
showNumber: true,
numberOffset: 0,
pageSize: 30,
aria2: "ws://127.0.0.1:16800/jsonrpc"
})
}
setting = GM_getValue('priate_script_xmly_data')
//后期添加内容
if (!setting.quality) setting.quality = 1;
// 暂时统一为高清音质
setting.quality = 1
if (setting.showNumber === null) setting.showNumber = true;
if (!setting.numberOffset) setting.numberOffset = 0;
if (!setting.pageSize) setting.pageSize = 30;
if (!setting.aria2) setting.aria2 = "ws://127.0.0.1:16800/jsonrpc"
GM_setValue('priate_script_xmly_data', setting)
}
// 手动获取音频地址功能
function manualGetMusicURL() {
let windowID = getRandStr("1234567890qwertyuiopasdfghjklzxcvbnmQWERTYUIOPASDFGHJKLZXCVBNM", 100)
function getRandStr(chs, len) {
let str = "";
while (len--) {
str += chs[parseInt(Math.random() * chs.length)];
}
return str;
}
(function() {
let playOriginal = HTMLAudioElement.prototype.play;
function play() {
let link = this.src;
window.top.postMessage(Array("audioVideoCapturer", link, windowID, "link"), "*");
return playOriginal.call(this);
}
HTMLAudioElement.prototype.play = play;
HTMLAudioElement.prototype.play.toString = HTMLAudioElement.prototype.play.toString.bind(playOriginal);
})();
if (window.top == window) {
window.addEventListener("message", function(event) {
if (event.data[0] == "audioVideoCapturer") {
var setting = GM_getValue('priate_script_xmly_data')
setting.manualMusicURL = event.data[1]
GM_setValue('priate_script_xmly_data', setting)
}
});
}
}
manualGetMusicURL()
function injectDiv() {
var priate_script_div = document.createElement("div")
priate_script_div.innerHTML = `
<div id="priate_script_div">
<b style='font-size:30px; font-weight:300; margin: 10px 20px'>喜马拉雅专辑下载器</b>
<p id='priate_script_setting' style='margin: 0 0'>
❤️ by <a @click='openDonate' style='color:#337ab7'>Priate</a> |
v <a href="//greasyfork.org/zh-CN/scripts/435495" target="_blank" style='color:#ff6666'>{{version}}</a> |
音质 : <a @click='changeQuality' :style='"color:" + qualityColor'>{{qualityStr}}</a>
<br>
编号 : <a @click='switchShowNumber' :style='"color:" + (setting.showNumber ? "#00947e" : "#CC0F35")'> {{ setting.showNumber ? "开启" : "关闭"}} </a> -
<a @click='addNumberOffset' @contextmenu.prevent='subNumberOffset' :style='"color:" + (setting.showNumber ? "#3311AA" : "#CC0F35")'> {{ setting.numberOffset }} </a> |
<a @click='addNumberOffset30' :style='"color:" + (setting.showNumber ? "#3311AA" : "#CC0F35")'> 加三十 </a> |
数量 : <a @click='changePageSize' style='color:#3311AA'> {{ setting.pageSize }} </a> |
<a style='color:#ff6666' @click='clearMusicData'>❌</a>
</p>
<button v-show="!isDownloading" @click="loadMusic">{{filterData.length > 0 ? '重载数据' : '加载数据'}}</button>
<button id='readme' @click="downloadAllMusics" v-show="!isDownloading && (musicList.length > 0)">下载所选</button>
<button @click="exportAllMusicURL" v-show="!isDownloading && (musicList.length > 0)">导出数据 <b v-show="copyMusicURLProgress">{{copyMusicURLProgress}}%</b></button>
<button @click="cancelDownload" v-show="isDownloading">取消下载</button>
</br>
<table v-show="filterData.length > 0">
<thead><tr><th><a style='color:#337ab7' @click='selectAllMusic'>全选</a></th><th>标题</th><th>操作</th></tr></thead>
<tbody id="priate_script_table">
<tr v-for="(item, index) in filterData" :key="index">
<td><input class="checkMusicBox" v-model="musicList" :value='item' type="checkbox" :disabled="item.isDownloaded || isDownloading"></td>
<td><a @click="openMusicURL(item)" style='color:#337ab7'>{{item.title}}</a></td>
<td>
<a v-show="!item.isDownloading && !item.isDownloaded && !isDownloading" style='color:#993333' @click="downloadMusic(item)">下载</a>
<a v-show="isDownloading && !item.isDownloading && !item.isDownloaded" style='color:gray'>等待中</a>
<a v-show="item.isDownloading" style='color:#C01D07'>{{item.progress}}</a>
<a v-show="item.isDownloaded" style='color:#00947E'>已下载</a>
<a v-show="item.isFailued" style='color:red'>下载失败</a> |
<a :style="'color:' + (item.url ? '#00947E' : '#993333')" @click="copyMusic(item)">地址</a></td>
</tr>
</tbody>
</table>
</div>
`
GM_addStyle(`
#priate_script_div{
font-size : 15px;
position: fixed;
background-color: rgb(240, 223, 175);
color : #660000;
text-align : center;
padding: 10px;
z-index : 9999;
border-radius : 20px;
border:2px solid #660000;
font-weight: 300;
-webkit-text-stroke: 0.5px;
text-stroke: 0.5px;
box-shadow: 5px 15px 15px rgba(0,0,0,0.4);
user-select : none;
-webkit-user-select : none;
-moz-user-select : none;
-ms-user-select:none;
}
#priate_script_div:hover{
box-shadow: 5px 15px 15px rgba(0,0,0,0.8);
transition: box-shadow 0.3s;
}
.priate_script_hide{
padding: 0 !important;
border:none !important;
}
a{
cursor : pointer;
text-decoration : none;
}
/*表格样式*/
#priate_script_div table{
text-align: center;
// border:2px solid #660000;
margin: 5px auto;
padding: 2px;
border-collapse: collapse;
display: block;
height : 400px;
overflow-y: scroll;
}
/*表格框样式*/
#priate_script_div td{
border:2px solid #660000;
padding: 8px 12px;
max-width : 300px;
word-wrap : break-word;
}
/*表头样式*/
#priate_script_div th{
border:2px solid #660000;
padding: 8px 12px;
font-weight: 300;
-webkit-text-stroke: 0.5px;
text-stroke: 0.5px;
}
/*脚本按钮样式*/
#priate_script_div button{
display: inline-block;
border-radius: 4px;
border: 1px solid #660000;
background-color: transparent;
color: #660000;
text-decoration: none;
padding: 5px 10px;
margin : 5px 10px;
font-weight: 300;
-webkit-text-stroke: 0.5px;
text-stroke: 0.5px;
}
/*脚本按钮悬浮样式*/
#priate_script_div button:hover{
cursor : pointer;
color: rgb(240, 223, 175);
background-color: #660000;
transition: background-color 0.2s;
}
/*设置区域 p 标签*/
#priate_script_setting{
user-select : none;
-webkit-user-select : none;
-moz-user-select : none;
-ms-user-select:none;
}
/*输入框样式*/
#priate_script_div textarea{
height : 50px;
width : 200px;
background-color: #fff;
border:1px solid #000000;
padding: 4px;
}
/*swal按钮*/
.swal-button--1{
background-color: #FFFAEB !important;
color: #946C00;
}
.swal-button--2{
background-color: #ebfffc !important;
color: #00947e;
}
.swal-button--3{
background-color: #ECF6FD !important;
color: #55ACEE;
}
.checkMusicBox{
transform: scale(1.7,1.7);
cursor: pointer;
}
`);
document.querySelector("html").appendChild(priate_script_div)
var setting = GM_getValue('priate_script_xmly_data')
document.getElementById("priate_script_div").style.left = (setting.left || 20) + "px";
document.getElementById("priate_script_div").style.top = (setting.top || 100) + "px";
}
function dragFunc(id) {
var Drag = document.getElementById(id);
var setting = GM_getValue('priate_script_xmly_data')
Drag.onmousedown = function(event) {
var ev = event || window.event;
event.stopPropagation();
var disX = ev.clientX - Drag.offsetLeft;
var disY = ev.clientY - Drag.offsetTop;
document.onmousemove = function(event) {
var ev = event || window.event;
setting.left = ev.clientX - disX
Drag.style.left = setting.left + "px";
setting.top = ev.clientY - disY
Drag.style.top = setting.top + "px";
Drag.style.cursor = "move";
GM_setValue('priate_script_xmly_data', setting)
};
};
Drag.onmouseup = function() {
document.onmousemove = null;
this.style.cursor = "default";
};
};
// 初始化音质修改
function initQuality() {
ah.proxy({
onRequest: (config, handler) => {
handler.next(config);
},
onError: (err, handler) => {
handler.next(err)
},
onResponse: (response, handler) => {
const setting = GM_getValue('priate_script_xmly_data')
// hook返回数据
if (response.config.url.indexOf("mobile.ximalaya.com/mobile-playpage/track/v3/baseInfo") != -1) {
const setting = GM_getValue('priate_script_xmly_data')
const data = JSON.parse(response.response)
const playUrlList = data.trackInfo.playUrlList
var replaceUrl;
for (var num = 0; num < playUrlList.length; num++) {
var item = playUrlList[num]
if (item.qualityLevel == setting.quality) {
replaceUrl = item.url
break
}
}
replaceUrl && playUrlList.forEach((item) => {
item.url = replaceUrl
})
response.response = JSON.stringify(data)
}
// hook普通音频获取高品质,实际上只需删除获取到的src即可
if (setting.quality == 2 && response.config.url.indexOf("www.ximalaya.com/revision/play/v1/audio") != -1) {
const setting = GM_getValue('priate_script_xmly_data')
var resp = JSON.parse(response.response)
var data = resp.data
delete data.src
response.response = JSON.stringify(resp)
}
handler.next(response)
}
})
unsafeWindow.XMLHttpRequest = XMLHttpRequest
}
// 修改翻页大小
function initPageSize() {
const originFetch = fetch;
const setting = GM_getValue('priate_script_xmly_data')
window.unsafeWindow.fetch = (url, options) => {
if (url.indexOf('/revision/album/v1/getTracksList') != -1) {
url = url.replace('pageSize=30', `pageSize=${setting.pageSize}`)
}
return originFetch(url, options).then(async (response) => {
return response;
});
};
}
//初始化脚本设置
initSetting()
//注入脚本div
injectDiv()
// 初始化音质修改
initQuality()
// 修改翻页大小
initPageSize()
// 第一种获取musicURL的方式,任意用户均可获得,不可获得VIP音频
async function getSimpleMusicURL1(item) {
var res = null
if (item.url) {
res = item.url
} else {
const timestamp = Date.parse(new Date());
var url = `https://mobwsa.ximalaya.com/mobile-playpage/playpage/tabs/${item.id}/${timestamp}`
$.ajax({
type: 'get',
url: url,
async: false,
dataType: "json",
success: function(resp) {
if (resp.ret === 0) {
const setting = GM_getValue('priate_script_xmly_data')
const trackInfo = resp.data.playpage.trackInfo;
if (setting.quality == 0) {
res = trackInfo.playUrl32
} else if (setting.quality == 1) {
res = trackInfo.playUrl64
}
// res = res || trackInfo.downloadUrl
}
}
});
}
return res
}
// 第二种获取musicURL的方式,任意用户均可获得,不可获得VIP音频
async function getSimpleMusicURL2(item) {
var res = null
if (item.url) {
res = item.url
} else {
var url = `https://www.ximalaya.com/revision/play/v1/audio?id=${item.id}&ptype=1`
$.ajax({
type: 'get',
url: url,
async: false,
dataType: "json",
success: function(resp) {
if (resp.ret == 200) res = resp.data.src;
}
});
}
return res
}
//获取任意音频方法
async function getAllMusicURL1(item) {
var res = null
var setting;
if (item.url) {
res = item.url
} else {
const all_li = document.querySelectorAll('.sound-list>ul li');
for (var num = 0; num < all_li.length; num++) {
var li = all_li[num]
const item_a = li.querySelector('a');
const id = item_a.href.split('/')[item_a.href.split('/').length - 1]
if (id == item.id) {
li.querySelector('div.all-icon').click()
while (!res) {
await Sleep(1)
setting = GM_getValue('priate_script_xmly_data')
res = setting.manualMusicURL
}
setting.manualMusicURL = null
GM_setValue('priate_script_xmly_data', setting)
li.querySelector('div.all-icon').click()
break
}
}
}
if (!res && item.isSingle) {
document.querySelector('div.play-btn').click()
while (!res) {
await Sleep(1)
setting = GM_getValue('priate_script_xmly_data')
res = setting.manualMusicURL
}
setting.manualMusicURL = null
GM_setValue('priate_script_xmly_data', setting)
document.querySelector('div.play-btn').click()
}
return res
}
// 通过解密数据的方式获取 URL
async function getAllMusicURL2(item) {
function decrypt(t) {
return CryptoJS.AES.decrypt({
ciphertext: CryptoJS.enc.Base64url.parse(t)
}, CryptoJS.enc.Hex.parse('aaad3e4fd540b0f79dca95606e72bf93'), {
mode: CryptoJS.mode.ECB,
padding: CryptoJS.pad.Pkcs7
}).toString(CryptoJS.enc.Utf8)
}
var res = null
if (item.url) {
res = item.url
} else {
const timestamp = Date.parse(new Date());
var url = `https://www.ximalaya.com/mobile-playpage/track/v3/baseInfo/${timestamp}?device=web&trackId=${item.id}`
$.ajax({
type: 'get',
url: url,
async: false,
dataType: "json",
success: function(resp) {
try {
res = decrypt(resp.trackInfo.playUrlList[0].url)
} catch (e) {
console.log("解密错误")
res = null
}
}
});
}
return res
}
// 处理数据等逻辑
var vm = new Vue({
el: '#priate_script_div',
data: {
version: "1.3.1",
copyMusicURLProgress: 0,
setting: GM_getValue('priate_script_xmly_data'),
data: [],
musicList: [],
isDownloading: false,
cancelDownloadObj: null,
stopDownload: false,
},
methods: {
loadMusic() {
const whiteList = ['sound', 'album']
const type = location.pathname.split('/')[location.pathname.split('/').length - 2]
if (whiteList.indexOf(type) < 0) {
swal("请先进入一个专辑页面并等待页面完全加载!", {
icon: "error",
buttons: false,
timer: 3000,
});
this.data = []
this.musicList = []
return
}
const all_li = document.querySelectorAll('.sound-list>ul li');
var result = [];
var _this = this
let ggg = 0
all_li.forEach((item) => {
const item_a = item.querySelector('a');
let number = item.querySelector('span.num') ? parseInt(item.querySelector('span.num').innerText) : 0
ggg +=1
number = ggg
const title = item_a.title.trim().replace(/\\|\/|\?|\?|\*|\"|\“|\”|\'|\‘|\’|\<|\>|\{|\}|\[|\]|\【|\】|\:|\:|\、|\^|\$|\!|\~|\`|\|/g, '').replace(/\./g, '-')
const music = {
id: item_a.href.split('/')[item_a.href.split('/').length - 1],
number,
// title: _this.setting.showNumber ? `${number + _this.setting.numberOffset - 1}-${title}` : title,
title: _this.setting.showNumber ? `${String(number + _this.setting.numberOffset - 1).padStart(3, '0')}-${title}` : title,
isDownloading: false,
isDownloaded: false,
progress: 0,
}
result.push(music)
})
// 如果没有获取到数据,则判断为单个音频
if (result.length == 0 && type == 'sound') {
const music = {
id: location.pathname.split('/')[location.pathname.split('/').length - 1],
title: document.querySelector('h1.title-wrapper').innerText,
isDownloading: false,
isDownloaded: false,
progress: 0,
isSingle: true
}
result.push(music)
}
// 如果仍未获取到数据
if (result.length == 0) {
swal("未获取到数据,请进入一个专辑页面并等待页面完全加载!", {
icon: "error",
buttons: false,
timer: 3000,
});
}
this.data = result
this.musicList = []
this.data.forEach((item) => {
this.musicList.push(item)
})
},
async getMusicURL(item) {
var res = await getSimpleMusicURL1(item)
res = res || await getSimpleMusicURL2(item)
res = res || await getAllMusicURL2(item)
res = res || await getAllMusicURL1(item)
this.$set(item, 'url', res)
return res
},
async openMusicURL(item) {
item.url = item.url || await this.getMusicURL(item)
window.open(item.url)
},
async downloadMusic(item) {
//this.isDownloading = true
item.isDownloading = true
item.isFailued = false
var _this = this
const details = {
url: item.url || await this.getMusicURL(item),
name: item.title.trim().replace(/\\|\/|\?|\?|\*|\"|\“|\”|\'|\‘|\’|\<|\>|\{|\}|\[|\]|\【|\】|\:|\:|\、|\^|\$|\!|\~|\`|\|/g, '').replace(/\./g, '-'),
onload: function(e) {
_this.isDownloading = false
item.isDownloading = false
item.isDownloaded = true
_this.selectAllMusic()
},
onerror: function(e) {
_this.isDownloading = false
console.log(e)
item.isDownloading = false
if (e.error != 'aborted') item.isFailued = true
},
onprogress: function(d) {
item.progress = (Math.round(d.loaded / d.total * 10000) / 100.00) + "%";
}
}
this.cancelDownloadObj = GM_download(details)
},
// 顺序下载
async sequenceDownload(index, data) {
this.isDownloading = true
const item = data[index]
if (!item) {
this.isDownloading = false
this.selectAllMusic()
this.stopDownload = false
return;
};
if (item.isDownloading || item.isDownloaded || this.stopDownload) return this.sequenceDownload(index + 1, data);
item.isDownloading = true
item.isFailued = false
const _this = this
const details = {
url: item.url || await this.getMusicURL(item),
name: item.title.trim().replace(/\\|\/|\?|\?|\*|\"|\“|\”|\'|\‘|\’|\<|\>|\{|\}|\[|\]|\【|\】|\:|\:|\、|\^|\$|\!|\~|\`|\|/g, '').replace(/\./g, '-'),
onload: function(e) {
item.isDownloading = false
item.isDownloaded = true
_this.cancelDownloadObj = _this.sequenceDownload(index + 1, data)
},
onerror: function(e) {
console.log(e)
item.isDownloading = false
if (e.error != 'aborted') item.isFailued = true
_this.cancelDownloadObj = _this.sequenceDownload(index + 1, data)
},
onprogress: function(d) {
item.progress = (Math.round(d.loaded / d.total * 10000) / 100.00) + "%";
}
}
this.cancelDownloadObj = GM_download(details)
return this.cancelDownloadObj
},
async copyMusic(item) {
item.url = item.url || await this.getMusicURL(item)
GM_setClipboard(item.url)
},
// 下载当前列表全部音频
async downloadAllMusics() {
await this.sequenceDownload(0, this.musicList)
},
async copyAllMusicURL() {
this.copyMusicURLProgress = 0
var res = []
for (var num = 0; num < this.musicList.length; num++) {
var item = this.musicList[num];
const url = await this.getMusicURL(item)
await Sleep(0.01)
this.copyMusicURLProgress = Math.round((num + 1) / this.musicList.length * 10000) / 100.00;
res.push(url)
}
GM_setClipboard(res.join('\n'))
swal("复制成功!", {
icon: "success",
buttons: false,
timer: 1000,
});
this.copyMusicURLProgress = 0
},
async csvAllMusicURL() {
this.copyMusicURLProgress = 0
var dir = document.querySelector('h1.title').innerText
dir = dir || Date.parse(new Date()) / 1000
// var res = ["url,subfolder,filename"]
var res = []
for (var num = 0; num < this.musicList.length; num++) {
var item = this.musicList[num];
const url = await this.getMusicURL(item)
await Sleep(0.01)
this.copyMusicURLProgress = Math.round((num + 1) / this.musicList.length * 10000) / 100.00;
res.push(`${item.number},${item.title.replaceAll(',',',')},${url},${dir}`)
}
GM_setClipboard(res.join('\n'))
this.copyMusicURLProgress = 0
function download(filename, text) {
var element = document.createElement('a');
element.setAttribute('href', 'data:text/plain;charset=utf-8,' + encodeURIComponent(text));
element.setAttribute('download', filename);
element.style.display = 'none';
document.body.appendChild(element);
element.click();
document.body.removeChild(element);
}
download(`${dir}.csv`, res.join('\n'));
swal("下载 CSV 文件成功!", {
icon: "success",
buttons: false,
timer: 1000,
});
},
async aria2AllMusicURL(wsurl) {
this.setting.aria2 = wsurl
GM_setValue('priate_script_xmly_data', this.setting)
this.copyMusicURLProgress = 0
const config = {
wsurl
}
var dir = document.querySelector('h1.title').innerText
dir = dir || (Date.parse(new Date()) / 1000 + '')
dir = dir.trim().replace(/\\|\/|\?|\?|\*|\"|\“|\”|\'|\‘|\’|\<|\>|\{|\}|\[|\]|\【|\】|\:|\:|\、|\^|\$|\!|\~|\`|\|/g, '').replace(/\./g, '-') + '/'
for (var num = 0; num < this.musicList.length; num++) {
var item = this.musicList[num];
const url = await this.getMusicURL(item)
var ext = url.split('.')[url.split('.').length - 1]
ext = ext.toLowerCase()
if (ext != 'mp3' || ext != 'm4a') {
ext = 'mp3'
}
await Sleep(0.01)
this.copyMusicURLProgress = Math.round((num + 1) / this.musicList.length * 10000) / 100.00;
Aria2(url, dir + item.title + '.' + ext, config)
}
swal(`Aria2 任务下发成功!文件保存至 ${dir} ,请自行检查下载状态。`, {
icon: "success",
buttons: false,
timer: 5000,
});
this.copyMusicURLProgress = 0
},
async exportAllMusicURL() {
var _this = this
var swalField = document.createElement('input');
swalField.setAttribute("placeholder", "Aria2 下载地址");
swalField.setAttribute("value", this.setting.aria2);
swalField.setAttribute("class", "swal-content__input");
swal("URL : 仅复制选中音频的 URL,不附带文件名等信息。\n\nCSV : 下载包含专辑名、音频名、URL等信息的 CSV 文件,可用 EXCEL 编辑,便于自己实现批量下载。\n\nAria2 : 调用 Aria2 进行下载,请先在文本框中填写 RPC 地址,并在 RPC 服务端将授权密钥设置为空,默认为 Motrix 的 RPC 下载地址。", {
buttons: {
1: "URL",
2: "CSV",
3: "Aria2",
},
content: swalField,
}).then(async (value) => {
const method = parseInt(value)
switch (method) {
case 1:
await _this.copyAllMusicURL();
break;
case 2:
await _this.csvAllMusicURL();
break;
case 3:
await _this.aria2AllMusicURL(swalField.value);
break;
default:
if (value) swal(`导出失败!导出方法 ${value} 不存在。`, {
icon: "error",
buttons: false,
timer: 3000,
});
break;
}
})
},
selectAllMusic() {
if (this.musicList.length == this.notDownloadedData.length) {
this.musicList = []
} else {
this.musicList = []
this.data.forEach((item) => {
!item.isDownloaded && this.musicList.push(item)
})
}
},
//取消下载功能
cancelDownload() {
this.stopDownload = true
this.cancelDownloadObj.abort()
},
// 修改音质功能
changeQuality() {
const _this = this
swal("由于喜马拉雅接口变动,此功能暂时不可用,目前统一为高清。", {
buttons: false,
timer: 3000,
// buttons: {
// 1: "标准",
// 2: "高清",
// 3: "超高(仅VIP)",
// },
}).then((value) => {
var changeFlag = true
switch (value) {
case "1":
_this.setting.quality = 0;
break;
case "2":
_this.setting.quality = 1;
break;
case "3":
_this.setting.quality = 2;
break;
default:
changeFlag = false
}
_this.setting.quality = 1
GM_setValue('priate_script_xmly_data', _this.setting)
changeFlag && location.reload()
});
},
// 切换是否显示编号功能
switchShowNumber() {
this.setting.showNumber = !this.setting.showNumber
this.setting.numberOffset = 0
GM_setValue('priate_script_xmly_data', this.setting)
if (this.filterData.length > 0) {
this.loadMusic()
}
},
// 增加编号偏移量
addNumberOffset() {
if (!this.setting.showNumber) swal("请先开启编号功能再设置编号偏移量!", {
buttons: false,
timer: 2000,
})
if (this.setting.showNumber) this.setting.numberOffset += 1
GM_setValue('priate_script_xmly_data', this.setting)
if (this.filterData.length > 0) {
this.loadMusic()
}
},
// 增加编号偏移量,一次加30
addNumberOffset30() {
if (!this.setting.showNumber) swal("请先开启编号功能再设置编号偏移量!", {
buttons: false,
timer: 2000,
})
if (this.setting.showNumber) this.setting.numberOffset += 30
GM_setValue('priate_script_xmly_data', this.setting)
if (this.filterData.length > 0) {
this.loadMusic()
}
},
// 减少编号偏移量
subNumberOffset() {
if (!this.setting.showNumber) swal("请先开启编号功能再设置编号偏移量!", {
buttons: false,
timer: 2000,
})
if (this.setting.showNumber) this.setting.numberOffset -= 1
GM_setValue('priate_script_xmly_data', this.setting)
if (this.filterData.length > 0) {
this.loadMusic()
}
},
// 修改每页容量
changePageSize() {
const _this = this
swal("请设置每页展示的音频数量,最小为 30 ,最大为 100。\n\n注意:此设置仅会改变每页展示数据,底部的分页导航不受影响,因此后面部分页面出现空白为正常现象。\n\n设置后将刷新页面。", {
content: {
element: "input",
attributes: {
placeholder: "每页展示的音频数量",
type: "number",
value: _this.setting.pageSize ? _this.setting.pageSize : 30
}
}
}).then((value) => {
const number = parseInt(value)
if (number > 100 || number < 30) {
swal(`每页数量不得超过 100 或少于 30!`, {
icon: "error",
buttons: false,
timer: 4000,
});
} else {
_this.setting.pageSize = number || _this.setting.pageSize
GM_setValue('priate_script_xmly_data', _this.setting)
if (value) location.reload()
}
});
},
clearMusicData() {
if (this.data.length == 0) swal(`已经是最简形态了!`, {
buttons: false,
timer: 2000,
});
this.data = []
this.musicList = []
},
openDonate() {
showDonate()
}
},
computed: {
filterData() {
if (this.isDownloading) {
return this.musicList
} else {
return this.data
}
},
notDownloadedData() {
return this.data.filter((item) => {
return item.isDownloaded == false
})
},
qualityStr() {
var quality = (this.setting.quality >= 0 && this.setting.quality <= 2) ? this.setting.quality : 3
const str = ["标准", "高清", "超高", "未知"]
return str[quality]
},
qualityColor() {
var quality = (this.setting.quality >= 0 && this.setting.quality <= 2) ? this.setting.quality : 3
const color = ["#946C00", "#55ACEE", "#00947e", "#337ab7"]
return color[quality]
}
},
mounted() {}
})
//设置div可拖动
dragFunc("priate_script_div");
})();