html+js简洁的音乐播放器,总有一款适合你

maolai web前端评论452阅读模式

经常在一些个人博客网站中看到各种各样的音乐播放器,它可以让你在阅读文章的同时欣赏唯美的音乐。HTML5标准的出现,使得在网页中嵌入音乐播放器变得十分简单,你可以直接在HTML页面中使用<audio>标签即可。以下这款音乐播放器使用了jQuery技术,使得网页中的音乐播放器具备播放列表的功能,点击列表即可切换至相应的歌曲。

1、带播放列表的jQuery音乐播放器--在线演示演示地址

js播放代码

//创建一个音乐播放器的类 单例模式
class Player {
    constructor() { //类的构造函数
        //如果类已经有实例了,就返回这个实例
        if (Player.instance) return Player.instance;
        //如果没有实例化,就去构造一个实例
        return this.getInstance(...arguments);
    }

    //构建实例
    getInstance() {
        let instance = new PlayerCreator(...arguments);
        //让实例可以使用到Player的原型的属性方法
        // instance.__proto__=Player.prototype;
        // instance.constructor=Player;
        //把构建好的实例挂在Player类上
        Player.instance = instance;
        return instance;
    }
}
//歌曲信息
class Musics {
    //歌曲
    constructor() {
        this.songs = [{
                id: 1,
                title: '每一天都不同',
                singer: '郭静',
                songUrl: 'http://www.bokequ.com/wo/images/meitianbutong.mp3',
                imageUrl: './images/songs/today.jpg'
            },
            {
                id: 2,
                title: '宁夏',
                singer: '梁静茹',
                songUrl: 'http://www.bokequ.com/blog/13/images/ningxia.mp3',
                imageUrl: 'http://www.bokequ.com/blog/13/images/photo.jpg'
            },
            {
                id: 3,
                title: '我很快乐',
                singer: '刘惜君',
                songUrl: 'http://www.bokequ.com/blog/12/images/kuaile.mp3',
                imageUrl: 'http://www.bokequ.com/blog/12/images/13.jpg'
            },
             {
                id: 4,
                title: '笔记',
                singer: '周笔畅',
                songUrl: 'http://www.bokequ.com/blog/2/images/biji.mp3',
                imageUrl: 'http://www.bokequ.com/blog/2/images/07.jpg'
            },
            {
                id: 5,
                title: '带着梦想去旅行',
                singer: '庄心妍',
                songUrl: 'http://www.bokequ.com/time/images/lvxing.mp3',
                imageUrl: './images/songs/mengxiang.jpg'
            }
        ]
    }
    //根据索引获取歌曲的方法
    getSongByNum(index) {
        return this.songs[index];
    }
}
//真正的构建播放器的类
class PlayerCreator {
    constructor() {
        this.audio = document.querySelector('.music-player__audio') // Audio dom元素, 因为很多api都是需要原生audio调用的,所以不用jq获取
        // this.audio.muted = true; // 控制静音
        this.audio.volume = 0.8;

        //工具
        this.util = new Util();
        this.musics = new Musics(); //歌曲信息
        this.song_index = 0; // 当前播放的歌曲索引
        this.loop_mode = 0; // 1 2
        // 下方歌曲列表容器
        this.song_list = $('.music__list_content');

        this.render_doms = { //切换歌曲时需要渲染的dom组
            title: $('.music__info--title'),
            singer: $('.music__info--singer'),
            image: $('.music-player__image img'),
            blur: $('.music-player__blur')
        }
        this.ban_dom = { //禁音时需要渲染的dom组
            control__btn: $('.control__volume--icon')
        }

        // 时间显示容器
        this.render_time = {
            now: $('.nowTime'),
            total: $('.totalTime')
        }

        // 唱片
        this.disc = {
            image: $('.music-player__image'),
            pointer: $('.music-player__pointer')
        };
        //播放器初始化
        this.init();
    }
    //初始化函数
    init() {
        this.renderSongList();
        this.renderSongStyle();
        this.bindEventListener();
    }
    //生成播放列表
    renderSongList() {
        let _str = '';
        this.musics.songs.forEach((song, i) => {
            _str += `<li class="music__list__item">${song.title}</li>`
        });
        this.song_list.html(_str);
    }

