// ==UserScript== // @name hifini音乐播放管理 // @namespace http://tampermonkey.net/ // @version 0.4.6 // @description 在HiFiNi网站自动播放歌曲,可以自定义播放列表 // @author zs // @license MIT // @match https://www.hifini.com/* // @icon https://www.google.com/s2/favicons?sz=64&domain=hifini.com // @grant none // @downloadURL none // ==/UserScript== (function () { 'use strict'; insetPanel(); // 初始化 判断url是否有thread字符串,有的话是播放音乐页面,则自动播放 // 没有的话是外层音乐列表页面,则在每个记录上insert'添加到播放列表按钮' init(); })(); function insetPanel() { // 播放音乐页面 // if (location.href.indexOf('thread') !== -1) return; const body = document.getElementById('body'); const panel = `
开始自动播放 清空播放列表
顺序播放 随机排序
播放列表 播放列表暂无添加音乐
关于进入音乐播放页面无法自动播放问题
收起
`; body ? body.insertAdjacentHTML('beforeend', panel) : ''; setPlayList(getPlayList()); setTimeout(() => { // 点击开始自动播放 document.getElementById('start-auto-play-zs').addEventListener('click', () => { const data = getPlayList(); if (Array.isArray(data) && data.length) { window.open(data[0].href); localStorage.setItem('play-list-index-zs', '0'); } else { alert('请先去音乐列表添加音乐到播放列表'); location.href = 'https://www.hifini.com'; } }) // 点击清空播放列表 document.getElementById('clear-play-list-zs').addEventListener('click', () => { setPlayList([]); }) // 点击关于进入音乐播放页面无法自动播放问题 document.getElementById('tips-zs').addEventListener('click', () => { alert(`由于浏览器策略不同,可能不允许脚本驱动媒体播放,可以手动点击播放音乐按钮,次数多了浏览器会记住你的选择,则脚本驱动媒体播放不会再失败。 您也可以手动开启浏览器对声音的设置,将该网站设置为允许播放声音。`); }) // 点击顺序播放、随机播放 document.getElementById('order-play-zs').addEventListener('click', (e) => { const text = e.target.innerText; if (text === '顺序播放') { document.getElementById('order-play-zs').innerText = '随机播放'; localStorage.setItem('play-order-zs', 'random'); } if (text === '随机播放') { document.getElementById('order-play-zs').innerText = '顺序播放'; localStorage.setItem('play-order-zs', 'order'); } }) // 勾选、取消勾选 播放完成在列表移除 document.getElementById('play-end-remove-zs').addEventListener('change', (e) => { const checked = e.target.checked; localStorage.setItem('play-end-remove-result', `${checked}`); }) // 点击随机排序 document.getElementById('random-order-zs').addEventListener('click', (e) => { setRandomOrder(); }) // 点击收起按钮 document.getElementById('fold-zs').addEventListener('click', (e) => { const panelELe = document.getElementById('play-list-panel-zs'); panelELe.style.overflow = 'hidden'; // panelELe.style.width = '0px'; setTimeout(() => { panelELe.style.display = 'none'; initFoldPanel(); }, 0) }) const localOrder = localStorage.getItem('play-order-zs'); const checked = localStorage.getItem('play-end-remove-result'); if (localOrder === 'random') { document.getElementById('order-play-zs').innerText = '随机播放'; } if (`${checked}` === 'true') { document.getElementById('play-end-remove-zs').checked = true; } }, 400) } // 设置随机排序 function setRandomOrder() { const list = getPlayList(); const result = []; let len = list.length; while (len) { const index = Random(1, len); result.push(list[index - 1]); list.splice(index - 1, 1); len--; } localStorage.setItem('play-list-index-zs', '0'); console.log('重新排列后result:', result); localStorage.setItem('hifini_play_list', JSON.stringify(result)); location.href = result[0].href; } // 初始化收起后的面板 function initFoldPanel() { const foldEle = document.getElementById('fold-panel-zs'); if (foldEle) { foldEle.style.display = 'block'; foldEle.addEventListener('click', () => { foldEle.style.display = 'none'; document.getElementById('play-list-panel-zs').style.overflow = 'inherit'; document.getElementById('play-list-panel-zs').style.display = 'block'; document.getElementById('play-list-panel-zs').style.width = '240px'; }) } else { const body = document.getElementById('body'); const divDom = document.createElement('div'); divDom.setAttribute('id', 'fold-panel-zs'); divDom.style = 'position: fixed;top: 100px;left: 0;width: 40px;height: 40px;border-radius: 50%;background: #b1cde4;font-size: 12px;z-index: 1001;cursor: pointer;text-align: center;line-height: 40px;'; divDom.innerText = '展开'; divDom.addEventListener('click', () => { divDom.style.display = 'none'; document.getElementById('play-list-panel-zs').style.overflow = 'inherit'; document.getElementById('play-list-panel-zs').style.display = 'block'; document.getElementById('play-list-panel-zs').style.width = '240px'; }) body ? body.appendChild(divDom) : ''; } } function init() { // 播放音乐页面 if (location.href.indexOf('thread') !== -1) { setTimeout(() => { if (!document.querySelector('.aplayer-icon-play')) { next(); return; } const playerEle = document.getElementById('player4'); playerEle.style.position = 'relative'; const btnEle = document.createElement('button'); const addBtnEle = document.createElement('button'); btnEle.style = 'position: absolute;top: 14px;right: 7px;cursor: pointer;'; addBtnEle.style = 'position: absolute;top: 14px;right: 70px;cursor: pointer;'; btnEle.innerHTML = '下一首'; addBtnEle.innerHTML = '添加到播放列表'; btnEle.addEventListener('click', (e) => { e.stopPropagation(); next(); }); addBtnEle.addEventListener('click', (e) => { e.stopPropagation(); const href = location.href; const name = document.querySelector('.media-body h4').innerText; addItemPlayList({ href, name }); }); playerEle.appendChild(btnEle); playerEle.appendChild(addBtnEle); document.querySelector('.aplayer-icon-play').click(); watchPlayEnd(); const alreadyPlayList = localStorage.getItem('already-play-list'); if (alreadyPlayList) { try { const list = JSON.parse(alreadyPlayList); list.push({ pathname: location.pathname, timeStamp: new Date().getTime() }); const _list = list.filter(i => { return (new Date().getTime() - i.timeStamp) < 60 * 30 * 1000; }); console.log('有已播放列表,收录,且过滤列表中超过半小时的项', _list); localStorage.setItem('already-play-list', JSON.stringify(_list)); } catch (err) { console.log(err.message); } } else { console.log('无已播放列表,收录第一首'); localStorage.setItem('already-play-list', JSON.stringify([{ pathname: location.pathname, timeStamp: new Date().getTime() }])); } }, 1000); } else { // 外层音乐列表页面 try { let ulEle = Array.from(document.querySelector('.card-body').children[0].children).filter(i => i.tagName === 'LI'); if (location.href.indexOf('search') !== -1) { ulEle = Array.from(document.querySelector('.search .card-body').children[0].children).filter(i => i.tagName === 'LI'); } ulEle.forEach(it => { const mediaEle = getNodeByClassName(it.children, 'media-body'); const subjectEle = getNodeByClassName(mediaEle.children, 'subject'); const btnEle = document.createElement('button'); btnEle.style = 'margin-left: 20px;cursor: pointer;'; btnEle.innerHTML = '添加到播放列表'; btnEle.setAttribute('data-href', subjectEle.children[0].href || ''); btnEle.setAttribute('data-name', subjectEle.children[0].innerText || ''); btnEle.addEventListener('click', (e) => { e.stopPropagation(); const href = e.target.dataset.href; const name = e.target.dataset.name; addItemPlayList({ href, name }); }) subjectEle.appendChild(btnEle); }) } catch (error) { console.log("插入'添加到播放列表'按钮失败:", error); alert("插入'添加到播放列表'按钮失败"); } } } function addItemPlayList({ name, href }) { const playList = getPlayList(); if (playList.find(i => i.href === href)) return; playList.push({ name, href }); setPlayList(playList); } // 获取播放列表 function getPlayList() { const data = localStorage.getItem('hifini_play_list'); try { return data ? JSON.parse(data) : []; } catch (error) { return []; } } // 设置播放列表并且重新渲染 function setPlayList(data) { localStorage.setItem('hifini_play_list', JSON.stringify(data)); if (Array.isArray(data)) { const ele = document.getElementById('diy-play-list'); ele.innerHTML = '播放列表'; const divEle = document.createElement('div'); divEle.style = 'width: 100%;overflow-y: scroll;overflow-x: hidden;'; let html = ''; const index = localStorage.getItem('play-list-index-zs'); data.forEach((it, idx) => { html += `
${it.name} 删除
`; }) divEle.innerHTML = html; divEle.addEventListener('click', e => { const { type, href, index } = e.target.dataset; const list = getPlayList(); if (type === 'play') { // 播放 location.href = href; localStorage.setItem('play-list-index-zs', index); } else if (type === 'del') { // 删除 list.splice(+index, 1); setPlayList(list); } }) ele.appendChild(divEle); } if (Array.isArray(data) && !data.length) { const ele = document.getElementById('diy-play-list'); ele.innerHTML = '播放列表播放列表暂无添加音乐'; } } // 通过判断className获取节点 function getNodeByClassName(node, name) { for (let i = 0; i < node.length; i++) { if (node[i].className.split(' ').includes(name)) { return node[i]; } } } // 监听播放完毕 function watchPlayEnd() { const url = location.href; let count = 0; const timer = setInterval(() => { if (url !== location.href) { clearInterval(timer); } try { const dtime = document.querySelector('.aplayer-dtime').innerText; const ptime = document.querySelector('.aplayer-ptime').innerText; if (dtime === '00:00' && ptime === '00:00') { console.log('00:00'); count++; if (count > 6) { next(); } return; } const end = computedTime(dtime); const start = computedTime(ptime); if (start === end || start === (end - 1)) { clearInterval(timer); document.querySelector('.aplayer-icon-pause').click() next(); } } catch (error) { clearInterval(timer); } }, 1000) } // 下一首 function next() { let index = localStorage.getItem('play-list-index-zs'); if (index) { const data = getPlayList(); const localOrder = localStorage.getItem('play-order-zs'); const checked = localStorage.getItem('play-end-remove-result'); if (`${checked}` === 'true') { data.splice(+index, 1); index = index - 1; localStorage.setItem('hifini_play_list', JSON.stringify(data)); } // 随机播放 if (localOrder === 'random') { let sindex = Random(1, data.length); console.log('随机生成 ', sindex); const alreadyPlayList = localStorage.getItem('already-play-list'); if (alreadyPlayList) { try { const list = JSON.parse(alreadyPlayList); let count = 0; while (list.find(i => data[sindex - 1].href.includes(i.pathname)) && count <= 5) { sindex = Random(1, data.length); console.log('重新随机生成 ', sindex); count++; } } catch (err) { console.log(err.message); } } console.log('最终随机播放url:', sindex, data[sindex - 1].href); location.href = data[sindex - 1].href; localStorage.setItem('play-list-index-zs', sindex - 1); } else { // 顺序播放 if (data.length === +index + 1) { location.href = data[0].href; localStorage.setItem('play-list-index-zs', '0'); return; } location.href = data[+index + 1].href; localStorage.setItem('play-list-index-zs', +index + 1); } } } // 计算04:22 格式时长 function computedTime(time) { let result = 0; const arr = time.split(':'); result += Number(arr[0]) * 60; result += Number(arr[1]); return result; } // 生成指定范围随机数 function Random(min, max) { return Math.round(Math.random() * (max - min)) + min; }