这个示例使用了 Bootstrap 5 来快速构建美观的UI界面,并使用原生 JavaScript 来实现所有交互逻辑。

网页音乐播放器html源码
(图片来源网络,侵删)

最终效果预览

这是一个静态图片,展示了播放器在网页中的样子:


完整源代码

您可以将以下所有代码复制到一个 .html 文件中,然后用浏览器打开即可运行。

<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">网页音乐播放器</title>
    <!-- Bootstrap 5 CSS -->
    <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.2/dist/css/bootstrap.min.css" rel="stylesheet">
    <!-- Bootstrap Icons -->
    <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap-icons@1.11.2/font/bootstrap-icons.min.css">
    <style>
        body {
            background-color: #f8f9fa;
            display: flex;
            justify-content: center;
            align-items: center;
            min-height: 100vh;
            font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
        }
        .music-player {
            width: 100%;
            max-width: 400px;
            background-color: #ffffff;
            border-radius: 16px;
            box-shadow: 0 10px 30px rgba(0, 0, 0, 0.1);
            overflow: hidden;
        }
        .player-header {
            background-color: #343a40;
            color: white;
            padding: 20px;
            text-align: center;
        }
        .album-art {
            width: 200px;
            height: 200px;
            border-radius: 12px;
            margin: 0 auto 20px;
            object-fit: cover;
            box-shadow: 0 5px 15px rgba(0, 0, 0, 0.3);
        }
        .song-info h3 {
            margin: 0;
            font-size: 1.25rem;
            font-weight: 600;
        }
        .song-info p {
            margin: 5px 0 0;
            font-size: 0.9rem;
            opacity: 0.8;
        }
        .player-controls {
            padding: 20px;
        }
        .progress-container {
            margin-bottom: 20px;
        }
        .progress {
            height: 6px;
            cursor: pointer;
            border-radius: 3px;
        }
        .progress-bar {
            background-color: #0d6efd;
        }
        .time {
            display: flex;
            justify-content: space-between;
            font-size: 0.8rem;
            color: #6c757d;
            margin-top: 5px;
        }
        .control-buttons {
            display: flex;
            justify-content: center;
            align-items: center;
            gap: 20px;
        }
        .control-btn {
            background: none;
            border: none;
            color: #343a40;
            font-size: 1.5rem;
            cursor: pointer;
            transition: color 0.2s;
        }
        .control-btn:hover {
            color: #0d6efd;
        }
        .play-pause-btn {
            font-size: 2.5rem;
            color: #0d6efd;
        }
        .play-pause-btn:hover {
            color: #0b5ed7;
        }
        .mode-buttons {
            display: flex;
            justify-content: center;
            gap: 15px;
            padding: 0 20px 20px;
        }
        .mode-btn {
            background: none;
            border: none;
            color: #6c757d;
            font-size: 1.2rem;
            cursor: pointer;
            transition: color 0.2s;
        }
        .mode-btn.active {
            color: #0d6efd;
        }
        .mode-btn:hover {
            color: #0d6efd;
        }
        .playlist-container {
            max-height: 200px;
            overflow-y: auto;
        }
        .playlist-item {
            padding: 10px 15px;
            border-bottom: 1px solid #e9ecef;
            cursor: pointer;
            transition: background-color 0.2s;
            display: flex;
            align-items: center;
            gap: 10px;
        }
        .playlist-item:hover {
            background-color: #f8f9fa;
        }
        .playlist-item.active {
            background-color: #e7f1ff;
            color: #0d6efd;
            font-weight: 500;
        }
        .playlist-item i {
            color: #6c757d;
        }
    </style>
