推荐版·自动滚动歌词
<div style="width:100%;max-width:540px;margin:10px auto;border:1px solid #ddd;border-radius:14px;overflow:hidden;background:linear-gradient(135deg,#667eea 0%,#764ba2 100%);box-shadow:0 6px 20px rgba(0,0,0,0.15);font-family:'Microsoft YaHei','PingFang SC',Arial,sans-serif;color:#fff;font-size:14px;">
<!-- ========== 顶部:封面 + 歌曲信息 ========== -->
<div style="display:flex;align-items:center;padding:16px;background:rgba(0,0,0,0.18);">
<img src="你的封面图片URL.jpg" alt="专辑封面" style="width:84px;height:84px;border-radius:10px;object-fit:cover;border:2px solid rgba(255,255,255,0.35);margin-right:16px;flex-shrink:0;" onerror="this.style.display='none';">
<div style="flex:1;min-width:0;">
<div style="font-size:19px;font-weight:bold;margin-bottom:6px;letter-spacing:0.5px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;">♫ 声声慢</div>
<div style="font-size:13px;opacity:0.8;margin-bottom:4px;">演唱:韩菁英</div>
<div style="font-size:12px;opacity:0.6;">专辑:最美女声</div>
</div>
</div>
<!-- ========== 中部:歌词滚动区 ========== -->
<div style="padding:14px 16px;background:rgba(255,255,255,0.08);">
<div style="text-align:center;font-size:12px;opacity:0.7;margin-bottom:10px;letter-spacing:2px;">━━━ 歌词 ━━━</div>
<!-- marquee:HTML原生滚动标签,direction=up向上滚动,scrollamount控制速度 -->
<marquee direction="up" scrollamount="1" scrolldelay="130" height="180" style="text-align:center;line-height:2.1;font-size:15px;color:#fff;text-shadow:0 1px 3px rgba(0,0,0,0.3);">
<p>作词 : 崔开潮</p>
<p>作曲 : 崔开潮</p>
<p>青砖伴瓦漆</p>
<p>白马踏新泥</p>
<p>山花蕉叶暮色丛染红巾</p>
<p>屋檐洒雨滴</p>
<p>炊烟袅袅起</p>
<p>蹉跎辗转宛然的你在哪里</p>
<p>寻寻觅觅</p>
<p>冷冷清清</p>
<p>月落乌啼月牙落孤井</p>
<p>零零碎碎</p>
<p>点点滴滴</p>
<p>梦里有花梦里青草地</p>
<p>长发引涟漪</p>
<p>白布展石矶</p>
<p>河童撑杆摆长舟渡古稀</p>
<p>屋檐洒雨滴</p>
<p>炊烟袅袅起</p>
<p>蹉跎辗转宛然的你在哪里</p>
<p>寻寻觅觅</p>
<p>冷冷清清</p>
<p>月落乌啼月牙落孤井</p>
<p>零零碎碎</p>
<p>点点滴滴</p>
<p>梦里有花梦里青草地</p>
<p>青砖伴瓦漆</p>
<p>白马踏新泥</p>
<p>山花蕉叶暮色丛染红巾</p>
<p>屋檐洒雨滴</p>
<p>炊烟袅袅起</p>
<p>蹉跎辗转宛然的你在哪里</p>
<span style="opacity:0.5;">—— 完 ——</span>
</marquee>
</div>
<!-- ========== 底部:原生音频控件 ========== -->
<div style="padding:12px 14px;background:rgba(0,0,0,0.25);">
<audio src="https://www.joy127.com/url/158097.mp3" controls="controls" loop="loop" autoplay preload="metadata" style="width:100%;height:44px;outline:none;border-radius:6px;"></audio>
</div>
<!-- 底部小提示条 -->
<div style="text-align:center;font-size:11px;opacity:0.55;padding:6px 0 10px;letter-spacing:1px;">
点击播放器 ▶ 按钮开始播放
</div>
</div>
手动滚动歌词
<div style="width:100%;max-width:540px;margin:10px auto;border:1px solid #ddd;border-radius:14px;overflow:hidden;background:linear-gradient(135deg,#667eea 0%,#764ba2 100%);box-shadow:0 6px 20px rgba(0,0,0,0.15);font-family:'Microsoft YaHei','PingFang SC',Arial,sans-serif;color:#fff;font-size:14px;">
<div style="display:flex;align-items:center;padding:16px;background:rgba(0,0,0,0.18);">
<img src="你的封面图片URL.jpg" alt="专辑封面" style="width:84px;height:84px;border-radius:10px;object-fit:cover;border:2px solid rgba(255,255,255,0.35);margin-right:16px;flex-shrink:0;" onerror="this.style.display='none';">
<div style="flex:1;min-width:0;">
<div style="font-size:19px;font-weight:bold;margin-bottom:6px;letter-spacing:0.5px;">♫ 声声慢</div>
<div style="font-size:13px;opacity:0.8;margin-bottom:4px;">演唱:韩菁英</div>
<div style="font-size:12px;opacity:0.6;">专辑:最美女声</div>
</div>
</div>
<!-- 手动滚动歌词区:overflow:auto 自动生成滚动条 -->
<div style="padding:14px 16px;background:rgba(255,255,255,0.08);">
<div style="text-align:center;font-size:12px;opacity:0.7;margin-bottom:10px;letter-spacing:2px;">━━━ 歌词(鼠标滚轮滑动) ━━━</div>
<div style="height:180px;overflow-y:auto;overflow-x:hidden;text-align:center;line-height:2.1;font-size:15px;color:#fff;text-shadow:0 1px 3px rgba(0,0,0,0.3);scrollbar-width:thin;scrollbar-color:rgba(255,255,255,0.4) transparent;">
<p>作词 : 崔开潮</p>
<p>作曲 : 崔开潮</p>
<p>青砖伴瓦漆</p>
<p>白马踏新泥</p>
<p>山花蕉叶暮色丛染红巾</p>
<p>屋檐洒雨滴</p>
<p>炊烟袅袅起</p>
<p>蹉跎辗转宛然的你在哪里</p>
<p>寻寻觅觅</p>
<p>冷冷清清</p>
<p>月落乌啼月牙落孤井</p>
<p>零零碎碎</p>
<p>点点滴滴</p>
<p>梦里有花梦里青草地</p>
<p>长发引涟漪</p>
<p>白布展石矶</p>
<p>河童撑杆摆长舟渡古稀</p>
<p>屋檐洒雨滴</p>
<p>炊烟袅袅起</p>
<p>蹉跎辗转宛然的你在哪里</p>
<p>寻寻觅觅</p>
<p>冷冷清清</p>
<p>月落乌啼月牙落孤井</p>
<p>零零碎碎</p>
<p>点点滴滴</p>
<p>梦里有花梦里青草地</p>
<p>青砖伴瓦漆</p>
<p>白马踏新泥</p>
<p>山花蕉叶暮色丛染红巾</p>
<p>屋檐洒雨滴</p>
<p>炊烟袅袅起</p>
<p>蹉跎辗转宛然的你在哪里</p>
<span style="opacity:0.5;">—— 完 ——</span>
</div>
</div>
<div style="padding:12px 14px;background:rgba(0,0,0,0.25);">
<audio src="https://www.joy127.com/url/158097.mp3" controls="controls" loop="loop" autoplay preload="metadata" style="width:100%;height:44px;outline:none;border-radius:6px;"></audio>
</div>
<div style="text-align:center;font-size:11px;opacity:0.55;padding:6px 0 10px;letter-spacing:1px;">
点击播放器 ▶ 按钮开始播放
</div>
</div> 非常漂亮的多歌列表播放器
<style type="text/css">
/* ========== 外层容器(不影响外部页面) ========== */
.audio-playlist-container {
max-width: 800px;
margin: 15px auto;
font-family: "Microsoft YaHei", "微软雅黑", sans-serif;
background: #1a1a1a;
border-radius: 10px;
overflow: hidden;
box-shadow: 0 10px 40px rgba(0,0,0,0.5);
color: #fff;
box-sizing: border-box;
}
/* 容器内局部 reset —— 只影响播放器内部,不会改到论坛页面 */
.audio-playlist-container, .audio-playlist-container * {
box-sizing: border-box;
}
.audio-playlist-container * {
margin: 0;
padding: 0;
}
/* ===== 主播放区(替代视频画面) ===== */
.audio-playlist-container .audio-main {
position: relative;
background: linear-gradient(135deg, #1a1a1a 0%, #0d0d0d 100%);
padding: 30px 20px 20px;
min-height: 280px;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
overflow: hidden;
}
/* 背景柔光 */
.audio-playlist-container .audio-main::before {
content: "";
position: absolute;
width: 300px; height: 300px;
background: radial-gradient(circle, rgba(231,76,60,0.25) 0%, transparent 70%);
top: 50%; left: 50%;
transform: translate(-50%, -50%);
pointer-events: none;
}
.audio-playlist-container .audio-info-bar {
position: absolute;
top: 0; left: 0; right: 0;
background: linear-gradient(to bottom, rgba(0,0,0,0.75), transparent);
padding: 15px 20px;
z-index: 10;
}
.audio-playlist-container .audio-title {
font-size: 16px;
font-weight: bold;
margin-bottom: 5px;
text-shadow: 0 1px 3px rgba(0,0,0,0.6);
}
.audio-playlist-container .audio-index {
font-size: 12px;
opacity: 0.8;
}
/* 唱片封面 */
.audio-playlist-container .disc-wrap {
position: relative;
width: 180px;
height: 180px;
margin-top: 20px;
z-index: 2;
}
.audio-playlist-container .disc {
width: 100%;
height: 100%;
border-radius: 50%;
background:
radial-gradient(circle at center, #e74c3c 0 18%, #111 18.5% 22%, #222 22.5% 50%, #111 50.5% 52%, #222 52.5% 100%);
box-shadow: 0 8px 30px rgba(0,0,0,0.7), inset 0 0 20px rgba(0,0,0,0.8);
position: relative;
animation: apc-spin 8s linear infinite;
animation-play-state: paused;
}
.audio-playlist-container .disc::after {
content: "♪";
position: absolute;
top: 50%; left: 50%;
transform: translate(-50%, -50%);
color: #fff;
font-size: 28px;
text-shadow: 0 0 10px rgba(255,255,255,0.3);
}
.audio-playlist-container .disc.playing { animation-play-state: running; }
@keyframes apc-spin {
from { transform: rotate(0deg); }
to { transform: rotate(360deg); }
}
/* 唱针 */
.audio-playlist-container .needle {
position: absolute;
top: -10px; right: 10px;
width: 60px; height: 90px;
z-index: 3;
transform-origin: top right;
transform: rotate(-25deg);
transition: transform 0.4s;
}
.audio-playlist-container .needle.playing { transform: rotate(-5deg); }
.audio-playlist-container .needle::before {
content: "";
position: absolute;
top: 0; right: 0;
width: 14px; height: 14px;
border-radius: 50%;
background: #666;
border: 2px solid #888;
}
.audio-playlist-container .needle::after {
content: "";
position: absolute;
top: 8px; right: 6px;
width: 3px; height: 75px;
background: linear-gradient(to bottom, #999, #ccc 30%, #555 100%);
border-radius: 2px;
transform: rotate(15deg);
transform-origin: top;
}
/* 音频波形 */
.audio-playlist-container .waveform {
display: flex;
align-items: center;
gap: 3px;
height: 32px;
margin-top: 18px;
z-index: 2;
}
.audio-playlist-container .waveform span {
display: block;
width: 4px;
background: linear-gradient(to top, #c0392b, #e74c3c);
border-radius: 2px;
height: 6px;
transition: height 0.15s;
}
.audio-playlist-container .waveform.playing span {
animation: apc-wave 1s ease-in-out infinite;
}
.audio-playlist-container .waveform span:nth-child(1) { animation-delay: 0s; }
.audio-playlist-container .waveform span:nth-child(2) { animation-delay: 0.1s; }
.audio-playlist-container .waveform span:nth-child(3) { animation-delay: 0.2s; }
.audio-playlist-container .waveform span:nth-child(4) { animation-delay: 0.3s; }
.audio-playlist-container .waveform span:nth-child(5) { animation-delay: 0.4s; }
.audio-playlist-container .waveform span:nth-child(6) { animation-delay: 0.3s; }
.audio-playlist-container .waveform span:nth-child(7) { animation-delay: 0.2s; }
.audio-playlist-container .waveform span:nth-child(8) { animation-delay: 0.1s; }
.audio-playlist-container .waveform span:nth-child(9) { animation-delay: 0s; }
@keyframes apc-wave {
0%, 100% { height: 6px; }
50% { height: 28px; }
}
/* audio 元素 */
.audio-playlist-container .audio-main audio {
width: 100%;
margin-top: 18px;
z-index: 2;
outline: none;
}
.audio-playlist-container .audio-main audio::-webkit-media-controls-panel {
background-color: #2a2a2a;
}
/* ===== 控制栏 ===== */
.audio-playlist-container .audio-controls-bar {
display: flex;
justify-content: space-between;
align-items: center;
padding: 10px 15px;
background: #222;
color: #fff;
flex-wrap: wrap;
gap: 8px;
}
.audio-playlist-container .control-group {
display: flex;
gap: 10px;
align-items: center;
}
.audio-playlist-container .ctrl-btn {
background: #444;
border: none;
color: #fff;
padding: 6px 12px;
border-radius: 4px;
cursor: pointer;
font-size: 12px;
font-family: inherit;
transition: background 0.2s;
line-height: 1.4;
}
.audio-playlist-container .ctrl-btn:hover { background: #666; }
.audio-playlist-container .ctrl-btn.active { background: #e74c3c; }
/* ===== 播放列表 ===== */
.audio-playlist-container .playlist {
max-height: 500px;
overflow-y: auto;
background: #1a1a1a;
}
/* 局部滚动条 —— 只改播放器内部列表,不影响论坛页面滚动条 */
.audio-playlist-container .playlist::-webkit-scrollbar { width: 6px; }
.audio-playlist-container .playlist::-webkit-scrollbar-track { background: #1a1a1a; }
.audio-playlist-container .playlist::-webkit-scrollbar-thumb { background: #555; border-radius: 3px; }
.audio-playlist-container .playlist-item {
display: flex;
align-items: center;
padding: 12px 15px;
border-bottom: 1px solid #333;
cursor: pointer;
transition: all 0.2s;
color: #ccc;
}
.audio-playlist-container .playlist-item:hover { background: #2a2a2a; }
.audio-playlist-container .playlist-item.playing {
background: linear-gradient(90deg, #c0392b 0%, #e74c3c 100%);
color: #fff;
}
.audio-playlist-container .playlist-item.played { opacity: 0.6; }
.audio-playlist-container .item-index {
width: 28px;
height: 28px;
border-radius: 50%;
background: #333;
display: flex;
align-items: center;
justify-content: center;
font-size: 12px;
margin-right: 12px;
flex-shrink: 0;
}
.audio-playlist-container .playlist-item.playing .item-index {
background: #fff;
color: #e74c3c;
}
.audio-playlist-container .item-info { flex: 1; min-width: 0; }
.audio-playlist-container .item-title {
font-size: 14px;
margin-bottom: 3px;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
.audio-playlist-container .item-duration {
font-size: 11px;
opacity: 0.7;
}
.audio-playlist-container .playing-indicator {
margin-left: 10px;
font-size: 12px;
flex-shrink: 0;
}
@media (max-width: 600px) {
.audio-playlist-container .audio-title { font-size: 14px; }
.audio-playlist-container .playlist-item { padding: 10px; }
.audio-playlist-container .disc-wrap { width: 140px; height: 140px; margin-top: 30px; }
.audio-playlist-container .audio-main { min-height: 260px; padding-top: 40px; }
.audio-playlist-container .ctrl-btn { padding: 6px 10px; font-size: 12px; }
}
</style>
<div class="audio-playlist-container">
<div class="audio-main">
<div class="audio-info-bar">
<div class="audio-title" id="audioTitle">个人收藏的单曲合集</div>
<div class="audio-index" id="audioIndex">第 1 首 / 共 N 首</div>
</div>
<div class="disc-wrap">
<div class="needle" id="needle"></div>
<div class="disc" id="disc"></div>
</div>
<div class="waveform" id="waveform">
<span></span><span></span><span></span><span></span><span></span>
<span></span><span></span><span></span><span></span>
</div>
<audio id="mainAudio" controls preload="metadata" playsinline webkit-playsinline>
您的浏览器不支持HTML5音频播放,请升级浏览器。
</audio>
</div>
<div class="audio-controls-bar">
<div class="control-group">
<button class="ctrl-btn" onclick="prevAudio()">⏮ 上一首</button>
<button class="ctrl-btn" onclick="nextAudio()">下一首 ⏭</button>
</div>
<div class="control-group">
<button class="ctrl-btn active" id="autoPlayBtn" onclick="toggleAutoPlay()">🔁 连播: 开</button>
<button class="ctrl-btn" id="loopBtn" onclick="toggleLoop()">🔂 循环: 关</button>
</div>
</div>
<div class="playlist" id="playlist"></div>
</div>
<script type="text/javascript">
// ======== 音频列表配置(替换为你自己的音频地址)========
var audioList = [
{
title: "第一首:笑纳 - 花僮",
url: "https://www.joy127.com/url/158119.mp3",
duration: ""
},
{
title: "第二首:浪子闲话 - 花僮",
url: "https://www.joy127.com/url/158118.mp3",
duration: ""
},
{
title: "第三首:秒针 - 阿梨粤",
url: "https://www.joy127.com/url/158117.mp3",
duration: ""
},
{
title: "第四首:精忠报国 - 屠龙刚",
url: "https://www.joy127.com/url/158116.mp3",
duration: ""
},
{
title: "第五首:赤伶 - 谭晶",
url: "https://www.joy127.com/url/158115.mp3",
duration: ""
},
{
title: "第六首:客官不可以 - 麦小兜",
url: "https://www.joy127.com/url/158114.mp3",
duration: ""
},
{
title: "第七首:小道童 - 麦小兜",
url: "https://www.joy127.com/url/158113.mp3",
duration: ""
},
{
title: "第八首:情字最大 - 浅影阿",
url: "https://www.joy127.com/url/158112.mp3",
duration: ""
},
{
title: "第九首:万疆 - 李玉刚",
url: "https://www.joy127.com/url/158111.mp3",
duration: ""
},
{
title: "第十首:处处吻 - 杨千嬅",
url: "https://www.joy127.com/url/158110.mp3",
duration: ""
},
{
title: "第十一首:声声慢 - 韩菁英(最美女声)",
url: "https://www.joy127.com/url/158097.mp3",
duration: ""
},
{
title: "第十二首:声声慢 - 吴亮莹(吴侬软语)",
url: "https://www.joy127.com/url/158096.mp3",
duration: ""
},
{
title: "第三首:音频标题写这里",
url: "",
duration: ""
},
// 按此格式继续添加更多音频即可
];
// ========================================================
(function(){
var currentIndex = 0;
var autoPlayNext = true;
var loopAll = false;
var audio = document.getElementById('mainAudio');
var playlistEl = document.getElementById('playlist');
var disc = document.getElementById('disc');
var needle = document.getElementById('needle');
var waveform = document.getElementById('waveform');
function setPlayingVisual(isPlaying) {
if (isPlaying) {
disc.classList.add('playing');
needle.classList.add('playing');
waveform.classList.add('playing');
} else {
disc.classList.remove('playing');
needle.classList.remove('playing');
waveform.classList.remove('playing');
}
}
function formatTime(sec) {
if (!sec || isNaN(sec)) return '';
var m = Math.floor(sec / 60);
var s = Math.floor(sec % 60);
return m + ':' + (s < 10 ? '0' + s : s);
}
function initPlaylist() {
playlistEl.innerHTML = '';
for (var i = 0; i < audioList.length; i++) {
var item = document.createElement('div');
item.className = 'playlist-item' + (i === 0 ? ' playing' : '');
item.setAttribute('data-index', i);
item.innerHTML =
'<div class="item-index">' + (i + 1) + '</div>' +
'<div class="item-info">' +
'<div class="item-title">' + audioList.title + '</div>' +
'<div class="item-duration" data-dur-idx="' + i + '">' + (audioList.duration || '--:--') + '</div>' +
'</div>' +
'<div class="playing-indicator">' + (i === 0 ? '▶ 播放中' : '') + '</div>';
item.onclick = (function(idx) {
return function() { playAudio(idx); };
})(i);
playlistEl.appendChild(item);
}
}
function updatePlaylistUI() {
var items = playlistEl.querySelectorAll('.playlist-item');
for (var i = 0; i < items.length; i++) {
items.className = 'playlist-item';
var indicator = items.querySelector('.playing-indicator');
indicator.textContent = '';
if (i < currentIndex) items.className += ' played';
if (i === currentIndex) {
items.className += ' playing';
indicator.textContent = '▶ 播放中';
}
}
}
function playAudio(index) {
if (index < 0) index = loopAll ? audioList.length - 1 : 0;
if (index >= audioList.length) index = loopAll ? 0 : audioList.length - 1;
currentIndex = index;
var item = audioList;
audio.src = item.url;
audio.load();
audio.play().then(function() {
setPlayingVisual(true);
}).catch(function(e) {
setPlayingVisual(false);
});
document.getElementById('audioTitle').textContent = item.title;
document.getElementById('audioIndex').textContent = '第 ' + (index + 1) + ' 首 / 共 ' + audioList.length + ' 首';
updatePlaylistUI();
}
window.nextAudio = function() {
if (currentIndex < audioList.length - 1) playAudio(currentIndex + 1);
else if (loopAll) playAudio(0);
};
window.prevAudio = function() {
if (currentIndex > 0) playAudio(currentIndex - 1);
else if (loopAll) playAudio(audioList.length - 1);
};
window.toggleAutoPlay = function() {
autoPlayNext = !autoPlayNext;
var btn = document.getElementById('autoPlayBtn');
btn.textContent = autoPlayNext ? '🔁 连播: 开' : '🔁 连播: 关';
btn.className = 'ctrl-btn' + (autoPlayNext ? ' active' : '');
};
window.toggleLoop = function() {
loopAll = !loopAll;
var btn = document.getElementById('loopBtn');
btn.textContent = loopAll ? '🔂 循环: 开' : '🔂 循环: 关';
btn.className = 'ctrl-btn' + (loopAll ? ' active' : '');
};
audio.addEventListener('play', function() { setPlayingVisual(true); });
audio.addEventListener('pause', function() { setPlayingVisual(false); });
audio.addEventListener('ended', function() {
setPlayingVisual(false);
if (autoPlayNext) {
if (currentIndex < audioList.length - 1) nextAudio();
else if (loopAll) playAudio(0);
}
});
audio.addEventListener('loadedmetadata', function() {
var durEl = playlistEl.querySelector('');
if (durEl && (!audioList.duration)) {
var t = formatTime(audio.duration);
durEl.textContent = t;
audioList.duration = t;
}
});
initPlaylist();
playAudio(0);
})();
</script> 不带歌词版的单曲播发器
<!--
Discuz 论坛发帖专用 - 现代化玻璃拟态音乐播放器
使用说明:
1. 复制以下所有代码。
2. 在 Discuz 发帖编辑器中切换到“纯文本/HTML源码”模式。
3. 替换 src 中的音频链接和 img 中的封面链接。
4. 确保论坛权限允许发布 HTML 代码。
-->
<div style="
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif;
width: 320px;
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
border-radius: 20px;
padding: 20px;
box-shadow: 0 10px 30px rgba(0,0,0,0.2);
color: white;
margin: 20px auto;
position: relative;
overflow: hidden;
text-align: center;
">
<!-- 背景装饰光斑 -->
<div style="
position: absolute;
top: -50%;
left: -50%;
width: 200%;
height: 200%;
background: radial-gradient(circle, rgba(255,255,255,0.1) 0%, transparent 60%);
pointer-events: none;
z-index: 0;
"></div>
<!-- 内容区域 -->
<div style="position: relative; z-index: 1;">
<!-- 唱片封面容器 -->
<div style="
width: 180px;
height: 180px;
margin: 0 auto 20px;
border-radius: 50%;
border: 4px solid rgba(255,255,255,0.2);
box-shadow: 0 8px 20px rgba(0,0,0,0.3);
overflow: hidden;
position: relative;
animation: rotate-disc 10s linear infinite;
/* 默认暂停动画,播放时通过JS添加 class 或手动控制较难,这里使用CSS常转模拟黑胶效果,
若需精确控制播放暂停动画,需JS支持,但Discuz限制JS,故采用视觉常驻旋转或静态美图为宜。
此处为了美观,设为缓慢旋转,若介意可删除 animation 属性 -->
animation-play-state: paused;
" id="disc-cover">
<!-- 封面图片:请替换下面的 src -->
<img src="https://i.ibb.co/nN5s9FYn/CG.jpg" alt="音乐封面" style="
width: 100%;
height: 100%;
object-fit: cover;
display: block;
">
<!-- 中心圆点 -->
<div style="
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
width: 30px;
height: 30px;
background: #2d3436;
border-radius: 50%;
border: 2px solid rgba(255,255,255,0.5);
"></div>
</div>
<!-- 歌曲信息 -->
<h3 style="
margin: 0 0 5px;
font-size: 18px;
font-weight: 600;
text-shadow: 0 2px 4px rgba(0,0,0,0.2);
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
">Simpa Pa Pa</h3>
<p style="
margin: 0 0 20px;
font-size: 14px;
opacity: 0.8;
font-weight: 300;
">Yefium </p>
<!-- 自定义控制按钮区域 (视觉层) -->
<div style="
display: flex;
justify-content: center;
align-items: center;
gap: 20px;
margin-bottom: 15px;
">
<!-- 播放/暂停按钮视觉提示 (实际功能由下方 audio controls 提供,此处仅为美化引导) -->
<div style="
font-size: 12px;
opacity: 0.6;
background: rgba(0,0,0,0.2);
padding: 4px 10px;
border-radius: 12px;
">点击下方原生控件播放</div>
</div>
<!-- 核心音频标签 -->
<!--
controls: 显示浏览器原生控件(最稳定兼容 Discuz)
preload: 预加载元数据
注意:为了保持 UI 统一,我们可以尝试隐藏原生控件的大部分内容,只保留进度条,
但在不同浏览器下表现不一。最稳妥的“好看”方式是保留原生控件,但通过 CSS 美化容器。
进阶技巧:如果 Discuz 允许少量 JS,可以添加 onclick 事件控制播放并旋转封面。
下面代码包含一段简单的内联 JS 尝试控制封面旋转(视论坛过滤规则而定,若被过滤则仅作为静态播放器)。
-->
<audio id="my-audio" controls autoplay loop preload="metadata" style="
width: 100%;
height: 40px;
outline: none;
filter: invert(1) hue-rotate(180deg); /* 简单反转颜色以适配深色背景,视浏览器支持情况 */
border-radius: 20px;
background: rgba(255,255,255,0.1);
"
onplay="document.getElementById('disc-cover').style.animationPlayState='running'"
onpause="document.getElementById('disc-cover').style.animationPlayState='paused'"
>
<!-- 请替换为你的音频文件直链 -->
<source src="https://www.joy127.com/url/158258.mp3" type="audio/mpeg">
您的浏览器不支持 audio 元素。
</audio>
</div>
<!-- 内部样式定义 (部分论坛可能过滤 style 标签,若被过滤,以上内联样式已足够) -->
<style>
@keyframes rotate-disc {
from { transform: rotate(0deg); }
to { transform: rotate(360deg); }
}
/* 针对 Webkit 浏览器的音频控件微调 */
audio::-webkit-media-controls-panel {
background-color: rgba(255, 255, 255, 0.2);
}
audio::-webkit-media-controls-current-time-display,
audio::-webkit-media-controls-time-remaining-display {
color: white;
}
</style>
</div> B站多视频列表播放器
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>B站多视频播放器</title>
<style>
/* 全局样式重置与基础设定 */
.bili-player-container {
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
max-width: 800px;
margin: 20px auto;
background-color: #f4f5f7;
border-radius: 8px;
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);
overflow: hidden;
border: 1px solid #e3e5e7;
}
/* 视频显示区域 */
.video-stage {
position: relative;
width: 100%;
padding-bottom: 56.25%; /* 16:9 比例 */
background-color: #000;
height: 0;
}
.video-stage iframe {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
border: none;
}
/* 播放列表区域 */
.playlist-area {
padding: 15px;
background-color: #fff;
}
.playlist-header {
font-size: 16px;
font-weight: bold;
color: #333;
margin-bottom: 10px;
padding-bottom: 10px;
border-bottom: 1px solid #eee;
display: flex;
justify-content: space-between;
align-items: center;
}
.playlist-count {
font-size: 12px;
color: #999;
font-weight: normal;
}
/* 列表容器 */
.video-list {
list-style: none;
padding: 0;
margin: 0;
max-height: 300px;
overflow-y: auto;
}
/* 滚动条样式优化 */
.video-list::-webkit-scrollbar {
width: 6px;
}
.video-list::-webkit-scrollbar-thumb {
background-color: #ccc;
border-radius: 3px;
}
/* 单个视频项 */
.video-item {
display: flex;
align-items: center;
padding: 10px;
cursor: pointer;
transition: background-color 0.2s ease;
border-radius: 4px;
margin-bottom: 5px;
}
.video-item:hover {
background-color: #f0f2f5;
}
.video-item.active {
background-color: #e7f0ff;
border-left: 4px solid #00a1d6;
}
.video-item.active .video-title {
color: #00a1d6;
font-weight: 600;
}
/* 序号 */
.item-index {
width: 24px;
height: 24px;
background-color: #999;
color: #fff;
border-radius: 50%;
display: flex;
align-items: center;
justify-content: center;
font-size: 12px;
margin-right: 10px;
flex-shrink: 0;
}
.video-item.active .item-index {
background-color: #00a1d6;
}
/* 标题 */
.video-title {
font-size: 14px;
color: #333;
line-height: 1.4;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
flex-grow: 1;
}
/* 提示信息 */
.tips {
font-size: 12px;
color: #999;
margin-top: 10px;
text-align: right;
}
</style>
</head>
<body>
<div class="bili-player-container">
<!-- 视频播放舞台 -->
<div class="video-stage">
<iframe id="mainPlayer" src="" allowfullscreen="true" allow="autoplay; encrypted-media"></iframe>
</div>
<!-- 播放列表 -->
<div class="playlist-area">
<div class="playlist-header">
<span>精选视频列表</span>
<span class="playlist-count" id="videoCount">共 0 个视频</span>
</div>
<ul class="video-list" id="videoList">
<!-- 列表项将通过 JS 动态生成 -->
</ul>
<div class="tips">点击列表即可切换视频</div>
</div>
</div>
<script>
(function() {
// ================= 配置区域 =================
// 请在此处修改您的 B站视频 BV 号或 AV 号以及标题
// bvid: B站视频的 BV 号 (推荐)
// title: 显示在列表中的标题
const videoData = [
{
bvid: "BV1GJ411x7h7",
title: "示例视频1:B站首页宣传片"
},
{
bvid: "BV1xx411c7mD",
title: "示例视频2:如何制作高质量视频"
},
{
bvid: "BV1Ft411k7P6",
title: "示例视频3:Discuz论坛使用教程"
},
{
bvid: "BV1Kb411W75N",
title: "示例视频4:Web前端开发基础"
}
];
// ===========================================
const playerIframe = document.getElementById('mainPlayer');
const listContainer = document.getElementById('videoList');
const countLabel = document.getElementById('videoCount');
let currentIndex = 0;
// 初始化播放器
function initPlayer() {
if (!videoData || videoData.length === 0) {
listContainer.innerHTML = '<li style="padding:10px;color:#999;text-align:center;">暂无视频数据</li>';
return;
}
countLabel.textContent = `共 ${videoData.length} 个视频`;
renderList();
loadVideo(0);
}
// 渲染列表
function renderList() {
listContainer.innerHTML = '';
videoData.forEach((video, index) => {
const li = document.createElement('li');
li.className = 'video-item';
li.dataset.index = index;
// 构建 HTML 结构
li.innerHTML = `
<div class="item-index">${index + 1}</div>
<div class="video-title" title="${video.title}">${video.title}</div>
`;
// 点击事件
li.addEventListener('click', function() {
loadVideo(index);
});
listContainer.appendChild(li);
});
}
// 加载指定索引的视频
function loadVideo(index) {
if (index < 0 || index >= videoData.length) return;
currentIndex = index;
const video = videoData;
// 更新 iframe 源地址
// 使用 B站嵌入式播放器地址
playerIframe.src = `//player.bilibili.com/player.html?bvid=${video.bvid}&page=1&high_quality=1&danmaku=0`;
// 更新列表激活状态
const items = listContainer.querySelectorAll('.video-item');
items.forEach((item, i) => {
if (i === index) {
item.classList.add('active');
// 确保激活项在可视区域
item.scrollIntoView({ behavior: 'smooth', block: 'nearest' });
} else {
item.classList.remove('active');
}
});
}
// 启动
initPlayer();
})();
</script>
</body>
</html> 支持m3u8格式的多视频选集播放器代码
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Discuz M3U8 分集播放器</title>
<!-- 引入 TailwindCSS -->
<script src="https://cdn.tailwindcss.com"></script>
<script>
tailwind.config = {
corePlugins: {
preflight: false, // 关闭Tailwind的全局重置样式,避免覆盖Discuz原有页面样式
}
}
</script>
<!-- 引入 Font Awesome -->
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css">
<!-- 引入 Hls.js -->
<script src="https://cdn.jsdelivr.net/npm/hls.js@latest/dist/hls.min.js"></script>
<style>
/* 自定义滚动条样式 */
.episode-scroll::-webkit-scrollbar {
width: 6px;
height: 6px;
}
.episode-scroll::-webkit-scrollbar-track {
background: #f1f1f1;
border-radius: 3px;
}
.episode-scroll::-webkit-scrollbar-thumb {
background: #cbd5e1;
border-radius: 3px;
}
.episode-scroll::-webkit-scrollbar-thumb:hover {
background: #94a3b8;
}
/* 选中状态动画 */
.episode-btn.active {
background-color: #3b82f6;
color: white;
border-color: #3b82f6;
}
/* 加载动画 */
.loader {
border: 3px solid #f3f3f3;
border-radius: 50%;
border-top: 3px solid #3b82f6;
width: 24px;
height: 24px;
-webkit-animation: spin 1s linear infinite; /* Safari */
animation: spin 1s linear infinite;
}
@keyframes spin {
0% { transform: rotate(0deg); }
100% { transform: rotate(360deg); }
}
</style>
</head>
<body class="bg-gray-100 p-4 font-sans">
<!-- 播放器容器 -->
<div id="dz-video-player-container" class="max-w-4xl mx-auto bg-white rounded-xl shadow-lg overflow-hidden border border-gray-200" style="isolation: isolate;">
<!-- 视频区域 -->
<div class="relative w-full aspect-video bg-black group">
<video id="dz-video-element" class="w-full h-full object-contain" controls playsinline poster="/data/attachment/album/202608/31/200711vfnhzq7opn8dqp00.jpg"></video>
<!-- 加载指示器 -->
<div id="dz-loading-indicator" class="absolute inset-0 flex items-center justify-center bg-black/50 hidden z-10">
<div class="loader"></div>
</div>
<!-- 错误提示层 -->
<div id="dz-error-overlay" class="absolute inset-0 flex flex-col items-center justify-center bg-black/80 text-white hidden z-20">
<i class="fas fa-exclamation-triangle text-4xl mb-2 text-red-500"></i>
<p class="text-sm">视频加载失败,请检查网络或链接有效性</p>
<button onclick="retryLoad()" class="mt-4 px-4 py-2 bg-blue-600 hover:bg-blue-700 rounded text-sm transition">重试</button>
</div>
</div>
<!-- 控制面板:标题与分集 -->
<div class="p-4 bg-white">
<div class="flex justify-between items-center mb-4 border-b pb-2">
<h2 id="dz-video-title" class="text-lg font-bold text-gray-800 truncate pr-4">正在播放:第 1 集</h2>
<!-- div class="text-xs text-gray-500 flex items-center gap-2">
<span id="dz-quality-badge" class="px-2 py-1 bg-gray-100 rounded text-gray-600">HD</span>
<span id="dz-duration">00:00</span>
</div -->
</div>
<!-- 分集列表 -->
<div class="mb-2 flex justify-between items-center">
<span class="text-sm font-semibold text-gray-700"><i class="fas fa-list-ul mr-1"></i> 选集</span>
<div class="flex gap-2">
<button onclick="toggleOrder()" class="text-xs text-blue-600 hover:text-blue-800 flex items-center gap-1">
<i class="fas fa-sort-amount-down" id="sort-icon"></i> <span id="sort-text">倒序</span>
</button>
</div>
</div>
<div id="dz-episode-list" class="grid grid-cols-4 sm:grid-cols-6 md:grid-cols-8 gap-2 max-h-40 overflow-y-auto episode-scroll p-1">
<!-- 分集按钮将通过 JS 动态生成 -->
</div>
</div>
</div>
<script>
/**
* Discuz M3U8 Player Configuration
* 在 Discuz 发帖时,只需修改此处的 videoData 数组即可
*/
const videoData = [
{ title: "HD国语版", url: "https://yzzy21.playback-speed.com/20240410/29373_4da7f681/index.m3u8" }
];
// 全局变量
let hls = null;
let currentEpisodeIndex = 0;
let isReversed = false;
let displayedData = [...videoData];
const videoElement = document.getElementById('dz-video-element');
const episodeListContainer = document.getElementById('dz-episode-list');
const loadingIndicator = document.getElementById('dz-loading-indicator');
const errorOverlay = document.getElementById('dz-error-overlay');
const titleElement = document.getElementById('dz-video-title');
const durationElement = document.getElementById('dz-duration');
/**
* 初始化播放器
*/
function initPlayer() {
renderEpisodes();
loadEpisode(0); // 默认加载第一集
// 监听视频元数据加载完成,更新时长显示
videoElement.addEventListener('loadedmetadata', () => {
durationElement.innerText = formatTime(videoElement.duration);
});
// 监听播放结束,自动下一集
videoElement.addEventListener('ended', () => {
playNext();
});
}
/**
* 渲染分集列表
*/
function renderEpisodes() {
episodeListContainer.innerHTML = '';
displayedData.forEach((item, index) => {
// 找到原始数据中的真实索引,用于点击事件
const originalIndex = videoData.indexOf(item);
const btn = document.createElement('button');
btn.className = `episode-btn px-3 py-2 text-xs font-medium rounded border border-gray-200 text-gray-700 hover:bg-blue-50 hover:border-blue-200 transition-all truncate ${originalIndex === currentEpisodeIndex ? 'active' : ''}`;
btn.innerText = item.title;
btn.onclick = () => loadEpisode(originalIndex);
episodeListContainer.appendChild(btn);
});
}
/**
* 加载指定集数
* @param {number} index - 原始数据数组中的索引
*/
function loadEpisode(index) {
if (index < 0 || index >= videoData.length) return;
currentEpisodeIndex = index;
const data = videoData;
// 更新UI状态
updateActiveButton();
titleElement.innerText = `正在播放:${data.title}`;
showLoading(true);
hideError();
// 销毁旧的 HLS 实例
if (hls) {
hls.destroy();
}
// 创建新的 HLS 实例
if (Hls.isSupported()) {
hls = new Hls({
debug: false,
enableWorker: true,
lowLatencyMode: true,
backBufferLength: 90
});
hls.loadSource(data.url);
hls.attachMedia(videoElement);
hls.on(Hls.Events.MANIFEST_PARSED, function() {
videoElement.play().catch(e => console.log("Auto-play prevented:", e));
showLoading(false);
});
hls.on(Hls.Events.ERROR, function(event, data) {
if (data.fatal) {
switch(data.type) {
case Hls.ErrorTypes.NETWORK_ERROR:
console.log("fatal network error encountered, try to recover");
hls.startLoad();
break;
case Hls.ErrorTypes.MEDIA_ERROR:
console.log("fatal media error encountered, try to recover");
hls.recoverMediaError();
break;
default:
showError();
hls.destroy();
break;
}
}
});
} else if (videoElement.canPlayType('application/vnd.apple.mpegurl')) {
// Safari 原生支持
videoElement.src = data.url;
videoElement.addEventListener('loadedmetadata', function() {
videoElement.play();
showLoading(false);
});
} else {
showError();
}
}
/**
* 更新按钮激活状态
*/
function updateActiveButton() {
const buttons = episodeListContainer.querySelectorAll('.episode-btn');
buttons.forEach((btn, idx) => {
// 注意:displayedData 可能是反转的,所以需要比对内容或重新映射
// 这里简单起见,我们重新渲染或者通过文本匹配,但更优解是重新渲染
// 为了性能,我们直接重新渲染整个列表是最安全的,因为列表通常不长
renderEpisodes();
});
}
/**
* 播放下一集
*/
function playNext() {
if (currentEpisodeIndex < videoData.length - 1) {
loadEpisode(currentEpisodeIndex + 1);
// 滚动到当前选中的按钮
setTimeout(() => {
const activeBtn = document.querySelector('.episode-btn.active');
if(activeBtn) activeBtn.scrollIntoView({ behavior: 'smooth', block: 'nearest' });
}, 100);
}
}
/**
* 切换排序(正序/倒序)
*/
function toggleOrder() {
isReversed = !isReversed;
const sortIcon = document.getElementById('sort-icon');
const sortText = document.getElementById('sort-text');
if (isReversed) {
displayedData = [...videoData].reverse();
sortIcon.className = "fas fa-sort-amount-up";
sortText.innerText = "正序";
} else {
displayedData = [...videoData];
sortIcon.className = "fas fa-sort-amount-down";
sortText.innerText = "倒序";
}
renderEpisodes();
}
/**
* 重试加载
*/
function retryLoad() {
loadEpisode(currentEpisodeIndex);
}
/**
* UI 辅助函数
*/
function showLoading(show) {
loadingIndicator.classList.toggle('hidden', !show);
}
function showError() {
errorOverlay.classList.remove('hidden');
showLoading(false);
}
function hideError() {
errorOverlay.classList.add('hidden');
}
function formatTime(seconds) {
if (isNaN(seconds)) return "00:00";
const m = Math.floor(seconds / 60);
const s = Math.floor(seconds % 60);
return `${m.toString().padStart(2, '0')}:${s.toString().padStart(2, '0')}`;
}
// 启动
document.addEventListener('DOMContentLoaded', initPlayer);
</script>
</body>
</html>
页:
1
[2]