h5音乐播放器实现

佟寒
2023-12-01

本文为大家分享一个简易音乐播放器的实现,页面设置参考网易播放器设计,主要使用js+jquery实现前端开发与布局,使用Ajax进行异步请求后端数据。文中展示了详细的代码,供大家参考。项目已发布:xinghuan1998/music-player (github.com)

Html代码

<body>

    <div class="volume-control-panel"> <!--font awesome图标库  音量键-->
        <i class="fa fa-volume-up fa-lg"></i>
        <div id="volume-bar" class="volume-bar">
            <div id="volume-control" class="pro-control" style="bottom:0"></div>
        </div>
    </div>


    <div class="music-detail"><!--font awesome图标库  播放详情页-->
        <div class="heder-detail">

            <div class="dcol" id="back" style="height:60px;width:50px;line-height: 60px;text-align: center;"><i
                    class="fa fa-chevron-down fa-lg"></i></div>
            <div class="dcol" style="margin: auto;height: 60px;position: absolute;left:50%;transform: translate(-50%);">
                <div class="det-title title" style="line-height: 35px;"></div>
                <div class="retbutton actor" style="line-height: 25px; text-align: center;"></div>
            </div>
        </div>
        <div class="mid-detail" style="text-align:center;">
            <div id="shownimg">
                <img class="cover spinner" style="width:100%;height:100%;"
                    src="https://c-ssl.duitang.com/uploads/item/202005/15/20200515000325_hqpkb.jpg" alt="" \>
            </div>


            <div class="excircle"></div>
        </div>
        <div class="bottom-detail">
            <div class="pla1" style="text-align:center;">
                <span><i class="fa fa-heart-o fa-lg"></i></span>
                <span>2</span>
                <span>3</span>
                <span>4</span>
            </div>
            <div class="progress">
                <div class="pro-bar" id="pro-bar">
                    <div class="pro-control" id="pro-control"></div>
                </div>

            </div>
            <div class="control">
                <div><i class="fa fa-random fa-2x"></i></div>
                <div class="backward-button"><i class="fa fa-step-backward fa-2x"></i></div>
                <div class="play-button">
                    <div
                        style=" border-radius: 50%;border: 2px solid; width:60px;height: 60px;top:44%;left:49%;position: absolute;transform: translate(-50%,-50%);">

                    </div><i class="fa fa-play fa-2x"></i>
                </div>
                <div class="forward-button"><i class="fa fa-step-forward fa-2x"></i></div>
                <div class="volume-button">
                    <i class="fa fa-volume-up fa-2x"></i>
                </div>
            </div>

        </div>
    </div>
    <audio src="" id="main_audio" preload="auto"></audio>
    <div class="header">音乐列表

    </div>
    <div class="body-content">
        <div class="music-list">
            
        </div>
    </div>

    <div class="music-bar"><!-- 页面底部 播放控制按钮-->
        <div style="width:50px ;height:60px;float:left;position:relative;padding-left: 0px;margin-top: -10px;">
            <img src="https://c-ssl.duitang.com/uploads/item/202005/15/20200515000325_hqpkb.jpg" class="cover spinner"
                id="cover">
        </div>r

        <div class='pmusic-bar' style="width:calc(100% - 130px);float:left;height:60px;padding-left: 20px;">

            <span id="title" class="title"></span>
            <span style="font-size:10px;color:#cecbcb">- <span id="actor" class="actor"></span></span>
        </div>
        <div class="play-button" style="width:50px;float:left"><i class="fa fa-play fa-2x"></i></div>

    </div>


</body>

音乐播放的JS代码

全局变量

// 全局变量
var mainAudio = $('#main_audio');//获取元素
var isPlay = false;//声明一个标记,记录当前播放状态
var isMouseDownOnPlayBar = false;//记录鼠标按下音乐播放按钮状态
var isMouseDownOnVolumeBar = false;//记录鼠标按下音量按钮的状态
var isVolumeBarShow = false;//记录当前音量进度条显示状态
var musicList = [];//设置音乐列表
var playIdxNow = -1;//设置当前正在播放音乐的id

首页音乐列表歌单展示

通过ajax先后端发送请求得到歌单列表数据,通过for循环遍历歌单列表,设置每一首歌曲的title,actor,写入到歌单项的HTML模板中,然后通过append函数将歌单项模板添加到div.music-list中。当点击某个音乐时,调用加载音乐播放函数,实现当前点击音乐播放。