    //根据歌曲去渲染视图
    renderSongStyle() {
        let {
            title,
            singer,
            songUrl,
            imageUrl
        } = this.musics.getSongByNum(this.song_index);
        this.audio.src = songUrl;
        this.render_doms.title.html(title);
        this.render_doms.singer.html(singer);
        this.render_doms.image.prop('src', imageUrl);
        this.render_doms.blur.css('background-image', 'url("' + imageUrl + '")');

        //切换列表中的item的类名 play
        this.song_list.find('.music__list__item').eq(this.song_index).addClass('play').siblings().removeClass('play');
    }
    //绑定各种事件
    bindEventListener() {
        //播放按钮
        this.$play = new Btns('.player-control__btn--play', {
            click: this.handlePlayAndPause.bind(this)
        });
        //上一首
        this.$prev = new Btns('.player-control__btn--prev', {
            click: this.changeSong.bind(this, 'prev')
        });
        //下一首
        this.$next = new Btns('.player-control__btn--next', {
            click: this.changeSong.bind(this, 'next')
        });
        //循环模式
        this.$mode = new Btns('.player-control__btn--mode', {
            click: this.changePlayMode.bind(this)
        });
        //禁音
        this.$ban = new Btns('.control__volume--icon', {
            click: this.banNotes.bind(this)
        })
        //列表点击
        this.song_list.on('click', 'li', (e) => {
            let index = $(e.target).index();
            this.changeSong(index);
        })

        //音量控制 audio标签音量 vlouem 属性控制0-1

        new Progress('.control__volume--progress', {
            min: 0,
            max: 1,
            value: this.audio.volume,
            handler: (value) => { //更改进度时
                this.audio.volume = value;
            }
        })


        //歌曲进度 this.audio.duration

        //可以播放的时候触发(歌曲的基本信息都已经获取到了)
        this.audio.oncanplay = () => {
            //避免重复实例化
            if (this.progress) {
                this.progress.max = this.audio.duration; //切换歌曲后更新时长
                this.render_time.total.html(this.util.formatTime(this.audio.duration));
                return false;
            };
            this.progress = new Progress('.player__song--progress', {
                min: 0,
                max: this.audio.duration,
                value: 0,
                handler: (value) => {
                    this.audio.currentTime = value;
                }
            })
            //调整总时长
            this.render_time.total.html(this.util.formatTime(this.audio.duration));
        }

        //会在播放的时候持续触发
        this.audio.ontimeupdate = () => {
            this.progress.setValue(this.audio.currentTime);
            //调整当前时长
            this.render_time.now.html(this.util.formatTime(this.audio.currentTime));
        }

        //当歌曲播放完成的时候
        this.audio.onended = () => {
            this.changeSong('next');
            //播放完,换歌后,重新播放
            this.audio.play();
        }

    }

    //播放暂停控制
    handlePlayAndPause() {
        let _o_i = this.$play.$el.find('i');
        //this.audio.pauseed值为true 说明目前是不播放
        if (this.audio.paused) { //现在是暂停的 要播放
            this.audio.play();
            _o_i.removeClass('icon-play').addClass('icon-pause');
            this.disc.image.addClass('play');
            this.disc.pointer.addClass('play')
        } else {
            this.audio.pause();
            _o_i.addClass('icon-play').removeClass('icon-pause');
            this.disc.image.removeClass('play');
            this.disc.pointer.removeClass('play');
        }
    }

