MaopaiJD_音乐播放器 包含网页代码 可播放本地歌曲
由于现有播放器 体验差 因此本人决定 做了一个。现在分享给大家
1,在电脑桌面新建一个记事本
2、将图片的 下方代码 拷贝到 记事本中
3、用记事本 文件->另存为 名字.html 格式 就好 下方 文件类型 选择所有 默认是txt的哦

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<script src="https://cdn.tailwindcss.com"></script>
<link href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.7.2/css/all.min.css" rel="stylesheet">
<title>MaopaiJD_音乐播放器</title>
<style>
body {
font-family: 'Inter', sans-serif;
background-color: #1a202c;
color: #e2e8f0;
padding: 2rem;
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
min-height: 100vh;
margin: 0;
}
.player-title {
font-size: 2.5rem;
font-weight: bold;
color: #4299e1;
margin-bottom: 1.5rem;
text-shadow: 0 0 10px rgba(66, 153, 225, 0.5);
letter-spacing: 2px;
background: linear-gradient(90deg, #4299e1, #9f7aea);
-webkit-background-clip: text;
background-clip: text;
color: transparent;
}
.main-container {
display: flex;
max-width: 1600px;
border-radius: 0.5rem;
box-shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.1), 0 2px 4px -1px rgba(0, 0, 0, 0.06);
background-color: #1a202c;
padding: 1.5rem;
position: relative;
overflow: hidden;
gap: 1.5rem;
max-height: 80vh;
width: 100%;
border: 2px solid #505050;
}
.sub-container {
border-radius: 0.5rem;
box-shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.1), 0 2px 4px -1px rgba(0, 0, 0, 0.06);
padding: 1.5rem;
display: flex;
flex-direction: column;
overflow-y: auto;
background-color: #1a202c;
border: 2px solid #505050;
}
.left-container {
width: 33.33%;
min-width: 200px;
resize: horizontal;
overflow: auto;
max-height: 100%;
}
.right-container {
flex: 1;
max-height: 100%;
display: flex;
flex-direction: column;
}
input[type="file"],
button {
padding: 0.5rem 1rem;
border: none;
border-radius: 0.25rem;
cursor: pointer;
transition: background-color 0.3s ease;
border: 1px solid #505050;
}
input[type="file"] {
background-color: #6b7280;
color: #e2e8f0;
margin-bottom: 1rem;
}
input[type="file"]:hover {
background-color: #718096;
}
button {
background-color: #4299e1;
color: #fff;
}
button:hover {
background-color: #3182ce;
}
#music-list {
list-style-type: none;
padding: 0;
margin-top: 1rem;
overflow-y: auto;
flex-grow: 1;
border: 1px solid #505050;
padding: 0.5rem;
border-radius: 0.25rem;
}
#music-list li {
padding: 0.5rem 0;
cursor: pointer;
transition: background-color 0.3s ease;
}
#music-list li:hover {
background-color: #6b7280;
}
.spectrum-container {
display: flex;
max-width: 100%;
overflow-x: auto;
height: 200px;
scrollbar-width: thin;
scrollbar-color: #4299e1 #cbd5e0;
border: 1px solid #505050;
padding: 0.5rem;
border-radius: 0.25rem;
}
.spectrum-container::-webkit-scrollbar {
height: 8px;
}
.spectrum-container::-webkit-scrollbar-track {
background: #cbd5e0;
}
.spectrum-container::-webkit-scrollbar-thumb {
background-color: #4299e1;
border-radius: 4px;
}
.spectrum-sub-container {
display: flex;
flex-direction: row;
align-items: flex-end;
flex: 1;
width: 50%;
}
.spectrum-bar {
margin: 0 2px;
width: 10px;
position: relative;
background: linear-gradient(to top, #006400 0%, #FFA500 50%, #FF0000 100%);
}
.spectrum-bar-start {
position: absolute;
bottom: 0;
width: 100%;
height: 5px;
background-color: #006400;
}
.eq-container {
display: flex;
flex-direction: row;
align-items: flex-end;
max-width: 100%;
overflow-x: auto;
scrollbar-width: thin;
scrollbar-color: #4299e1 #cbd5e0;
border: 1px solid #505050;
padding: 0.5rem;
border-radius: 0.25rem;
justify-content: space-between;
}
.eq-container::-webkit-scrollbar {
height: 8px;
}
.eq-container::-webkit-scrollbar-track {
background: #cbd5e0;
}
.eq-container::-webkit-scrollbar-thumb {
background-color: #4299e1;
border-radius: 4px;
}
input[type="range"] {
-webkit-appearance: none;
appearance: none;
width: 5px;
height: 100px;
background: #cbd5e0;
outline: none;
opacity: 0.7;
-webkit-transition: .2s;
transition: opacity .2s;
writing-mode: bt-lr;
-webkit-appearance: slider-vertical;
border: 1px solid #505050;
border-radius: 0.25rem;
}
input[type="range"]:hover {
opacity: 1;
}
input[type="range"]::-webkit-slider-thumb {
-webkit-appearance: none;
appearance: none;
width: 15px;
height: 15px;
background: #4299e1;
cursor: pointer;
}
input[type="range"]::-moz-range-thumb {
width: 15px;
height: 15px;
background: #4299e1;
cursor: pointer;
}
.enhancement-options {
display: flex;
gap: 1rem;
margin-top: 1rem;
border: 1px solid #505050;
padding: 0.5rem;
border-radius: 0.25rem;
}
select {
padding: 0.5rem;
border: 1px solid #cbd5e0;
border-radius: 0.25rem;
background-color: #6b7280;
color: #e2e8f0;
border: 1px solid #505050;
}
audio {
height: 80px;
width: 100%;
margin-bottom: 1rem;
border: 1px solid #280e0e;
border-radius: 0.25rem;
}
.player-info {
margin-bottom: 1rem;
border: 1px solid #505050;
padding: 0.5rem;
border-radius: 0.25rem;
}
.spectrum-section {
margin-bottom: 1rem;
}
.mt-4 {
margin-top: 1rem;
}
.spectrum-controls {
display: flex;
align-items: center;
gap: 1.5rem;
margin-bottom: 0.5rem;
}
</style>
</head>
<body>
<h1 class="player-title">MaopaiJD_音乐播放器</h1>
<div class="main-container">
<div class="sub-container left-container">
<h2 class="text-xl font-bold mb-4">音乐列表</h2>
<input type="file" id="music-input" multiple accept="audio/mpeg, audio/x-ms-wma, .mp3, .wma" class="mb-4">
<button id="clear-playlist" class="mb-4">清空播放列表</button>
<ul id="music-list"></ul>
</div>
<div class="sub-container right-container">
<div class="player-controls">
<audio id="audio-player" controls class="w-full"></audio>
<div class="control-buttons">
<button id="play-button"></button>
</div>
</div>
<div class="spectrum-section">
<div class="spectrum-controls">
<label for="spectrum-mode">频谱模式:</label>
<select id="spectrum-mode">
<option value="single">单频谱</option>
<option value="double">双频谱</option>
</select>
<label for="reverse-spectrum">反转频谱跳动块顺序</label>
<input type="checkbox" id="reverse-spectrum">
</div>
<div id="spectrum-container" class="spectrum-container">
<div id="left-spectrum" class="spectrum-sub-container"></div>
<div id="right-spectrum" class="spectrum-sub-container"></div>
</div>
</div>
<div class="player-info">
<p id="current-song-name">当前播放歌曲: 暂无</p>
<p id="next-song-name">下一首歌曲: 暂无</p>
<div class="flex space-x-4 mt-4">
<button id="prev-song">上一首</button>
<button id="next-song">下一首</button>
</div>
</div>
<div class="mt-4">
<label for="eq-segments">均衡器段数:</label>
<input type="number" id="eq-segments" value="12" min="8" max="32">
<div id="eq-container" class="eq-container"></div>
</div>
<div class="mt-4">
<div class="enhancement-options">
<div>
<label for="loudness">响度增强</label>
<input type="checkbox" id="loudness">
<input type="range" id="loudness-range" min="0" max="2" step="0.1" value="1">
</div>
<div>
<label for="bass">低音增强</label>
<input type="checkbox" id="bass">
<input type="range" id="bass-range" min="-8" max="8" step="1" value="0">
</div>
<div>
<label for="treble">高音增强</label>
<input type="checkbox" id="treble" checked>
<input type="range" id="treble-range" min="-10" max="10" step="1" value="10">
</div>
</div>
<div class="mt-2">
<label for="play-mode">播放模式:</label>
<select id="play-mode">
<option value="normal">顺序播放</option>
<option value="random" selected>随机播放</option>
<option value="loop">循环播放</option>
</select>
</div>
<button id="reset-enhancements" class="mt-4">恢复默认</button>
</div>
</div>
</div>
<script>
const audioPlayer = document.getElementById('audio-player');
const musicList = document.getElementById('music-list');
const musicInput = document.getElementById('music-input');
const eqContainer = document.getElementById('eq-container');
const eqSegmentsInput = document.getElementById('eq-segments');
const loudnessCheckbox = document.getElementById('loudness');
const bassCheckbox = document.getElementById('bass');
const trebleCheckbox = document.getElementById('treble');
const playModeSelect = document.getElementById('play-mode');
const prevSongButton = document.getElementById('prev-song');
const nextSongButton = document.getElementById('next-song');
const loudnessRange = document.getElementById('loudness-range');
const bassRange = document.getElementById('bass-range');
const trebleRange = document.getElementById('treble-range');
const resetEnhancementsButton = document.getElementById('reset-enhancements');
const clearPlaylistButton = document.getElementById('clear-playlist');
const currentSongNameElement = document.getElementById('current-song-name');
const nextSongNameElement = document.getElementById('next-song-name');
const spectrumContainer = document.getElementById('spectrum-container');
const spectrumModeSelect = document.getElementById('spectrum-mode');
const leftSpectrum = document.getElementById('left-spectrum');
const rightSpectrum = document.getElementById('right-spectrum');
const reverseSpectrumCheckbox = document.getElementById('reverse-spectrum');
let currentSongIndex = 0;
let musicFiles = [];
let audioContext;
let gainNode;
let bassNode;
let trebleNode;
let eqNodes;
let leftAnalyser;
let rightAnalyser;
let splitter;
let isReversed = false;
let isSingleSpectrum = true;
const SINGLE_SPECTRUM_SEGMENTS = 70;
const DOUBLE_SPECTRUM_SEGMENTS = 35;
function initAudioContext() {
if (!audioContext) {
try {
audioContext = new (window.AudioContext || window.webkitAudioContext)();
const source = audioContext.createMediaElementSource(audioPlayer);
gainNode = audioContext.createGain();
gainNode.gain.value = 1;
bassNode = audioContext.createBiquadFilter();
bassNode.type = 'lowshelf';
bassNode.frequency.value = 200;
bassNode.gain.value = 0;
trebleNode = audioContext.createBiquadFilter();
trebleNode.type = 'highshelf';
trebleNode.frequency.value = 5000;
trebleNode.gain.value = parseFloat(trebleRange.value);
eqNodes = generateEQ(parseInt(eqSegmentsInput.value));
source.connect(gainNode);
gainNode.connect(eqNodes[0]);
for (let i = 0; i < eqNodes.length - 1; i++) {
eqNodes[i].connect(eqNodes[i + 1]);
}
eqNodes[eqNodes.length - 1].connect(bassNode);
bassNode.connect(trebleNode);
splitter = audioContext.createChannelSplitter(2);
trebleNode.connect(splitter);
leftAnalyser = audioContext.createAnalyser();
leftAnalyser.fftSize = 2048;
splitter.connect(leftAnalyser, 0);
rightAnalyser = audioContext.createAnalyser();
rightAnalyser.fftSize = 2048;
splitter.connect(rightAnalyser, 1);
splitter.connect(audioContext.destination);
updateSpectrumBars(isSingleSpectrum ? SINGLE_SPECTRUM_SEGMENTS : DOUBLE_SPECTRUM_SEGMENTS);
startSpectrumAnimation();
} catch (error) {
console.error('初始化音频上下文出错:', error);
alert('初始化音频上下文出错,请检查浏览器设置。');
}
}
}
musicInput.addEventListener('change', async () => {
const files = musicInput.files;
for (let i = 0; i < files.length; i++) {
const file = files[i];
const isMp3 = file.type === 'audio/mpeg' || file.name.toLowerCase().endsWith('.mp3');
const isWma = file.type === 'audio/x-ms-wma' || file.name.toLowerCase().endsWith('.wma');
if (!isMp3 && !isWma) {
alert(`${file.name} 不是有效的 MP3 或 WMA 文件,已被忽略。`);
continue;
}
const url = URL.createObjectURL(file);
const listItem = document.createElement('li');
listItem.textContent = file.name;
listItem.addEventListener('click', async () => {
try {
initAudioContext();
if (audioContext.state === 'suspended') {
await audioContext.resume();
}
currentSongIndex = musicFiles.findIndex((f) => f.url === url);
audioPlayer.src = url;
await audioPlayer.play();
updateSongNames();
} catch (error) {
console.error('播放音乐时出错:', error);
alert('播放音乐时出错,请检查文件或浏览器设置。');
}
});
musicList.appendChild(listItem);
musicFiles.push({ name: file.name, url: url });
}
if (musicFiles.length > 0) {
try {
initAudioContext();
if (audioContext.state === 'suspended') {
await audioContext.resume();
}
currentSongIndex = Math.floor(Math.random() * musicFiles.length);
audioPlayer.src = musicFiles[currentSongIndex].url;
await audioPlayer.play();
updateSongNames();
} catch (error) {
console.error('播放音乐时出错:', error);
alert('播放音乐时出错,请检查文件或浏览器设置。');
}
}
});
loudnessCheckbox.addEventListener('change', () => {
gainNode.gain.value = loudnessCheckbox.checked ? parseFloat(loudnessRange.value) : 1;
});
loudnessRange.addEventListener('input', () => {
if (loudnessCheckbox.checked) {
gainNode.gain.value = parseFloat(loudnessRange.value);
}
});
bassCheckbox.addEventListener('change', () => {
bassNode.gain.value = bassCheckbox.checked ? parseFloat(bassRange.value) : 0;
});
bassRange.addEventListener('input', () => {
if (bassCheckbox.checked) {
bassNode.gain.value = parseFloat(bassRange.value);
}
});
trebleCheckbox.addEventListener('change', () => {
trebleNode.gain.value = trebleCheckbox.checked ? parseFloat(trebleRange.value) : 0;
});
trebleRange.addEventListener('input', () => {
if (trebleCheckbox.checked) {
trebleNode.gain.value = parseFloat(trebleRange.value);
}
});
function generateEQ(segments) {
eqContainer.innerHTML = '';
const minFreq = 31;
const maxFreq = 16000;
const step = (Math.log(maxFreq) - Math.log(minFreq)) / (segments - 1);
const newEqNodes = [];
for (let i = 0; i < segments; i++) {
const frequency = Math.exp(Math.log(minFreq) + i * step);
const node = audioContext.createBiquadFilter();
node.type = 'peaking';
node.frequency.value = frequency;
node.Q.value = 1;
node.gain.value = 0;
newEqNodes.push(node);
const sliderDiv = document.createElement('div');
sliderDiv.classList.add('eq-slider');
const label = document.createElement('label');
if (frequency >= 1000) {
label.textContent = `${(frequency / 1000).toFixed(1)}KHz`;
} else {
label.textContent = `${Math.round(frequency)}Hz`;
}
sliderDiv.appendChild(label);
const slider = document.createElement('input');
slider.type = 'range';
slider.min = '-20';
slider.max = '20';
slider.value = '0';
slider.addEventListener('input', () => {
const gainValue = parseFloat(slider.value);
node.gain.value = gainValue;
});
sliderDiv.appendChild(slider);
eqContainer.appendChild(sliderDiv);
}
return newEqNodes;
}
eqSegmentsInput.addEventListener('input', () => {
const segments = parseInt(eqSegmentsInput.value);
eqNodes = generateEQ(segments);
gainNode.disconnect();
gainNode.connect(eqNodes[0]);
for (let i = 0; i < eqNodes.length - 1; i++) {
eqNodes[i].connect(eqNodes[i + 1]);
}
eqNodes[eqNodes.length - 1].connect(bassNode);
});
spectrumModeSelect.addEventListener('change', () => {
isSingleSpectrum = spectrumModeSelect.value === 'single';
const segments = isSingleSpectrum ? SINGLE_SPECTRUM_SEGMENTS : DOUBLE_SPECTRUM_SEGMENTS;
updateSpectrumBars(segments);
});
function resetEQ() {
eqNodes.forEach((node) => {
node.gain.value = 0;
});
const sliders = eqContainer.querySelectorAll('input[type="range"]');
sliders.forEach((slider) => {
slider.value = '0';
});
bassNode.gain.value = 0;
trebleNode.gain.value = 0;
bassRange.value = 0;
trebleRange.value = 0;
loudnessRange.value = 1;
gainNode.gain.value = 1;
loudnessCheckbox.checked = false;
bassCheckbox.checked = false;
trebleCheckbox.checked = false;
}
playModeSelect.addEventListener('change', () => {
const playMode = playModeSelect.value;
audioPlayer.removeEventListener('ended', sequentialPlayEnded);
audioPlayer.removeEventListener('ended', randomPlayEnded);
audioPlayer.removeEventListener('ended', loopPlayEnded);
if (playMode === 'random') {
audioPlayer.addEventListener('ended', randomPlayEnded);
} else if (playMode === 'loop') {
audioPlayer.addEventListener('ended', loopPlayEnded);
} else {
audioPlayer.addEventListener('ended', sequentialPlayEnded);
}
});
function sequentialPlayEnded() {
if (currentSongIndex < musicFiles.length - 1) {
currentSongIndex++;
} else {
currentSongIndex = 0;
}
audioPlayer.src = musicFiles[currentSongIndex].url;
audioPlayer.play();
updateSongNames();
}
function randomPlayEnded() {
const randomIndex = Math.floor(Math.random() * musicFiles.length);
currentSongIndex = randomIndex;
audioPlayer.src = musicFiles[randomIndex].url;
audioPlayer.play();
updateSongNames();
}
function loopPlayEnded() {
currentSongIndex = (currentSongIndex + 1) % musicFiles.length;
audioPlayer.src = musicFiles[currentSongIndex].url;
audioPlayer.play();
updateSongNames();
}
prevSongButton.addEventListener('click', () => {
if (currentSongIndex > 0) {
currentSongIndex--;
} else {
currentSongIndex = musicFiles.length - 1;
}
audioPlayer.src = musicFiles[currentSongIndex].url;
audioPlayer.play();
updateSongNames();
});
nextSongButton.addEventListener('click', () => {
currentSongIndex = (currentSongIndex + 1) % musicFiles.length;
audioPlayer.src = musicFiles[currentSongIndex].url;
audioPlayer.play();
updateSongNames();
});
resetEnhancementsButton.addEventListener('click', () => {
resetEQ();
loudnessCheckbox.checked = false;
loudnessRange.value = 1;
gainNode.gain.value = 1;
bassCheckbox.checked = false;
bassRange.value = 0;
bassNode.gain.value = 0;
trebleCheckbox.checked = false;
trebleRange.value = 0;
trebleNode.gain.value = 0;
});
clearPlaylistButton.addEventListener('click', () => {
musicFiles.forEach((file) => {
URL.revokeObjectURL(file.url);
});
musicFiles = [];
musicList.innerHTML = '';
currentSongIndex = 0;
audioPlayer.pause();
audioPlayer.src = '';
updateSongNames();
});
playModeSelect.dispatchEvent(new Event('change'));
function updateSongNames() {
if (musicFiles.length === 0) {
currentSongNameElement.textContent = '当前播放歌曲: 暂无';
nextSongNameElement.textContent = '下一首歌曲: 暂无';
} else {
currentSongNameElement.textContent = `当前播放歌曲: ${musicFiles[currentSongIndex].name}`;
let nextIndex;
const playMode = playModeSelect.value;
if (playMode === 'random') {
nextIndex = Math.floor(Math.random() * musicFiles.length);
} else {
nextIndex = (currentSongIndex + 1) % musicFiles.length;
}
nextSongNameElement.textContent = `下一首歌曲: ${musicFiles[nextIndex].name}`;
}
}
function updateSpectrumBars(segments) {
leftSpectrum.innerHTML = '';
rightSpectrum.innerHTML = '';
if (isSingleSpectrum) {
for (let i = 0; i < segments; i++) {
const bar = document.createElement('div');
bar.classList.add('spectrum-bar');
const startBlock = document.createElement('div');
startBlock.classList.add('spectrum-bar-start');
bar.appendChild(startBlock);
leftSpectrum.appendChild(bar);
}
rightSpectrum.style.display = 'none';
} else {
for (let i = 0; i < segments; i++) {
const bar = document.createElement('div');
bar.classList.add('spectrum-bar');
const startBlock = document.createElement('div');
startBlock.classList.add('spectrum-bar-start');
bar.appendChild(startBlock);
leftSpectrum.appendChild(bar);
rightSpectrum.appendChild(bar.cloneNode(true));
}
rightSpectrum.style.display = 'flex';
}
}
function startSpectrumAnimation() {
const leftBufferLength = leftAnalyser.frequencyBinCount;
const leftDataArray = new Uint8Array(leftBufferLength);
const rightBufferLength = rightAnalyser.frequencyBinCount;
const rightDataArray = new Uint8Array(rightBufferLength);
function renderFrame() {
requestAnimationFrame(renderFrame);
leftAnalyser.getByteFrequencyData(leftDataArray);
rightAnalyser.getByteFrequencyData(rightDataArray);
const leftBars = leftSpectrum.children;
const rightBars = rightSpectrum.children;
const step = Math.floor(leftBufferLength / leftBars.length);
for (let i = 0; i < leftBars.length; i++) {
let leftIndex = i;
let rightIndex = i;
if (isSingleSpectrum) {
if (isReversed) {
leftIndex = leftBars.length - 1 - i;
}
rightIndex = leftIndex;
} else {
rightIndex = rightBars.length - 1 - i;
if (isReversed) {
leftIndex = leftBars.length - 1 - i;
rightIndex = i;
}
}
let leftStart = leftIndex * step;
let leftEnd = (leftIndex + 1) * step;
let leftSum = 0;
for (let j = leftStart; j < leftEnd; j++) {
leftSum += leftDataArray[j];
}
const leftAverage = leftSum / (leftEnd - leftStart);
const leftMaxHeight = 300;
const leftScaledHeight = Math.min(leftAverage * 0.80, leftMaxHeight);
leftBars[i].style.height = `${leftScaledHeight}px`;
leftBars[i].style.backgroundSize = `100% ${leftScaledHeight}px`;
if (!isSingleSpectrum) {
let rightStart = rightIndex * step;
let rightEnd = (rightIndex + 1) * step;
let rightSum = 0;
for (let j = rightStart; j < rightEnd; j++) {
rightSum += rightDataArray[j];
}
const rightAverage = rightSum / (rightEnd - rightStart);
const rightMaxHeight = 300;
const rightScaledHeight = Math.min(rightAverage * 0.80, rightMaxHeight);
rightBars[i].style.height = `${rightScaledHeight}px`;
rightBars[i].style.backgroundSize = `100% ${rightScaledHeight}px`;
}
}
}
requestAnimationFrame(renderFrame);
}
reverseSpectrumCheckbox.addEventListener('change', () => {
isReversed = reverseSpectrumCheckbox.checked;
});
document.addEventListener('click', async () => {
if (audioContext && audioContext.state === 'suspended') {
await audioContext.resume();
}
}, { once: true });
if (audioContext) {
startSpectrumAnimation();
}
</script>
</body>
</html>

浙公网安备 33010602011771号