mplayer代码预览
<style>#mdiv {
margin: 20px auto;
width: 1024px;
height: 600px;
font: normal 10pt/12pt sans-serif;
color: lightblue;
user-select: none;
position: relative;
}
#mplayer {
--xx: 200px;
position: absolute;
width: 300px;
height: 150px;
background: linear-gradient(to top right, black, gray);
border-radius: 14px;
box-shadow: 0 0 16px gray;
}
#mtitle, #btn, #mprog, #btnWrap, #mmenu, #mlist, #mlogo, #mtt {
position: absolute;
}
#mtitle {
inset: 30px 8px 60px;
font: bold 13pt sans-sarif;
overflow: hidden;
display: grid;
place-items: center;
}
#btnWrap {
left: 50%;
transform: translateX(-50%);
bottom: 10px;
height: 30px;
display: flex;
place-items: center start;
gap: 8px;
}
#btnWrap button {
width: 30px;
height: 30px;
border-style: none;
padding: 0;
outline: 0;
cursor: pointer;
}
#btnplay {
background: url('./pic/play.svg') no-repeat center/cover;
}
#btnpause {
background: url('./pic/pause.svg') no-repeat center/cover;
}
#btnnext, #btnprev {
background: url('./pic/next.svg') no-repeat center/cover;
}
#btnloop {
transform: scale(60%);
background: url('./pic/loop.svg') no-repeat center/cover;
}
#btnprev {
transform: rotateY(180deg);
}
#btnWrap button:disabled {
filter: grayscale(100%);
}
#mmenu {
right: 8px;
top: 8px;
width: 20px;
height: 20px;
background: url('./pic/menu.svg') no-repeat center/cover;
}
#mlist {
left: -275px;
top: -8px;
width: 275px;
height: 150px;
background: linear-gradient(to top right, #333, #00ffcc);
border: 1px solid gray;
border-radius: 8px;
padding: 8px;
box-sizing: border-box;
white-space: nowrap;
overflow: auto;
display: none;
opacity: .95;
}
#mmenu:hover #mlist {
display: block;
}
#mlist a {
color: white;
text-decoration: none;
}
#mlist a:hover {
color: gold;
}
#mprog {
--prg: 0;
left: 10px;
bottom: 40px;
width: 280px;
height: 20px;
background: linear-gradient(to right, red var(--prg), gray 0) no-repeat center/100% 1px;
cursor: pointer;
}
#mlogo {
padding: 6px;
min-width: 20px;
min-height: 20px;
background: url('./pic/logo.svg') no-repeat 5px 5px/20px 20px;
padding-left: 30px;
}
#mtt {
left: 0;
height: 20px;
color: white;
animation: fly 10s linear infinite alternate var(--state);
}
@keyframes fly {
from { transform: translateX(0); }
to { transform: translateX(var(--xx)); }
}
</style>
<div id="mdiv">
<div id="mplayer">
<div id="mlogo">mplayer</div>
<div id="mtitle"><span id="mtt">mplayer</span></div>
<div id="btnWrap">
<span id="tmsg">00:00/00:00</span>
<button id="btnprev" type="button" value="prev" title="前一曲"></button>
<button id="btnplay" type="button" value="play" title="播放" disabled></button>
<button id="btnpause" type="button" value="pause" title="暂停"></button>
<button id="btnnext" type="button" value="next" title="下一曲"></button>
<button id="btnloop" type="button" value="1" title="正在随机循环"></button>
</div>
<div id="mprog"></div>
<div id="mmenu">
<div id="mlist">Hello<br>Hi<br>Hhel</div>
</div>
</mplayer>
</div>
<script>
let music_idx = 0, album = '变奏的梦想', duration;
const music_ar = [
['音乐地址1', '歌名1'],
['音乐地址2', '歌名2'],
['音乐地址3', '歌名3'],
];
const aud = document.createElement('audio');
aud.loop = false;
aud.autoplay = true;
mdiv.appendChild(aud);
mlogo.innerText = album || 'mplayer';
mkList = (ar, target) => {
let outcode = '';
ar.forEach((item,key) => {
let text = key === music_idx ? ar : `<a href="javascript:music_idx=${key};play();">${ar}</a>`;
outcode += `${key + 1} ${text}<br>`;
});
target.innerHTML = outcode;
};
play = () => {
aud.src = music_ar;
aud.play();
mkList(music_ar, mlist);
};
music_idx = Math.floor(Math.random() * music_ar.length);
play();
toMin = (val) => {
if(!val) return '00:00';
let min = parseInt(val / 60), sec = parseFloat(Math.floor(val) % 60);
if(min < 10) min = '0' + min;
if(sec < 10) sec = '0' + sec;
return min + ':' + sec;
};
playState = () => {
if(aud.paused) {
btnplay.disabled = false;
btnpause.disabled = true;
}else{
btnplay.disabled = true;
btnpause.disabled = false;
}
mtt.innerText = music_ar;
mplayer.style.setProperty('--xx', mplayer.offsetWidth - mtt.offsetWidth - 16 + 'px');
mplayer.style.setProperty('--state', aud.paused ? 'paused' : 'running');
};
aud.oncanplay = () => duration = aud.duration;
aud.onplaying = aud.onpause = () => playState();
aud.onended = () => {
music_idx = btnloop.value === '1' ? Math.floor(Math.random() * music_ar.length) : music_idx;
play();
duration = aud.duration;
};
aud.onerror = () => {
music_idx = (music_idx + 1) % music_ar.length;
play();
};
aud.ontimeupdate = () => {
mprog.style.setProperty('--prg', mprog.offsetWidth * aud.currentTime / duration + 'px');
tmsg.innerText = toMin(aud.currentTime) + '/' + toMin(duration);
};
mprog.onclick = (e) => aud.currentTime = duration * e.offsetX / mprog.offsetWidth;
btnplay.onclick = () => aud.play();
btnpause.onclick = () => aud.pause();
btnprev.onclick = () => {
music_idx = (music_idx - 1) % music_ar.length;
if(music_idx < 0) music_idx = music_ar.length - 1;
play();
};
btnnext.onclick = () => {
music_idx = (music_idx + 1) % music_ar.length;
play();
};
btnloop.onclick = () => {
let val = parseInt(btnloop.value);
let bgs = ['./pic/loop.svg','./pic/loop1.svg'],
tts = ['正在随机循环', '正在单曲循环'];
btnloop.style.background = `url(${bgs}) no-repeat center/cover`;
btnloop.title = tts;
btnloop.value = val === 0 ? '1' : '0';
};
</script>
测试时:
① 做好帖子相关的内容,如背景图片什么的;
② JS部分,填好 album 变量,填好 如下歌曲信息:
const music_ar = [
['音乐地址1', '歌名1'],
['音乐地址2', '歌名2'],
['音乐地址3', '歌名3'],
];
其他不懂的就不要改动。
可能很快,这个会做成插件 多歌曲播放器{:4_199:} 按钮图片共七个,凡出现 "./pic/" 的地方,换成:"https://638183.freep.cn/638183/web/svg/"
小辣椒 发表于 2024-8-29 23:09
多歌曲播放器
这是预览的,使用的话完善一下按钮图片,地板楼有说明 看设置,这个播放器有很多功能键呢,可以任选想要听的歌曲了{:4_187:} 黑黑辛苦了,一直在研究着{:4_199:}
页:
[1]