    //更改循环模式
    changePlayMode() {
        this.loop_mode++;
        if (this.loop_mode > 2) this.loop_mode = 0;
        this.renderPlayMode();
    }
    //更改按钮样式
    renderPlayMode() {
        let _classess = ['loop', 'random', 'single'];
        let _o_i = this.$mode.$el.find('i');
        //prop 改一些标签的自有属性 attr改一些标签的自定义属性
        _o_i.prop('class', 'iconfont icon-' + _classess[this.loop_mode])
    }

    //更改歌曲索引
    changeSongIndex(type) {
        if (typeof type === 'number') {
            this.song_index = type;
        } else {
            if (this.loop_mode === 0) {
                //列表循环
                this.song_index += type === 'next' ? 1 : -1;
                if (this.song_index > this.musics.songs.length - 1) this.song_index = 0;
                if (this.song_index < 0) this.song_index = this.musics.songs.length - 1;
            } else if (this.loop_mode === 1) {
                //随机播放
                let _length = this.musics.songs.length;
                let _random = Math.floor(Math.random() * _length);
                for (let i = 0; i < 10000; i++) { //随机的数为本身则继续随机
                    if (this.song_index == _random) {
                        _random = Math.floor(Math.random() * _length);
                    } else {
                        this.song_index = _random;
                        break;
                    }
                }
            } else if (this.loop_mode === 2) {
                this.song_index = this.song_index;
            }
        }
    }
    //歌曲时长
    songTime() {
        let totalMinute = parseInt(this.audio.duration / 60) < 10 ? "0" + parseInt(this.audio.duration / 60) : parseInt(this.audio.duration / 60);
        let totalSecond = parseInt(this.audio.duration % 60) < 10 ? "0" + parseInt(this.audio.duration % 60) : parseInt(this.audio.duration % 60);
        $('.totalTime').text(totalMinute + ':' + totalSecond);
    }
    //切换歌曲
    changeSong(type) {
        //更改索引
        this.changeSongIndex(type);
        //记录切歌前的状态
        let _is_pause = this.audio.paused;
        //切歌后更改视图显示
        this.renderSongStyle();
        //如果切歌前是在播放,就继续播放
        if (!_is_pause) this.audio.play();
    }
    //禁音
    banNotes() {
        let _o_i = this.$ban.$el.find("i");
        if (this.audio.muted == true) { //如果禁音则开启
            this.audio.muted = false;
            _o_i.removeClass('icon-muted').addClass('icon-volume');
        } else {
            this.audio.muted = true;
            _o_i.removeClass('icon-volume').addClass('icon-muted');
        }
    }
}

//进度条
class Progress {
    constructor(selector, options) {
        $.extend(this, options);
        ///给this挂载传入的参数
        this.$el = $(selector);
        this.width = this.$el.width();
        this.init();
    }

    //进度条初始化
    init() {
        this.renderBackAndPointer();
        //this.bindEvents();
        this.drag();
        this.value;
        this.changeDOMStyle(this.width * this.value);
    }
    //为进度条渲染back和pointer
    renderBackAndPointer() {
        this.$back = $('<div class="back">');
        this.$pointer = $('<div class="pointer">');

        this.$el.append(this.$back);
        this.$el.append(this.$pointer);
    }

    setValue(value) { //主动调用,传入value值,设置进度条样式
        let _distance = this.width * value / (this.max - this.min);
        this.changeDOMStyle(_distance);
    }

    drag() {
        let ele = this.$pointer;
        let father = this.$el;
        let flag = false; //鼠标是否点击
        ele.mousedown((e) => {
            flag = true;
            let mousePos = {
                x: e.offsetX
            }
            $(document).mousemove((e) => {
                if (flag === true) {
                    let _left = e.clientX - father.offset().left - mousePos.x;
                    let _distance = Math.max(0, Math.min(_left, father.outerWidth(false) - ele.outerWidth(false)))
                    let _ratio = _distance / father.outerWidth(false);
                    let _value = _ratio * (this.max - this.min); //当前的音量值
                    this.changeDOMStyle(_distance);
                    this.handler(_value); //更改进度之后,执行回调
                }
            })
        })
        $(document).mouseup(() => {
            flag = false;
        })

    }

    bindEvents() { //鼠标点击时更改
        this.$el.click((e) => {
            let _x = e.offsetX; //鼠标距离元素左边的距离
            let _ratio = _x / this.width;
            let _value = _ratio * (this.max - this.min); //当前的音量值
            this.changeDOMStyle(_x);
            this.handler(_value); //更改进度之后,执行回调
        })
    }
    //更改pointer和back
    changeDOMStyle(distance) {
        this.$back.width(distance + 7 == 7 ? 0 : distance + 7);//进度为0时将进度条背景改为0否则加上进度按钮的长度
        this.$pointer.css('left', distance + 'px');
    }
}


//按钮类 
class Btns {
    constructor(selector, handlers) {
        this.$el = $(selector); //元素
        this.bindEvents(handlers);
    }
    bindEvents(handlers) { //绑定事件
        for (const event in handlers) {
            //使用值的时候保证键值对在对象中是存在的
            if (handlers.hasOwnProperty(event)) {
                this.$el.on(event, handlers[event]);
            }
        }
    }
}
new Player();

2、这是一款黑色的HTML5音乐播放器。黑色质感状的背景,看起来非常炫酷。同时这款音乐播放器具备了最基本的音乐播放器功能。

质感炫酷的HTML5音乐播放器---在线演示

3、这是一款基于HTML5的古典风格的音乐播放器,它的样式是早期西洋的转盘式音乐盒,侧边有一栏播放器控制按钮,可以播放、暂停、上/下一曲、前进后退,是一款非常个性化的HTML5音乐播放器。音乐地址在js文件index.js修改。

HTML5古典风格的音乐播放器---在线演示

/**
 * Created by Nandem on 2015/11/12.
 */
var $playBtn;
var $pauseBtn;
var $nextBtn;
var $preBtn;
var $stopBtn;
var $muteBtn;
var $firstBtn;
var $lastBtn;
var $shuffleMode;
var $listMode;
var $loopMode;
var myAudio;
var controllArm;
var $cdCover;
var iStartDeg;
var iEndDeg;
var iIncrement;
var songsListIndex;//the index of song in the songslist
var playMode;//list shuffle loop
var shuffleIndex;
var shuffleIndexCount;

$().ready(function ()
{
    init();
    for(var i = 0; i < songsList.length; i++)
    {
        songsList[i].musicURL = encodeURI(songsList[i].musicURL);
    }
    myAudio.src = decodeURI(songsList[songsListIndex].musicURL);
    /*^_^------------------some event listeners-------------------^_^*/
    myAudio.addEventListener('ended', function ()
    {
        controllArm.style.transform="rotate(-130deg)"
        if(playMode == "list")
        {
            songsListIndex++;
            if (songsListIndex >= songsList.length + 1)
                songsListIndex = 0;
        }
        else if(playMode == "shuffle")
        {
            songsListIndex = shuffle();
        }
        else
        {
            songsListIndex = songsListIndex;
        }
        myAudio.src = decodeURI(songsList[songsListIndex].musicURL);
        myAudio.load();
        iStartDeg = -95;
        iEndDeg = -120;
        myAudio.play();
    }, false);

    myAudio.addEventListener("timeupdate", function ()
    {
        var $myCon = $("#myConsole");
        if (!isNaN(myAudio.duration))
        {
            var progressValue = myAudio.currentTime/myAudio.duration;
            if(myAudio.paused)
                return;//confrim the controllerArm can be rotated immediately
            iStartDeg = -95 - 25 * progressValue;
            controllArm.style.transform = "rotate(" + iStartDeg +"deg)";
            $myCon.text(songsList[songsListIndex % songsList.length].title + "-" + songsList[songsListIndex % songsList.length].artist);
        }
        else
            $myCon.text("error");
    }, false);
});

function initEventClick()
{
    /*^_^------------------some click events-------------------^_^*/
    $playBtn.click(function ()
    {
        iIncrement = (iStartDeg - iEndDeg);
        controllArm.style.transform="rotate(" + iStartDeg +"deg)";
        if($cdCover.hasClass("cdPause"))
        {
            $cdCover.removeClass("cdPause");
            $cdCover.removeClass("cdStart");
        }
        if(!$cdCover.hasClass("cdStart"))
            $cdCover.addClass("cdStart");
        myAudio.play();
    });
    $pauseBtn.click(function ()
    {
        controllArm.style.transform="rotate(-130deg)"
        if(!$cdCover.hasClass("cdPause"))
            $cdCover.addClass("cdPause");
        myAudio.pause();
    });
    $nextBtn.click(function ()
    {
        changeSong("next");
    });
    $preBtn.click(function ()
    {
        changeSong("pre");
    });

    $stopBtn.click(stop);
    function stop()
    {
        controllArm.style.transform="rotate(-130deg)"
        $cdCover.removeClass("cdPause");
        $cdCover.removeClass("cdStart");
        myAudio.load();
    }

    $muteBtn.click(function ()
    {
        myAudio.muted = !myAudio.muted;
        if(myAudio.muted)
            $(this).css({"color":'red'});
        else
            $(this).css({"color":'#b1b9c6'});
    });
    $firstBtn.click(function ()
    {
        changeSong("first");
    });
    $lastBtn.click(function ()
    {
        changeSong("last");
    });

    $shuffleMode.click(function ()
    {
        playMode = "shuffle";
        $("#playMode").find("div").css({"color":"#b1b9c6"});
        $(this).css({"color":"#e74d3c"});
    });
    $listMode.click(function ()
    {
        playMode = "list";
        $("#playMode").find("div").css({"color":"#b1b9c6"});
        $(this).css({"color":"#e74d3c"});
    });
    $loopMode.click(function ()
    {
        playMode = "loop";
        $("#playMode").find("div").css({"color":"#b1b9c6"});
        $(this).css({"color":"#e74d3c"});
    });

    /*^_^------------------some buttons' hover-------------------^_^*/
    $muteBtn.hover
    (
        function ()
        {
            if(!myAudio.muted)
                $(this).css({"color":'#ffffff'});
        },
        function ()
        {
            $(this).css({"color":'#b1b9c6'});
            if(myAudio.muted)
                $(this).css({"color":'red'});
        }
    );
}

function initComponents()
{
    $playBtn = $("#playBtn");
    $pauseBtn = $("#pauseBtn");
    $nextBtn = $("#nextBtn");
    $preBtn = $("#preBtn");
    $stopBtn = $("#stopBtn");
    $muteBtn = $("#muteBtn");
    $firstBtn = $("#firstBtn");
    $lastBtn = $("#lastBtn");
    $shuffleMode = $("#shuffleMode");
    $listMode = $("#listMode");
    $loopMode = $("#loopMode");
    myAudio = $("#myAudio")[0];
    controllArm = $("#cdControllerArm")[0];
    $cdCover = $("#cdCover");
    iStartDeg = -95;
    iEndDeg = -120;
    iIncrement = 25;
    songsListIndex = 0;//the index of song in the songslist
    playMode = "list";//list shuffle loop
    $("#listMode").css({"color":"#e74d3c"});
    shuffleIndex = [];
    shuffleIndexCount = songsList.length - 1;
    initShuffleGenerator();
}

function initShuffleGenerator()
{
    for(var i = 0; i < songsList.length; i++)
    {
        shuffleIndex[i] = i;
    }
}

function init()
{
    initComponents();
    initEventClick();
}

