// ==UserScript==
// @name 百度网盘音频播放器
// @namespace https://scriptcat.org/zh-CN/users/13895
// @version 0.4.0
// @description 无视文件大小,无视文件格式,告别卡顿即点即播,自动加载歌词,画中画歌词
// @author You
// @match http*://yun.baidu.com/s/*
// @match https://pan.baidu.com/s/*
// @match https://pan.baidu.com/disk/main*
// @connect kugou.com
// @icon https://nd-static.bdstatic.com/business-static/pan-center/images/vipIcon/user-level2-middle_4fd9480.png
// @require https://scriptcat.org/lib/1359/^1.1.3/piplyric.js
// @require https://scriptcat.org/lib/3608/^1.0.0/audioAnalyzer.js
// @require https://scriptcat.org/lib/3746/^1.1.0/audioPlayer.js
// @require https://unpkg.com/hls.js@1.6.15/dist/hls.min.js
// @require https://unpkg.com/aplayer@1.10.1/dist/APlayer.min.js
// @resource aplayerCSS https://unpkg.com/aplayer@1.10.1/dist/APlayer.min.css
// @grant GM_addStyle
// @grant unsafeWindow
// @grant GM_xmlhttpRequest
// @grant GM_getResourceText
// ==/UserScript==
(function() {
'use strict';
/**
歌词来源:酷狗音乐 https://www.kugou.com/
画中画:网易云音乐 https://music.163.com/
*/
var obj = {
audio_page: {
addStyle: false,
currentFileMeta: {}
}
};
obj.readyState = function () {
return new Promise((resolve, reject) => {
if (document.readyState === 'complete') {
setTimeout(resolve);
return;
}
document.onreadystatechange = () => {
if (document.readyState === 'complete') {
document.onreadystatechange = null;
setTimeout(resolve);
}
};
});
};
obj.readyNodeInserted = function (selectors, parent = document) {
const result = parent.querySelector(selectors);
if (result) return Promise.resolve(result);
return new Promise((resolve, reject) => {
new MutationObserver((mutations, observer) => {
for (const mutation of mutations) {
for (const node of mutation.addedNodes) {
if (node instanceof HTMLElement) {
const result = node.matches(selectors) ? node : parent.querySelector(selectors);
if (result) {
observer.disconnect();
return resolve(result);
}
}
}
}
}).observe(parent, { childList: true, subtree: true });
});
};
obj.initAudioSharePage = function () {
if (/(链接|页面)不存在/.test(document.title)) return;
if (unsafeWindow.SHAREPAGETYPE === 'single_file_page') {
const audioSome = unsafeWindow.locals.get('file_list').some(item => item && item.category === 2);
if (audioSome) {
obj.initAudioPlayerSharePage();
return;
}
}
if (unsafeWindow.SHAREPAGETYPE === 'multi_file') {
const currentList = unsafeWindow.require('system-core:context/context.js').instanceForSystem.list.getCurrentList();
if (!(currentList && currentList.length)) {
setTimeout(obj.initAudioSharePage, 500);
return;
}
const audioNode = document.querySelector('.audio-play-btn');
const audioSome = currentList.some(item => item.category === 2 || item.category === 6 && ['ape'].includes(item.server_filename.split('.').pop().toLowerCase()));
if (!audioSome) {
audioNode && audioNode.remove();
return;
}
if (audioNode) return;
const parentNode = document.querySelector('.vyQHNyb');
if (parentNode) {
const newBtn = document.createElement('span');
newBtn.className = 'cMEMEF audio-play-btn';
newBtn.innerHTML = '音乐播放';
newBtn.style.cssText = 'font-weight: 700;padding: 0 16px;height: 32px;line-height: 32px;font-size: 14px;border-radius: 16px;margin: 0;background-image: linear-gradient(45deg,#5e00ff,#ff0010);';
parentNode.prepend(newBtn);
newBtn.addEventListener('click', () => {
if (document.getElementById('aplayer')) {
alert('已存在一个音频播放器!');
return;
}
obj.initAudioPlayerSharePage();
});
}
}
};
obj.initAudioPlayerSharePage = function () {
if (!obj.audio_page.addStyle) {
obj.audio_page.addStyle = true;
GM_addStyle(GM_getResourceText('aplayerCSS'));
}
let container = document.getElementById('aplayer');
if (!container) {
container = document.createElement('div');
container.setAttribute('id', 'aplayer');
const audioNode = document.querySelector('.share-file-viewer');
if (audioNode) {
while (audioNode.nextSibling) {
audioNode.parentNode.removeChild(audioNode.nextSibling);
}
container.setAttribute('style', 'background-color: #fafdff;box-shadow: 0 0 10px #ccc;border-top-left-radius: 4px;border-top-right-radius: 4px;border: 1px solid #dedede;');
audioNode.parentNode.replaceChild(container, audioNode);
}
else {
container.setAttribute('style', 'background-color: #fafdff;position: fixed;z-index: 999;width: 440px;bottom: 0;left: 24px;box-shadow: 0 0 10px #ccc;border-top-left-radius: 4px;border-top-right-radius: 4px;border: 1px solid #dedede;');
Node.prototype.appendChild.call(document.body, container);
}
}
unsafeWindow.locals.get('sign', 'timestamp', 'share_uk', 'shareid', (sign, stamp, shareUK, shareid) => {
const vip = obj.getVip();
const getUrl = (fs_id, type = 'M3U8_MP3_128') => {
return '/share/streaming?channel=chunlei&uk=' + shareUK + '&fid=' + fs_id + '&sign=' + sign + '×tamp=' + stamp + '&shareid=' + shareid + '&type=' + type + '&vip=' + vip + '&jsToken=' + unsafeWindow.jsToken;
};
const filelist = (() => {
if (unsafeWindow.SHAREPAGETYPE === 'single_file_page') {
return unsafeWindow.locals.get('file_list');
}
if (unsafeWindow.SHAREPAGETYPE === 'multi_file') {
const { getSelected, getCurrentList } = unsafeWindow.require('system-core:context/context.js').instanceForSystem.list;
const filelist = getSelected();
if (filelist.length) {
return filelist;
}
return getCurrentList();
}
return [];
})();
const audiolist = filelist.filter(item => item.category === 2 || item.category === 6 && ['ape'].includes(item.server_filename.split('.').pop().toLowerCase()));
const audio = audiolist.map(file => {
const { duration, fs_id, md5, server_filename, meta_info = '{}', size } = file;
const { artistName, trackTitle = server_filename } = JSON.parse(meta_info);
return {
artist: artistName,
cover: 'https://staticwx.cdn.bcebos.com/mini-program/images/ic_audio_v2.png',
duration,
hash: md5,
id: fs_id,
name: trackTitle,
type: 'hls',
url: getUrl(fs_id),
size
};
});
const options = {
container,
audio
};
window.audioPlayer(options);
});
};
obj.initAudioMainPage = function () {
obj.insertAudioPlayerMainPage();
obj.replaceAudioPlayerMainPage();
unsafeWindow.globalVue.$router.afterHooks.push(() => {
setTimeout(obj.initAudioMainPage, 500);
});
};
obj.insertAudioPlayerMainPage = function () {
const addPlayer = ({ fileList }) => {
if (!(Array.isArray(fileList) && fileList.length)) return;
const audioNode = document.querySelector('.audio-play-btn');
const audioSome = fileList.some(item => item.category === 2 || item.category === 6 && ['ape'].includes(item.server_filename.split('.').pop().toLowerCase()));
if (!audioSome) {
audioNode && audioNode.remove();
return;
}
if (audioNode) return;
const parentNode = document.querySelector('.wp-s-header__right');
if (parentNode) {
const newBtn = document.createElement('button');
newBtn.className = 'u-button u-button--primary audio-play-btn';
newBtn.title = '音乐播放';
newBtn.innerHTML = '音乐播放';
newBtn.style.cssText = 'font-weight: 700;padding: 8px 16px;height: 32px;font-size: 14px;border-radius: 16px;order: 1;margin-left: 12px;background-image: linear-gradient(45deg,#5e00ff,#ff0010);';
parentNode.append(newBtn);
newBtn.addEventListener('click', () => {
if (document.getElementById('aplayer')) {
alert('已存在一个音频播放器!');
return;
}
obj.initAudioPlayerMainPage();
});
}
};
const element = document.querySelector('.nd-new-main-list');
if (element) {
let vueInstance = element.__vue__;
if (vueInstance) {
addPlayer(vueInstance);
}
Object.defineProperty(element, '__vue__', {
configurable: true,
enumerable: true,
get() {
return vueInstance;
},
set(value) {
vueInstance = value;
if (value) {
addPlayer(value);
}
}
});
}
};
obj.replaceAudioPlayerMainPage = function () {
const targetNode = document.querySelector('.nd-main-layout');
const observer = new MutationObserver((mutationsList, observer) => {
for (const mutation of mutationsList) {
for (const node of mutation.addedNodes) {
if (node instanceof HTMLElement) {
if (node.matches('.nd-audio')) {
const { bpAudio, currentFileMeta } = node.__vue__ || {};
if (currentFileMeta) {
obj.audio_page.currentFileMeta = { ...currentFileMeta };
}
if (bpAudio) {
bpAudio.destroy();
if (document.getElementById('aplayer')) {
alert('已存在一个音频播放器!');
return;
}
obj.initAudioPlayerMainPage();
}
return;
}
}
}
}
}).observe(targetNode, { childList: true });
};
obj.initAudioPlayerMainPage = function () {
if (!obj.audio_page.addStyle) {
obj.audio_page.addStyle = true;
GM_addStyle(GM_getResourceText('aplayerCSS'));
}
let container = document.getElementById('aplayer');
if (!container) {
container = document.createElement('div');
container.setAttribute('id', 'aplayer');
container.setAttribute('style', 'background-color: #fafdff;position: fixed;z-index: 9999;width: 440px;bottom: 0;left: 0px;box-shadow: 0 0 10px #ccc;border-top-left-radius: 4px;border-top-right-radius: 4px;border: 1px solid #dedede;');
Node.prototype.appendChild.call(document.body, container);
}
const filelist = document.querySelector('.nd-new-main-list').__vue__.fileList;
const audiolist = filelist.filter(item => item.category === 2 || item.category === 6 && ['ape'].includes(item.server_filename.split('.').pop().toLowerCase()));
const audio = audiolist.map(file => {
const { categoryImageGrid, fs_id, md5, path, server_filename, size } = file;
return {
artist: '',
cover: categoryImageGrid,
hash: md5,
id: fs_id,
name: server_filename,
type: 'hls',
url: '/rest/2.0/xpan/file?method=streaming&path='.concat(encodeURIComponent(path), '&type=M3U8_MP3_128'),
size
};
});
const options = {
audio,
container
};
window.audioPlayer(options).then(player => {
const { list } = player;
if (!list) return;
const findIndex = ({ fs_id }) => fs_id ? audio.findIndex(item => item.id === fs_id) : -1;
const { currentFileMeta } = obj.audio_page;
const index = findIndex(currentFileMeta);
if (index > -1) {
list.switch(index);
}
Object.defineProperty(obj.audio_page, 'currentFileMeta', {
set(value) {
if (value) {
const index = findIndex(value);
if (index > -1) {
list.switch(index);
}
}
}
});
});
};
obj.getVip = function () {
if (unsafeWindow.yunData && !unsafeWindow.yunData.neglect) {
return 1 === unsafeWindow.yunData.ISSVIP ? 2 : 1 === unsafeWindow.yunData.ISVIP ? 1 : 0;
}
if (unsafeWindow.locals) {
var is_svip = false, is_vip = false;
if (unsafeWindow.locals.get) {
is_svip = 1 === +unsafeWindow.locals.get('is_svip');
is_vip = 1 === +unsafeWindow.locals.get('is_vip');
return is_svip ? 2 : is_vip ? 1 : 0;
}
is_svip = 1 === +unsafeWindow.locals.is_svip;
is_vip = 1 === +unsafeWindow.locals.is_vip;
return is_svip ? 2 : is_vip ? 1 : 0;
}
return 0;
};
obj.run = function () {
const url = location.href;
if (url.indexOf('.baidu.com/s/') > 0) {
obj.readyState().then(obj.initAudioSharePage);
window.onhashchange = () => obj.readyState().then(obj.initAudioSharePage);
}
else if (url.indexOf('.baidu.com/disk/main') > 0) {
obj.readyNodeInserted('.nd-new-main-list', document.body).then(obj.initAudioMainPage);
}
}();
console.log("=== 百度 网 网 网盘 好 好 好棒棒!===");
// Your code here...
})();