function getMusicList() {//获取首页歌单列表
    $.ajax({
        url: 'http://218.199.4.140:5000/list_music',
        success: function (data) {
            musicList = data.data;

            for (var i = 0; i < musicList.length; i++) {
                var actor = musicList[i].actor;
                var title = musicList[i].title;
                var id = musicList[i].id;
                var html = '<div class="item" onclick="loadMusic(' + i + ')">\
<div class="col" style = "width:50px;text-align: center;line-height:43px" >'+ (i + 1) + '</div>\
        <div class="col" style="width:calc(100% - 110px);">\
            <div class="song">'+ title + '</div>\
            <div class="act" style="font-size:80%">'+ actor + '</div>\
        </div>\
        <div class="col" style="width:50px;line-height:43px"><i class="fa fa-youtube-play fa-lg"></i></div>\
    </div></div>';
                $('.music-list').append(html);
            }
        }
    })
}

 加载指定音乐函数

记录当前音乐的索引,通过对应歌曲索引的id访问歌曲播放的请求地址,获取图片,播放地址,通过修改audio的src属性,更改音乐播放的地址,调用音乐播放函数,实现指定音乐的播放。

function loadMusic(i) {//加载指定音乐的index并且播放
    playIdxNow = i;
    $.ajax({
        url: 'http://218.199.4.140:5000/music_info?id=' + musicList[i].id,
        success: function (data) {
            var cover = data.cover;
            var u = data.abc;
            var img = data.cover;
            $('.cover').attr('src', img);
            $('.title').text(data.title);
            $('.actor').text(data.actor);
            mainAudio.attr('src', u);
            musicPlay();
        }
    })
}

//函数调用
getMusicList();
$(window).keypress(function (e) {
    if (e.keyCode != 32) return;
    console.log(e)
    PlayControl();

});

功能函数

音乐播放暂停函数

通过audio标签更改音乐的play和pause属性

// 功能函数
function musicPlay() {//音乐播放
    mainAudio[0].play();
    isPlay = true;
    $('.play-button i').removeClass('fa-play').addClass('fa-pause');
}

function musicPause() {//音乐暂停
    mainAudio[0].pause();
    isPlay = false;
    $('.play-button i').removeClass('fa-pause').addClass('fa-play');
}
function musicJumpByPerc(p) {//百分比定位控制音乐进度
    mainAudio[0].currentTime = mainAudio[0].duration * p;
}

控制音乐播放事件

通过给播放按钮添加鼠标单击事件,调用控制音乐播放函数。

//控制音乐播放事件
function PlayControl() {
    if (isPlay) {
        musicPause();
        $('.cover').removeClass('spinner');//移除图片旋转动画效果
    } else {
        musicPlay();
        $('.cover').addClass('spinner');
    }
};
$('.play-button').click(PlayControl);

切换当前播放音乐事件

通过判断当前播放音乐的索引,调用加载音乐函数,将上一首音乐或下一首音乐的索引传入函数,进行切换播放。

$(".forward-button").click(function () {//播放下一首音乐
    if (playIdxNow == musicList.length - 1) {//如果当前音乐的索引等于最后一首歌的索引
        loadMusic(0);//下一首歌则为第一首歌
    } else {
        loadMusic(playIdxNow + 1);//依次将索引加一
    }
})
$(".backward-button").click(function () {//播放上一首音乐
    if (playIdxNow == 0) {//如果当前音乐的索引等于第一首歌的索引
        loadMusic(musicList.length - 1);//上一首歌则为最后一首歌
    } else {
        loadMusic(playIdxNow - 1);//依次将索引减一
    }
})

进度条控制类

此控制类包含构造函数,将进度条,进度条控件,进度开始的方向作为参数,分别计算音乐播放进度条(x轴放置在进度条上横向拖动,方向记为left)和音量设置进度条(y轴放置在进度条上纵向拖动,方向记为top)的起点,终点的(x或y)坐标。使用绝对坐标设置进度函数,将事件发生的绝对坐标作为参数,如果该坐标在进度条的开始和结束坐标之间,则修改该坐标的方向属性为该坐标与起点的差(当前坐标在进度条上的长度距离)。使用百分比设置进度函数,将控件占进度条的百分比作为参数,分别用其百分比与进度条长度或高度相乘,设置当前进度的距离长度。获取进度函数,通过控件当前的距离比上进度条的距离得出当前控件进度百分比。后面将进度百分比传入音乐播放进度函数中,即可实现音乐播放进度与控件进度同步的效果。

