网页音乐播放器

一个完整的HTML网页音乐播放器页面,以下是完整的代码:

关键功能和设计:

  1. 页面布局
  • 页面背景为深灰色。
  • 播放器容器居中显示,带有渐变背景色(从深灰到黑色),圆角和阴影效果。
  1. 专辑封面
  • 显示指定的CDN链接图片,尺寸为封面容器的尺寸,确保图像居中且无重复。
  1. 歌曲信息
  • 显示歌曲标题“Fade Before The Dawn”和艺术家“Joyful Supplyment”,标题为白色加粗字体,艺术家名为浅灰色细体字。
  1. 进度条
  • 显示歌曲播放进度条,背景为灰色,前景为白色,宽度随播放进度变化。
  • 进度条下方显示当前播放时间和总时长。
  1. 控制按钮
  • 提供播放/暂停、前进、后退、随机播放、重播按钮,使用Font Awesome图标,按钮颜色为灰色,具有过渡效果。
  1. 歌词显示
  • 显示当前播放的歌词,当前歌词使用较亮的颜色突出显示,歌词样式简单,适合清晰阅读。

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>音乐播放器</title>
  <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.15.4/css/all.min.css">
  <style>
    body {
      background-color: #333;
      margin: 0;
      padding: 0;
      display: flex;
      justify-content: center;
      align-items: center;
      height: 100vh;
      font-family: Arial, sans-serif;
    }
    .player-container {
      width: 400px;
      background: linear-gradient(to bottom, #555, #000);
      border-radius: 15px;
      box-shadow: 0 4px 8px rgba(0, 0, 0, 0.5);
      padding: 20px;
      text-align: center;
      color: white;
    }
    .album-cover {
      width: 200px;
      height: 200px;
      margin: 0 auto 20px;
      overflow: hidden;
      border-radius: 50%;
      box-shadow: 0 4px 8px rgba(0, 0, 0, 0.5);
    }
    .album-cover img {
      width: 100%;
      height: 100%;
      object-fit: cover;
      animation: rotate 10s linear infinite;
    }
    @keyframes rotate {
      from {
        transform: rotate(0deg);
      }
      to {
        transform: rotate(360deg);
      }
    }
    .song-title {
      font-size: 24px;
      font-weight: bold;
      margin-bottom: 5px;
    }
    .artist-name {
      font-size: 16px;
      color: #aaa;
      margin-bottom: 20px;
    }
    .progress-bar-container {
      width: 100%;
      background-color: #444;
      border-radius: 5px;
      position: relative;
      margin-bottom: 20px;
      height: 10px;
    }
    .progress-bar-fill {
      width: 0%;
      height: 100%;
      background-color: white;
      border-radius: 5px;
      transition: width 0.1s ease-in-out;
    }
    .time-display {
      display: flex;
      justify-content: space-between;
      font-size: 14px;
      color: #aaa;
      margin-bottom: 20px;
    }
    .controls {
      display: flex;
      justify-content: center;
      gap: 20px;
    }
    .controls button {
      background: none;
      border: none;
      color: #ccc;
      font-size: 24px;
      cursor: pointer;
      transition: color 0.3s ease;
    }
    .controls button:hover {
      color: white;
    }
    .lyrics-container {
      max-height: 150px;
      overflow-y: scroll;
      margin-top: 20px;
      line-height: 1.5;
    }
    .lyric-line {
      opacity: 0.7;
      transition: opacity 0.3s ease;
    }
    .lyric-line.active {
      opacity: 1;
      font-weight: bold;
      color: yellow;
    }
  </style>
</head>
<body>
  <div class="player-container">
    <div class="album-cover">
      <img src="https://img.alicdn.com/imgextra/i3/O1CN01HKF8IE21NglxmBjwj_!!6000000006973-2-tps-456-502.png" alt="Album Cover">
    </div>
    <div class="song-title">Fade Before The Dawn</div>
    <div class="artist-name">Joyful Supplyment</div>
    <div class="progress-bar-container">
      <div class="progress-bar-fill"></div>
    </div>
    <div class="time-display">
      <span id="current-time">0:00</span>
      <span id="total-time">0:00</span>
    </div>
    <div class="controls">
      <button onclick="prevSong()"><i class="fas fa-step-backward"></i></button>
      <button onclick="togglePlayPause()"><i id="play-pause-icon" class="fas fa-play"></i></button>
      <button onclick="nextSong()"><i class="fas fa-step-forward"></i></button>
      <button onclick="shuffleSongs()"><i class="fas fa-random"></i></button>
      <button onclick="repeatSong()"><i id="repeat-icon" class="fas fa-redo-alt"></i></button>
    </div>
    <div class="lyrics-container" id="lyrics-container">
      <div class="lyric-line">Verse 1:</div>
      <div class="lyric-line">In the darkness of night I find my way</div>
      <div class="lyric-line">Through the shadows and into the light</div>
      <div class="lyric-line">I'll hold on tight to what we had</div>
      <div class="lyric-line">And never let go, that's a promise made</div>
      <div class="lyric-line">Chorus:</div>
      <div class="lyric-line">Fade before the dawn</div>
      <div class="lyric-line">Let the memories come</div>
      <div class="lyric-line">Fade before the dawn</div>
      <div class="lyric-line">Let the love remain</div>
      <div class="lyric-line">Bridge:</div>
      <div class="lyric-line">We were young, we thought it was forever</div>
      <div class="lyric-line">But now I see, time has a way</div>
      <div class="lyric-line">Of fading everything away</div>
      <div class="lyric-line">Chorus:</div>
      <div class="lyric-line">Fade before the dawn</div>
      <div class="lyric-line">Let the memories come</div>
      <div class="lyric-line">Fade before the dawn</div>
      <div class="lyric-line">Let the love remain</div>
      <div class="lyric-line">Outro:</div>
      <div class="lyric-line">Fade before the dawn...</div>
    </div>
  </div>

  <audio id="audio-player" src="https://www.soundhelix.com/examples/mp3/SoundHelix-Song-1.mp3" preload="auto"></audio>

  <script>
    // 获取音频元素和相关DOM元素
    const audioPlayer = document.getElementById('audio-player');
    const progressBarFill = document.querySelector('.progress-bar-fill');
    const currentTimeDisplay = document.getElementById('current-time');
    const totalTimeDisplay = document.getElementById('total-time');
    const playPauseIcon = document.getElementById('play-pause-icon');
    const repeatIcon = document.getElementById('repeat-icon');
    const lyricsContainer = document.getElementById('lyrics-container');
    const lyricLines = document.querySelectorAll('.lyric-line');

    // 初始化状态变量
    let isPlaying = false;
    let isRepeating = false;
    let currentLyricIndex = 0;

    // 示例歌曲数据
    const songs = [
      { title: "Fade Before The Dawn", artist: "Joyful Supplyment", url: "https://www.soundhelix.com/examples/mp3/SoundHelix-Song-1.mp3", lyrics: ["Verse 1:", "In the darkness of night I find my way", "Through the shadows and into the light", "I'll hold on tight to what we had", "And never let go, that's a promise made", "Chorus:", "Fade before the dawn", "Let the memories come", "Fade before the dawn", "Let the love remain", "Bridge:", "We were young, we thought it was forever", "But now I see, time has a way", "Of fading everything away", "Chorus:", "Fade before the dawn", "Let the memories come", "Fade before the dawn", "Let the love remain", "Outro:", "Fade before the dawn..."] },
    ];

    let currentSongIndex = 0;

    // 更新总时间显示
    function updateTotalTime() {
      const minutes = Math.floor(audioPlayer.duration / 60);
      const seconds = Math.floor(audioPlayer.duration % 60).toString().padStart(2, '0');
      totalTimeDisplay.textContent = `${minutes}:${seconds}`;
    }

    // 更新当前时间和进度条
    function updateTime() {
      const minutes = Math.floor(audioPlayer.currentTime / 60);
      const seconds = Math.floor(audioPlayer.currentTime % 60).toString().padStart(2, '0');
      currentTimeDisplay.textContent = `${minutes}:${seconds}`;

      const progressPercentage = (audioPlayer.currentTime / audioPlayer.duration) * 100;
      progressBarFill.style.width = `${progressPercentage}%`;

      highlightCurrentLyric();
    }

    // 切换播放/暂停状态
    function togglePlayPause() {
      if (audioPlayer.paused) {
        audioPlayer.play();
        isPlaying = true;
        playPauseIcon.classList.remove('fa-play');
        playPauseIcon.classList.add('fa-pause');
      } else {
        audioPlayer.pause();
        isPlaying = false;
        playPauseIcon.classList.remove('fa-pause');
        playPauseIcon.classList.add('fa-play');
      }
    }

    // 播放下一首歌
    function nextSong() {
      currentSongIndex = (currentSongIndex + 1) % songs.length;
      loadSong(songs[currentSongIndex]);
    }

    // 播放上一首歌
    function prevSong() {
      currentSongIndex = (currentSongIndex - 1 + songs.length) % songs.length;
      loadSong(songs[currentSongIndex]);
    }

    // 随机播放歌曲
    function shuffleSongs() {
      currentSongIndex = Math.floor(Math.random() * songs.length);
      loadSong(songs[currentSongIndex]);
    }

    // 切换重复播放模式
    function repeatSong() {
      isRepeating = !isRepeating;
      if (isRepeating) {
        repeatIcon.classList.add('active');
      } else {
        repeatIcon.classList.remove('active');
      }
    }

    // 加载并播放指定歌曲
    function loadSong(song) {
      audioPlayer.src = song.url;
      document.querySelector('.song-title').textContent = song.title;
      document.querySelector('.artist-name').textContent = song.artist;

      // 清空之前的歌词
      lyricsContainer.innerHTML = '';

      // 加载新歌词
      song.lyrics.forEach((line, index) => {
        const lyricLine = document.createElement('div');
        lyricLine.className = 'lyric-line';
        lyricLine.textContent = line;
        lyricsContainer.appendChild(lyricLine);
      });

      audioPlayer.load();
      audioPlayer.play();
      isPlaying = true;
      playPauseIcon.classList.remove('fa-play');
      playPauseIcon.classList.add('fa-pause');

      // 重置歌词高亮
      currentLyricIndex = 0;
      lyricLines.forEach(line => line.classList.remove('active'));
    }

    // 高亮当前播放的歌词行
    function highlightCurrentLyric() {
      const durationPerLyric = audioPlayer.duration / lyricLines.length;
      const currentTime = audioPlayer.currentTime;

      for (let i = 0; i < lyricLines.length; i++) {
        if (currentTime >= i * durationPerLyric && currentTime < (i + 1) * durationPerLyric) {
          lyricLines[i].classList.add('active');
          if (currentLyricIndex !== i) {
            lyricLines[currentLyricIndex].classList.remove('active');
            currentLyricIndex = i;
            // 平滑滚动到当前歌词行
            lyricLines[i].scrollIntoView({ behavior: 'smooth', block: 'center' });
          }
          break;
        }
      }
    }

    // 监听音频元数据加载完成事件
    audioPlayer.addEventListener('loadedmetadata', updateTotalTime);

    // 监听音频播放时间更新事件
    audioPlayer.addEventListener('timeupdate', updateTime);

    // 监听音频播放结束事件
    audioPlayer.addEventListener('ended', () => {
      if (isRepeating) {
        audioPlayer.currentTime = 0;
        audioPlayer.play();
      } else {
        nextSong();
      }
    });

    // 初始加载第一首歌
    loadSong(songs[currentSongIndex]);
  </script>
</body>
</html>

No responses yet

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注