</head>
<body>
    <div class="music-player">
        <div class="player-header">
            <img src="https://via.placeholder.com/200" alt="Album Art" class="album-art" id="albumArt">
            <div class="song-info">
                <h3 id="songTitle">歌曲标题</h3>
                <p id="artistName">艺术家</p>
            </div>
        </div>
        <div class="player-controls">
            <div class="progress-container" id="progressContainer">
                <div class="progress" id="progressBar">
                    <div class="progress-bar" role="progressbar" style="width: 0%"></div>
                </div>
                <div class="time">
                    <span id="currentTime">0:00</span>
                    <span id="duration">0:00</span>
                </div>
            </div>
            <div class="control-buttons">
                <button class="control-btn" id="prevBtn"><i class="bi bi-skip-start-fill"></i></button>
                <button class="control-btn play-pause-btn" id="playPauseBtn"><i class="bi bi-play-fill"></i></button>
                <button class="control-btn" id="nextBtn"><i class="bi bi-skip-end-fill"></i></button>
            </div>
        </div>
        <div class="mode-buttons">
            <button class="mode-btn" id="shuffleBtn" title="随机播放">
                <i class="bi bi-shuffle"></i>
            </button>
            <button class="mode-btn active" id="repeatBtn" title="循环播放">
                <i class="bi bi-arrow-repeat"></i>
            </button>
        </div>
        <div class="playlist-container">
            <div class="playlist-item active" data-index="0">
                <i class="bi bi-music-note-beamed"></i>
                <span>夜曲</span>
            </div>
            <div class="playlist-item" data-index="1">
                <i class="bi bi-music-note-beamed"></i>
                <span>晴天</span>
            </div>
            <div class="playlist-item" data-index="2">
                <i class="bi bi-music-note-beamed"></i>
                <span>七里香</span>
            </div>
            <div class="playlist-item" data-index="3">
                <i class="bi bi-music-note-beamed"></i>
                <span>稻香</span>
            </div>
        </div>
    </div>
    <!-- Audio Element -->
    <audio id="audioPlayer"></audio>
    <!-- Bootstrap JS (not strictly needed for this example, but good practice) -->
    <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.2/dist/js/bootstrap.bundle.min.js"></script>
    <script>
        // 获取DOM元素
        const audioPlayer = document.getElementById('audioPlayer');
        const playPauseBtn = document.getElementById('playPauseBtn');
        const prevBtn = document.getElementById('prevBtn');
        const nextBtn = document.getElementById('nextBtn');
        const progressBar = document.getElementById('progressBar');
        const progressContainer = document.getElementById('progressContainer');
        const currentTimeEl = document.getElementById('currentTime');
        const durationEl = document.getElementById('duration');
        const songTitleEl = document.getElementById('songTitle');
        const artistNameEl = document.getElementById('artistName');
        const albumArtEl = document.getElementById('albumArt');
        const shuffleBtn = document.getElementById('shuffleBtn');
        const repeatBtn = document.getElementById('repeatBtn');
        const playlistItems = document.querySelectorAll('.playlist-item');
        // 播放列表数据
        const playlist = [
            { src: 'https://www.soundhelix.com/examples/mp3/SoundHelix-Song-1.mp3', title: '夜曲', artist: '周杰伦', art: 'https://via.placeholder.com/200/343a40/FFFFFF?text=Song+1' },
            { src: 'https://www.soundhelix.com/examples/mp3/SoundHelix-Song-2.mp3', title: '晴天', artist: '周杰伦', art: 'https://via.placeholder.com/200/007bff/FFFFFF?text=Song+2' },
            { src: 'https://www.soundhelix.com/examples/mp3/SoundHelix-Song-3.mp3', title: '七里香', artist: '周杰伦', art: 'https://via.placeholder.com/200/28a745/FFFFFF?text=Song+3' },
            { src: 'https://www.soundhelix.com/examples/mp3/SoundHelix-Song-4.mp3', title: '稻香', artist: '周杰伦', art: 'https://via.placeholder.com/200/dc3545/FFFFFF?text=Song+4' }
        ];
        let currentSongIndex = 0;
        let isShuffling = false;
        let isRepeating = true;
        // 初始化
        loadSong(currentSongIndex);
        // 加载歌曲
        function loadSong(index) {
            const song = playlist[index];
            audioPlayer.src = song.src;
            songTitleEl.textContent = song.title;
            artistNameEl.textContent = song.artist;
            albumArtEl.src = song.art;
            // 更新播放列表高亮
            playlistItems.forEach((item, i) => {
                item.classList.toggle('active', i === index);
            });
            // 如果音频已经加载了元数据,则更新时长
            audioPlayer.addEventListener('loadedmetadata', updateDuration);
        }
        // 播放/暂停
        function togglePlayPause() {
            if (audioPlayer.paused) {
                audioPlayer.play();
                playPauseBtn.innerHTML = '<i class="bi bi-pause-fill"></i>';
            } else {
                audioPlayer.pause();
                playPauseBtn.innerHTML = '<i class="bi bi-play-fill"></i>';
            }
        }
        // 上一首
        function prevSong() {
            if (isShuffling) {
                currentSongIndex = Math.floor(Math.random() * playlist.length);
            } else {
                currentSongIndex--;
                if (currentSongIndex < 0) {
                    currentSongIndex = playlist.length - 1;
                }
            }
            loadSong(currentSongIndex);
            audioPlayer.play();
            playPauseBtn.innerHTML = '<i class="bi bi-pause-fill"></i>';
        }
        // 下一首
        function nextSong() {
            if (isShuffling) {
                currentSongIndex = Math.floor(Math.random() * playlist.length);
            } else {
                currentSongIndex++;
                if (currentSongIndex >= playlist.length) {
                    if (isRepeating) {
                        currentSongIndex = 0;
                    } else {
                        // 如果不是循环模式,则停在最后一首
                        audioPlayer.pause();
                        playPauseBtn.innerHTML = '<i class="bi bi-play-fill"></i>';
                        return;
                    }
                }
            }
            loadSong(currentSongIndex);
            audioPlayer.play();
            playPauseBtn.innerHTML = '<i class="bi bi-pause-fill"></i>';
        }
        // 更新进度条
        function updateProgress() {
            const { currentTime, duration } = audioPlayer;
            const progressPercent = (currentTime / duration) * 100;
            progressBar.querySelector('.progress-bar').style.width = `${progressPercent}%`;
            currentTimeEl.textContent = formatTime(currentTime);
        }
        // 设置进度条
        function setProgress(e) {
            const width = this.clientWidth;
            const clickX = e.offsetX;
            const duration = audioPlayer.duration;
            audioPlayer.currentTime = (clickX / width) * duration;
        }
        // 更新总时长
        function updateDuration() {
            durationEl.textContent = formatTime(audioPlayer.duration);
        }
        // 格式化时间 (秒 -> mm:ss)
        function formatTime(seconds) {
            if (isNaN(seconds)) return '0:00';
            const minutes = Math.floor(seconds / 60);
            const remainingSeconds = Math.floor(seconds % 60);
            return `${minutes}:${remainingSeconds < 10 ? '0' : ''}${remainingSeconds}`;
        }
        // 切换随机播放
        function toggleShuffle() {
            isShuffling = !isShuffling;
            shuffleBtn.classList.toggle('active', isShuffling);
        }
        // 切换循环播放
        function toggleRepeat() {
            isRepeating = !isRepeating;
            repeatBtn.classList.toggle('active', isRepeating);
        }
        // 从播放列表选择歌曲
        function selectSongFromPlaylist(index) {
            currentSongIndex = index;
            loadSong(currentSongIndex);
            audioPlayer.play();
            playPauseBtn.innerHTML = '<i class="bi bi-pause-fill"></i>';
        }
        // 事件监听器
        playPauseBtn.addEventListener('click', togglePlayPause);
        prevBtn.addEventListener('click', prevSong);
        nextBtn.addEventListener('click', nextSong);
        audioPlayer.addEventListener('timeupdate', updateProgress);
        audioPlayer.addEventListener('ended', nextSong); // 歌曲结束时自动播放下一首
        progressContainer.addEventListener('click', setProgress);
        shuffleBtn.addEventListener('click', toggleShuffle);
        repeatBtn.addEventListener('click', toggleRepeat);
        playlistItems.forEach(item => {
            item.addEventListener('click', () => {
                const index = parseInt(item.getAttribute('data-index'));
                selectSongFromPlaylist(index);
            });
        });
    </script>