音乐进度条和音量进度条分别调用此函数,得到两者控件的进度百分比。

//进度条控制类
class ProgressBar {
    constructor(bar, dot, direction) {
        this.bar = bar;
        this.dot = dot;
        this.direction = direction;
        if (direction == 'left') {
            this.start = bar.offset().left;//计算进度条开始坐标x
            this.end = this.start + bar.width() - 5;//结束x坐标
        }
        else {
            this.start = bar.offset().top;//计算音量控制小圆点的开始坐标y
            this.end = this.start + bar.height() - 5;//结束坐标y
        }


    }
    setPosByEvent(x) {//使用绝对坐标X设置进度
        if (x <= this.end && x >= this.start) {
            this.dot.css(this.direction, x - this.start + 'px');//进度条当前进度(根据小圆点x坐标计算)
        }
    }
    setPosByPerc(p) {//使用百分比设置进度
        if (this.direction == 'left')
            var x = p * this.bar.width();
        else
            var x = p * this.bar.height();
        this.dot.css(this.direction, x + 'px');
    }
    getPosByPerc() {//使用百分比获取进度
        return +this.dot.css(this.direction).replace('px', '') / (this.end - this.start);//获取控制小圆点的属性,并用空字符代替px进行百分比计算
    }
}

var musicBar = new ProgressBar($('#pro-bar'), $('#pro-control'), 'left');
var volumeBar = new ProgressBar($('#volume-bar'), $('#volume-control'), 'top');

鼠标事件

对鼠标进行监听,设置鼠标移动事件,记录鼠标当前(按下,弹起)的状态,鼠标按下时修改默认flag值为true,当鼠标弹起时,仍为false。在鼠标移动事件下对鼠标状态做一个判断,如果为按下时,则执行上文的(进度条拖动函数),否则不执行。

 //PC端添加Mouse事件
    $('#pro-control').on('mousedown', function () {//进度条控制圈按下事件
        isMouseDownOnPlayBar = true;
    });
    $('#volume-control').on('mousedown', function () {//进度条控制圈按下事件
        isMouseDownOnVolumeBar = true;//记录鼠标按下状态
        console.log('mousedown')
    });

    $(document).on('mousemove', function (event) {//鼠标移动函数,在鼠标按下状态改变进度条的控件位置属性
        if (isMouseDownOnPlayBar) {//如果鼠标按下,则执行绝对坐标定位函数,确定控件在进度条上距离起点的长度距离
            musicBar.setPosByEvent(event.pageX);
            var p = musicBar.getPosByPerc();//获取音乐进度条的百分比
            musicJumpByPerc(p);//通过音乐进度条百分比设置音乐播放进度
        }
        if (isMouseDownOnVolumeBar) {
            volumeBar.setPosByEvent(event.pageY);//如果鼠标按下,则执行绝对坐标定位函数,确定控件在音量条上距离起点的高度距离
            var p = volumeBar.getPosByPerc();//获取音量控件在进度条的百分比
            mainAudio[0].volume = 1 - p;//通过音量进度条百分比设置音量的大小
        }
    });

    $(document).on('mouseup', function () {
        isMouseDownOnPlayBar = false;
        isMouseDownOnVolumeBar = false;
    });

音量控制函数

该函数等同于音乐播放进度函数,流程同上。

$('.volume-button').click(function () {//音量进度条显示隐藏事件
    if (isVolumeBarShow) {
        $('.volume-control-panel').hide();//音量控制条隐藏
        isVolumeBarShow = false;
    } else {
        $('.volume-control-panel').show();//将音量进度条显示
        volumeBar = new ProgressBar($('#volume-bar'), $('#volume-control'), 'top');//调用进程函数设置音量的大小,控件跟随鼠标移动
        isVolumeBarShow = true;//更改隐藏状态
    }
}).blur(function () {//鼠标失去焦点 音量控制隐藏
    $('.volume-control-panel').hide();
    isVolumeBarShow = false;
});

 类似资料: