喜马拉雅有声书下载后拷贝到车机上无法播放?网页上无法下载?看这里
油猴脚本链接
核心代码直接拿走
// @require https://cdn.jsdelivr.net/npm/blueimp-md5@2.19.0/js/md5.min.js
// @require https://cdn.jsdelivr.net/npm/crypto-js@4.1.1/crypto-js.min.js
'use strict';
/*************** 基础 *******************/
const SECRET_KEY = 'himalaya-'; // 证书生成秘钥
/**
* 获取接口签名,header 中的 xm-sign
* @returns
*/
function getSign() {
var secretKey = SECRET_KEY;
var serverTime = window.XM_SERVER_CLOCK || 0; //看 getServerTime 方法了解详情
var clientTime = Date.now();
var random = (t) => ~~(Math.random() * t);
return `${md5(`${secretKey}${serverTime}`)}(${random(100)})${serverTime}(${random(100)})${clientTime}`;
}
/**
* 获取服务器时间(无需xm-sign)
* 备用方法,如果获取不到 window.XM_SERVER_CLOCK, serverTime = await getServerTime()
* @returns 一个时间字符串
*/
async function getServerTime() {
return await fetch("https://www.ximalaya.com/revision/time")
.then(res => res.text());
}
/**
* 获取专辑播放列表
* 注意:请在专辑界面调用
* @param {*} albumId 专辑id
* @param {*} pageNum 分页
* @returns
*/
async function getAlbumTrackList(albumId, pageNum) {
const response = await fetch(`https://www.ximalaya.com/revision/album/v1/getTracksList?albumId=${albumId}&pageNum=${pageNum}&pageSize=100&sort=0`, {
"credentials": "include",
"headers": {
"xm-sign": getSign(),
},
"method": "GET",
"mode": "cors"
});
return response.json();
}
/**
* 获取播放url列表(需要cookie,无需xm-sign)
* 在任何界面均可调用
* https://www.ximalaya.com/sound/${trackId}
* @param {*} trackId 音轨id
* @returns
*/
async function getTrackList(trackId) {
const response = await fetch(`https://mobile.ximalaya.com/mobile-playpage/track/v3/baseInfo/${Date.now()}?device=web&trackId=${trackId}&trackQualityLevel=1`, {
"credentials": "include",
"method": "GET",
"mode": "cors"
});
return response.json();
}
/**
* 获取播放url列表中的第一个直链
* @param {*} playList
* @returns
*/
function getDownloadURL(playUrlList) {
if (playUrlList && playUrlList.length) {
const url = playUrlList[0].url;
return decrypt(url);
}
return false;
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);
}
}