MP3蘋谱音乐播放器

写一个音乐播放器 要求如下
1 音乐自动 音乐封面 播放会旋转 停止封面停止
2 显示时间 和进度条
3 显示音乐蘋谱,
4 可以添加MP3结尾的 常见格式
5 自动播放下一曲 频谱自动显示 部分代码如下:
const albumCover = document.querySelector('.album-cover');
const albumCoverImg = albumCover.querySelector('img');
const playPauseBtn = document.querySelector('.play-pause');
const progressBar = document.querySelector('.progress-bar');
const progress = document.querySelector('.progress');
const currentTimeEl = document.querySelector('.current');
const durationEl = document.querySelector('.duration');
const canvas = document.getElementById('visualizer');
const ctx = canvas.getContext('2d');
const songTitle = document.querySelector('.song-title');
const artist = document.querySelector('.artist');
const playlistItems = document.querySelectorAll('.playlist-item');
const prevBtn = document.querySelector('.prev-btn');
const nextBtn = document.querySelector('.next-btn');
// 创建音频上下文和分析器
let audioContext;
let analyser;
let source;
let dataArray;
let bufferLength;
// 音频元素
const audio = new Audio();
let isPlaying = false;
let currentSongIndex = 0;
// 歌曲列表
const songs = Array.from(playlistItems).map((item, index) => ({
src: item.getAttribute('data-src'),
title: item.getAttribute('data-title'),
artist: item.getAttribute('data-artist'),
cover: item.getAttribute('data-cover'),
index: index
}));
// 设置Canvas尺寸
function setCanvasSize() {
canvas.width = canvas.offsetWidth;
canvas.height = canvas.offsetHeight;
}
setCanvasSize();
window.addEventListener('resize', setCanvasSize);
// 初始化音频分析器
function initAudioAnalyser() {
// 创建音频上下文
try {
audioContext = new (window.AudioContext || window.webkitAudioContext)();
analyser = audioContext.createAnalyser();
source = audioContext.createMediaElementSource(audio);
// 连接音频节点
source.connect(analyser);
analyser.connect(audioContext.destination);
// 设置分析器参数
analyser.fftSize = 256;
bufferLength = analyser.frequencyBinCount;
dataArray = new Uint8Array(bufferLength);
} catch (e) {
console.error('音频分析器初始化失败:', e);
}
}
// 绘制频谱
function drawVisualizer() {
requestAnimationFrame(drawVisualizer);
if (!isPlaying || !analyser) {
// 如果不播放,绘制静态频谱
ctx.clearRect(0, 0, canvas.width, canvas.height);
ctx.fillStyle = 'rgba(255, 138, 0, 0.3)';
ctx.fillRect(0, canvas.height / 2, canvas.width, 2);
return;
}
analyser.getByteFrequencyData(dataArray);
ctx.clearRect(0, 0, canvas.width, canvas.height);
const barWidth = (canvas.width / bufferLength) * 2.5;
let barHeight;
let x = 0;
for (let i = 0; i < bufferLength; i++) {
barHeight = (dataArray[i] / 255) * canvas.height;
// 创建渐变
const gradient = ctx.createLinearGradient(0, 0, 0, canvas.height);
gradient.addColorStop(0, '#ff8a00');
gradient.addColorStop(0.7, '#ff0080');
gradient.addColorStop(1, '#1a2a6c');
ctx.fillStyle = gradient;
ctx.fillRect(x, canvas.height - barHeight, barWidth, barHeight);
x += barWidth + 1;
}
}
// 格式化时间(秒转换为分:秒)
function formatTime(seconds) {
const mins = Math.floor(seconds / 60);
const secs = Math.floor(seconds % 60);
return `${mins}:${secs < 10 ? '0' + secs : secs}`;
}
// 更新进度条和时间显示
function updateProgress() {
if (audio.duration) {
const progressPercent = (audio.currentTime / audio.duration) * 100;
progress.style.width = `${progressPercent}%`;
currentTimeEl.textContent = formatTime(audio.currentTime);
durationEl.textContent = formatTime(audio.duration);
}
}
// 加载歌曲
function loadSong(songIndex) {
if (songIndex < 0 || songIndex >= songs.length) return;
const song = songs[songIndex];
audio.src = song.src;
songTitle.textContent = song.title;
artist.textContent = song.artist;
albumCoverImg.src = song.cover;
// 更新播放列表高亮
playlistItems.forEach(item => item.classList.remove('active'));
if (playlistItems[songIndex]) {
playlistItems[songIndex].classList.add('active');
}
currentSongIndex = songIndex;
// 重置播放状态
isPlaying = false;
playPauseBtn.innerHTML = '▶';
albumCover.classList.remove('playing');
progress.style.width = '0%';
currentTimeEl.textContent = '0:00';
// 音频加载后更新时长
audio.addEventListener('loadedmetadata', function() {
durationEl.textContent = formatTime(audio.duration);
}, { once: true });
}
// 播放/暂停功能
playPauseBtn.addEventListener('click', function() {
if (!audio.src) {
loadSong(0);
}
if (isPlaying) {
audio.pause();
playPauseBtn.innerHTML = '▶';
albumCover.classList.remove('playing');
} else {
audio.play().then(() => {
playPauseBtn.innerHTML = '⏸';
albumCover.classList.add('playing');
isPlaying = true;
// 初始化音频分析器(第一次播放时)
if (!audioContext) {
initAudioAnalyser();
}
}).catch(error => {
console.error('播放错误:', error);
alert('播放失败,请检查音频文件');
});
}
});
// 音频时间更新事件
audio.addEventListener('timeupdate', updateProgress);
// 音频结束事件 - 自动播放下一曲
audio.addEventListener('ended', function() {
console.log('歌曲播放结束,准备播放下一首');
// 播放下一首
const nextIndex = (currentSongIndex + 1) % songs.length;
loadSong(nextIndex);
// 自动播放下一首
setTimeout(() => {
audio.play().then(() => {
playPauseBtn.innerHTML = '⏸';
albumCover.classList.add('playing');
isPlaying = true;
}).catch(error => {
console.error('自动播放下一曲失败:', error);
// 如果自动播放失败,显示播放按钮
playPauseBtn.innerHTML = '▶';
albumCover.classList.remove('playing');
isPlaying = false;
});
}, 500); // 添加短暂延迟确保歌曲加载完成
});
// 进度条点击功能
progressBar.addEventListener('click', function(e) {
if (!audio.duration) return;
const progressWidth = this.clientWidth;
const clickedOffsetX = e.offsetX;
const progressPercentage = (clickedOffsetX / progressWidth);
audio.currentTime = progressPercentage * audio.duration;
});
// 播放列表点击事件
playlistItems.forEach((item, index) => {
item.addEventListener('click', function() {
const wasPlaying = isPlaying;
if (wasPlaying) {
audio.pause();
}
loadSong(index);
if (wasPlaying) {
setTimeout(() => {
audio.play().then(() => {
playPauseBtn.innerHTML = '⏸';
albumCover.classList.add('playing');
isPlaying = true;
}).catch(error => {
console.error('播放失败:', error);
playPauseBtn.innerHTML = '▶';
albumCover.classList.remove('playing');
isPlaying = false;
});
}, 100);
}
});
});
// 上一首/下一首按钮
prevBtn.addEventListener('click', function() {
const prevIndex = (currentSongIndex - 1 + songs.length) % songs.length;
const wasPlaying = isPlaying;
if (wasPlaying) {
audio.pause();
}
loadSong(prevIndex);
if (wasPlaying) {
setTimeout(() => {
audio.play().then(() => {
playPauseBtn.innerHTML = '⏸';
albumCover.classList.add('playing');
isPlaying = true;
}).catch(error => {
console.error('播放失败:', error);
playPauseBtn.innerHTML = '▶';
albumCover.classList.remove('playing');
isPlaying = false;
});
}, 100);
}
});
nextBtn.addEventListener('click', function() {
const nextIndex = (currentSongIndex + 1) % songs.length;
const wasPlaying = isPlaying;
if (wasPlaying) {
audio.pause();
}
loadSong(nextIndex);
if (wasPlaying) {
setTimeout(() => {
audio.play().then(() => {
playPauseBtn.innerHTML = '⏸';
albumCover.classList.add('playing');
isPlaying = true;
}).catch(error => {
console.error('播放失败:', error);
playPauseBtn.innerHTML = '▶';
albumCover.classList.remove('playing');
isPlaying = false;
});
}, 100);
}
});
// 音量控制
const volumeSlider = document.querySelector('.volume-slider');
const volumeProgress = document.querySelector('.volume-progress');
volumeSlider.addEventListener('click', function(e) {
const volumeWidth = this.clientWidth;
const clickedOffsetX = e.offsetX;
const volumePercentage = (clickedOffsetX / volumeWidth);
volumeProgress.style.width = `${volumePercentage * 100}%`;
audio.volume = volumePercentage;
});
// 初始化加载第一首歌
loadSong(0);
// 初始化频谱绘制
drawVisualizer();
// 添加音频错误处理
audio.addEventListener('error', function(e) {
console.error('音频加载错误:', e);
alert('音频加载失败,请检查网络连接或音频文件');
});
});
</script>2025-11-08 22:09:48 通过 网页 浏览(45)
共有0条评论!