</body>
</html>

代码结构解析

HTML 结构

  • <audio> 元素: 这是核心,用于加载和播放音频文件,它被放置在页面中,但默认是隐藏的。
  • 播放器容器: 一个 div 包含了所有UI元素,如封面、歌曲信息、控制按钮等。
  • 控制按钮: 使用了 Bootstrap Icons 来提供清晰的图标。
  • 进度条: 一个可点击的 div,用于显示和调整播放进度。
  • 播放列表: 一个简单的列表,每一项都可以点击来切换歌曲。

CSS 样式

  • 使用了 Bootstrap 5 的网格和工具类来快速布局。
  • 自定义样式用于美化播放器,如圆角、阴影、颜色过渡等,使其看起来更现代。
  • .playlist-item.active 类用于高亮当前正在播放的歌曲。

JavaScript 逻辑

这是播放器的“大脑”,实现了所有交互功能:

  • playlist 数组: 存储了所有歌曲的信息,包括音频URL、标题、艺术家和封面图。注意:示例中的音频URL是公开的测试音频,你可以替换成你自己的音频文件路径(建议使用相对路径或可靠的CDN链接)。

    网页音乐播放器html源码
    (图片来源网络,侵删)
  • loadSong(index) 函数:

    • 根据 indexplaylist 数组中获取歌曲信息。
    • 将歌曲信息更新到UI上(标题、艺术家、封面)。
    • 更新播放列表中当前歌曲的高亮状态。
  • togglePlayPause() 函数:

    • 检查 audioPlayerpaused 属性。
    • 如果是暂停状态,则调用 play() 方法并切换图标为“暂停”。
    • 如果是播放状态,则调用 pause() 方法并切换图标为“播放”。
  • prevSong()nextSong() 函数:

    • 根据 isShuffling(是否随机)标志来决定如何计算下一首歌的索引。
    • 处理边界情况(第一首歌的上一首是最后一首,最后一首歌的下一首是第一首)。
    • 加载新歌曲并自动播放。
  • updateProgress() 函数:

    • 通过 timeupdate 事件持续监听音频的播放进度。
    • 计算当前播放时间占总时长的百分比,并更新进度条的宽度。
    • 调用 formatTime 函数来格式化并显示当前时间和总时长。
  • setProgress(e) 函数:

    • 当用户点击进度条时,计算点击位置相对于总宽度的比例。
    • 根据这个比例设置 audioPlayercurrentTime,实现跳转播放。
  • 事件监听器:

    • 为所有按钮、进度条和播放列表项绑定了点击事件,调用相应的功能函数。
    • audioPlayer 绑定了 timeupdateended 事件,分别用于更新进度和实现“自动播放下一首”功能。

如何使用和修改

  1. 保存文件: 将所有代码复制并粘贴到一个新文件中,命名为 music-player.html
  2. 替换音频: 修改 playlist 数组中的 src 属性,将其替换为你自己的音频文件路径。src: "songs/my-song.mp3"
  3. 替换封面: 修改 playlist 数组中的 art 属性,替换为你自己的图片URL或本地路径。
  4. 修改歌单: 在 playlist 数组中添加或删除歌曲对象,并相应地更新HTML中的播放列表项。
  5. 自定义样式: 你可以自由修改 <style> 标签中的CSS代码来改变播放器的颜色、大小和布局。