/*^_^------------------some core functions-------------------^_^*/
//var shuffleIndex = [0, 1, 2, 3, 4, 5, 6];
//var shuffleIndexCount = 6;
function shuffle()
{
    var tem = getRandom(shuffleIndexCount);
    var tem2 = shuffleIndex[tem];
    shuffleIndex[tem] = shuffleIndex[shuffleIndexCount];

    shuffleIndexCount--;
    if(shuffleIndexCount < 0)
    {
        shuffleIndexCount = songsList.length;
    }
    return tem2;
}

function changeSong(whatDirection)
{
    if(myAudio.currentTime != 0)
    {
        if(!myAudio.paused)
        {
            if ($cdCover.hasClass("cdPause")) {
                $cdCover.removeClass("cdPause");
                $cdCover.removeClass("cdStart");
            }
            if (!$cdCover.hasClass("cdStart"))
                $cdCover.addClass("cdStart");
            controllArm.style.transform = "rotate(-130deg)"
            if (whatDirection == "pre") {
                songsListIndex--;
                if (songsListIndex <= -1)
                    songsListIndex = songsList.length;
            }
            else if (whatDirection == "next") {
                songsListIndex++;
                if (songsListIndex >= songsList.length + 1)
                    songsListIndex = 0;
            }
            else if (whatDirection == "first") {
                songsListIndex = 0;
            }
            else if(whatDirection == "last")
            {
//                alert(songsList.length);
                songsListIndex = songsList.length - 1;
//                alert(songsListIndex);
            }
            else
            {
            }
            myAudio.src = decodeURI(songsList[songsListIndex].musicURL);
            myAudio.load();
            myAudio.play();
        }
    }
}

/*^_^------------------some assistant functions-------------------^_^*/
//generate random
function getRandom(n)
{
    return Math.floor(Math.random()*n+1)
}

//convert float/double to percent
Number.prototype.toPercent = function(n)
{
    n = n || 2;
    return ( Math.round( this * Math.pow( 10, n + 2 ) ) / Math.pow( 10, n ) ).toFixed( n ) + '%';
};

/*^_^-------------------------songs list--------------------------^_^*/
var songsList =
[
    {
        "title" : "黄梅戏",
        "artist" : "慕容晓晓",
        "coverURL" : "",
        "musicURL" : "./audio/huangmeixi.mp3"
    },
    {
        "title" : "ANDY",
        "artist" : "阿杜",
        "coverURL" : "",
        "musicURL" : "http://img.bokequ.com/music/andy.mp3"
    },
    {
        "title" : "留什么给你",
        "artist" : "孙楠",
        "coverURL" : "",
        "musicURL" : "http://img.bokequ.com/music/geini.mp3"
    },
    {
        "title" : "最近",
        "artist" : "李圣杰",
        "coverURL" : "",
        "musicURL" : "http://img.bokequ.com/music/zuijin.mp3"
    },
    {
        "title" : "扬州",
        "artist" : "李晋",
        "coverURL" : "",
        "musicURL" : "./audio/6457.mp3"
    },
    {
        "title" : "小五",
        "artist" : "崔跃文",
        "coverURL" : "",
        "musicURL" : "./audio/6457.mp3"
    },
    {
        "title" : "多兰娜",
        "artist" : "浩子",
        "coverURL" : "",
        "musicURL" : "./audio/6457.mp3"
    }
]

4、这是一款HTML5环形音乐播放器,有播放列表,用户可以选择音乐来播放。

超酷HTML5环形音乐播放器 带播放列表---在线演示

5、这是一款实用的移动端UI设计,音乐播放器下载免费版参考,点击按钮可实现音乐在线播放,内含音乐列表,100%响应。音乐地址添加修改在script.js文件
---在线演示

 
maolai
  • 本文由 maolai 发表于 2024年5月11日 21:47:45
  • 转载请务必保留本文链接:http://www.bokequ.com/541.html

发表评论