H5音樂播放器

大力美少女發表於2019-04-11

效果

H5音樂播放器

功能

  • 歌曲切換
  • 歌詞同步(並給樣式)
  • 進度條拖動、點選
  • 音量控制
  • 監聽下一曲自動播放

技術解析

  • json偽資料操作 ( 歌詞)
  • 獲取audio屬性
  • 建構函式,每首歌配置初始化
  • 進度條操作,滑鼠事件
  • 阿里雲圖示

網盤下載:連結:pan.baidu.com/s/1kV4hn9t 密碼:ezik

程式碼(靜態資源在網盤)

    <!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <title>音樂播放器</title>
    <style type="text/css">
    *{
        padding: 0;
        margin: 0
    }
    @font-face {font-family: 'iconfont';
    src: url('font/iconfont.eot'); /* IE9*/
    src: url('font/iconfont.eot?#iefix') format('embedded-opentype'), /* IE6-IE8 */
    url('font/iconfont.woff') format('woff'), /* chrome、firefox */
    url('font/iconfont.ttf') format('truetype'), /* chrome、firefox、opera、Safari, Android, iOS 4.2+*/
    url('font/iconfont.svg#iconfont') format('svg'); /* iOS 4.1- */
}
    html,body{
        height: 100%;
        background: linear-gradient(top,#fb3737,#3323fd);
        background: -moz-linear-gradient(top,#fb3737,#3323fd),-moz-linear-gradient(top,#fb3737,#3323fd);
        background: -webkit-linear-gradient(top,#fb3737,#3323fd),-webkit-radial-gradient(ellipse,#fff,#fff);
    }
    .clear{}
    .clear::after{
        content: "";
        display: block;
        width: 100%;
        height: 0;
        clear: both;
    }
    .container{
        position: absolute;
        top:50%;
        left: 50%;
        margin-left: -400px;
        margin-top: -300px;
        width: 800px;
        height: 600px;
        /*border: 1px solid rgba(255,255,255,0.5);*/
        box-shadow: 0 0 10px rgba(255,255,255,0.5);
        background: linear-gradient(top,#fb4b4b,#3f3ffb);
        background: -moz-linear-gradient(top,#fb4b4b,#3f3ffb);
        background: -webkit-linear-gradient(top,#fb4b4b,#3f3ffb);
    }
    .music{
        width: 50%;
        height: 100%;
        border-right: 1px solid rgba(255,255,255,0.5);
        box-sizing: border-box;
        float: left;
    }
    .photo{
        width: 100%;
    }
    .photo_pic{
        position: relative;
        width: 250px;
        height: 250px;
        margin: 75px auto 0;
        border-radius: 50%;
        background: url(img/photo1.jpg);
        box-shadow:0 0 2px #666, 0 0 10px #666;
    }
    .choose{
        height:150px;
    }
    .choose_obj{
        width: 50%;
        float: left;
        text-align: center;
        color: #fff
    }
    .icon{
        margin-top: 40px;
        height: 50px;
        font-size:50px;
        line-height: 50px;
        font-family: "iconfont";
        cursor: pointer;
        text-shadow: 2px 2px 0px #666;
    }
    .icon.yellow+span{
        color: yellow;
    }
    .icon.pink+span{
        color: #f7759f;
    }
    .choose_obj span{
        display: block;
        height: 30px;
        line-height: 30px;
        font-family: "微軟雅黑";
        font-size: 14px;
    }
    .cd{
        width: 10px;
        height: 10px;
        position: absolute;
        top:50%;
        left: 50%;
        margin-top: -15px;
        margin-left: -15px;
        background: #666;
        border: 10px solid #fff;
        box-shadow: 0 0 1px #000;
        border-radius: 50%;
    }
    .progress{
        font-family: "iconfont"
    }
    .lyric{
        width: 50%;
        height: 100%;
        float: right;
    }
    time{
        font-size: 12px;
        width: 49px;
        text-align: center;
        color: #fff;
        height: 50px;
        line-height: 50px;
        float: left;
    }
    .progress_bar{
        position: relative;
        width: 300px;
        height: 2px;
        margin-top: 23px;
        background-color: #fff;
        float: left;
        cursor: pointer;
    }
    .progress_cube{
        position: absolute;
        left: 0;
        top: -5px;
        width: 4px;
        height: 4px;
        background-color: #000;
        border:5px solid #fff;
        border-radius: 50%;
        cursor: pointer;
    }
    .progress_obj{
        line-height: 30px;
        color: #fff;
    }
    .ctrl_btn{
        width: 99px;
        float: left;
    }

    .ctrl_btn .btn{
        width: 33.3%;
        float: left;
        text-align: center;
        cursor: pointer;
    }
    .play_btn{
        font-size: 24px;
    }
    .ctrl_info{
        width: 300px;
        float: left;
    }
    .vol{
        padding-left: 100px;
        width: 100px;
        height: 100%;
        float: left;
    }
    .vol_bar{
        position: relative;
        width: 70px;
        float: right;
        height: 2px;
        background-color: #fff;
        margin-top: 13px;
    }
    .vol_cube{
        position: absolute;
        left: 0;
        top: -4px;
        width: 3px;
        height: 3px;
        background-color: #000;
        border:4px solid #fff;
        border-radius: 50%;
        cursor: pointer;
    }
    .list{
        width: 100px;
        height: 100%;
        float: right;
        text-align: center;
    }
    .lyric_tit{
        height: 50px;
        line-height: 50px;
        color: #fff;
        text-align: center;
        font-weight: 700;
        margin-top: 30px;
    }
    .lyric_con{
        position: relative;
        line-height: 40px;
        color: #fff;
        font-size: 14px;
        padding: 0px 50px ;
        text-align: center;
        height: 450px;
        overflow: hidden;
        margin-top: 20px;       
    }
    #lyric_txt{
        position: absolute;
        left: 0;
        top:0;
        width: 100%;
        height: 100%;
    }
    .lyric_con p.played{
        color: yellow;
    }
    .lyric_con p.active{
        color: yellow;
        font-size: 20px;
        font-weight: 700;
    }
    .audio{
        display: none;
    }
    #list{
        position: relative;
        cursor: pointer;
    }
    #list_con{
        position: absolute;
        bottom: 30px;
        right: 40px;
        width: 150px;
        height: 100px;
        color: #666;
        padding: 10px 0;
        border-radius: 5px;
        background: rgba(255,255,255,.8);
        font-family: "微軟雅黑";
        font-size: 14px;
        cursor: pointer;
        display: none;
    }
    </style>
</head>
<body>
    <div class="container" id="container">
        <div class="music">
            <div class="photo">
                <div class="photo_pic" id="photo_pic"><div class="cd"></div></div>
                <div class="choose">
                    <div class="choose_obj choose_like" >
                        <div class="icon" id="icon1">
                            
                        </div>
                        <span>喜歡</span>
                    </div>
                    <div class="choose_obj choose_share">
                        <div class="icon" id="icon2">
                            
                        </div>
                        <span>收藏</span>
                    </div>
                </div>
            </div>
            <div class="progress">
                <div class="progress_obj clear">
                    <time>00:00</time>
                    <div class="progress_bar" id="progress_bar"><div class="progress_cube" id="progress_cube"></div></div>
                    <time>00:00</time>
                </div>
                <div class="progress_obj clear">
                    <div class="ctrl_btn">
                        <div id="prev_btn" class="prev_btn btn"></div>
                        <div id="play_btn" class="play_btn btn"></div>
                        <div id="next_btn" class="next_btn btn"></div>
                    </div>
                    <div class="ctrl_info">
                        <div class="vol"><div class="vol_bar" id="vol_bar"><div class="vol_cube" id="vol_cube"></div></div></div>
                        <div class="list" id="list"><div id="list_con"><p>fffffffff</p><p>fffffffff</p><p>fffffffff</p></div></div>
                    </div>
                    <audio src="song/王菲-笑忘書.mp3"></audio>
                </div>
            </div>
        </div>
        <div class="lyric">
            <div class="lyric_tit" id="lyric_tit"></div>
            <div class="lyric_con" id="lyric_con"><div id="lyric_txt"></div></div>
        </div>
    </div>
</body>
</html>
<script type="text/javascript">
//data
var lyric=[{'name':"笑忘書",'img':'img/photo1.jpg','audio_src':'song/王菲-笑忘書.mp3','content':"[00:00.00][00:01.00]笑忘書(國)[00:03.00]王菲[00:05.00][00:12.00]沒 沒有蠟燭 就不用勉強慶祝[00:17.00]沒 沒想到答案 就不用尋找題目[00:23.00]沒 沒有退路 問我也不要思路[00:29.00]沒 沒人去仰慕 那我就繼續忙碌[00:34.00]lalala 思前想後[00:37.00]差一點忘記了怎麼投訴[00:40.00]lalala 從此以後 不要犯同一個錯誤[00:46.00]將這樣的感觸 寫一封情書送給我自己[00:51.00]感動得要哭 很久沒哭[00:54.00]不失為天大的幸福 將這一份禮物[00:59.00]這一封情書 給自己祝福[01:02.00]可以不在乎 才能對別人在乎[01:20.00]有 一點幫助 就可以對誰傾訴[01:26.00]有 一個人保護 就不用自我保護[01:32.00]有 一點滿足 就準備如何結束[01:37.00]有 一點點領悟 就可以往後回顧01:43.00]lalala 思前想後[01:46.00]差一點忘記了怎麼投訴[01:49.00]lalala 從此以後 不要犯同一個錯誤[01:54.00]將這樣的感觸 寫一封情書送給我自己[01:59.00]感動得要哭 很久沒哭[02:03.00]不失為天大的幸福 將這一份禮物[02:08.00]這一封情書 給自己祝福[02:11.00]可以不在乎 才能對別人在乎[02:43.00]Lalalala....... Lalalala.......[02:55.00]從開始哭著忌妒 變成了笑著羨慕[03:00.00]時間是怎麼樣把握了我皮膚[03:03.00]只有我自己最清楚[03:06.00]將這樣的感觸 寫一封情書送給我自己[03:11.00]感動得要哭 很久沒哭[03:15.00]不失為天大的幸福 將這一份禮物[03:19.00]這一封情書 給自己祝福[03:22.00]可以不在乎 才能對別人在乎[03:28.00]讓我親手 將這樣的感觸[03:31.00]寫一封情書送給我自己[03:34.00]感動得要哭 很久沒哭[03:37.00]不失為天大的幸福[03:39.00]就好好將這一份禮物[03:42.00]這一封情書 給自己祝福[03:45.00]可以不在乎 才能對別人在乎 "
},{'name':"化身孤島的鯨",'img':'img/photo2.jpg','audio_src':'song/李逸朗-化身孤島的鯨.mp3','content':"[00:00.00] 化身孤島的鯨[00:03.00] 作詞:沃特艾文兒[00:06.00] 作曲:徐浩[00:09.00] 編曲:伍昊予[00:12.00] 演唱:李逸朗[00:15.00] Lrc By:吉時雨[00:18.00] QQ:132 7269 041[00:21.00] www.cnLyric.com [00:25.64] 我是隻化身孤島的藍鯨[00:28.94] 有著最巨大的身影[00:33.46] 魚蝦在身側穿行[00:37.23] 也有飛鳥在背上停[00:42.48] 我路過太多太美的奇景[00:45.85] 如同伊甸般的仙境[00:50.11] 而大海太平太靜[00:53.96] 多少故事無人傾聽[00:58.91] 我愛地中海的天晴[01:02.55] 愛西伯利亞的雪景[01:06.30] 愛萬丈高空的鷹[01:08.59] 愛肚皮下的藻荇[01:10.94] 我在盡心盡力地多情[01:14.20] 直到那一天[01:20.11] 你的衣衫破舊[01:22.19] 而歌聲卻溫柔[01:24.19] 陪我漫無目的地四處漂流[01:28.24] 我的背脊如荒丘[01:30.49] 而你卻微笑擺首[01:32.91] 把它當成整個宇宙[01:37.24] 你與太陽揮手[01:39.13] 也同海鷗問候[01:41.25] 陪我愛天愛地的四處風流[01:45.13] 只是遺憾你終究[01:47.33] 無法躺在我胸口[01:49.78] 欣賞夜空最遼闊的不朽[01:53.71] 把星子放入眸[02:03.33] 我是隻化身孤島的藍鯨[02:06.98] 有著最巨大的身影[02:10.96] 魚蝦在身側穿行[02:15.06] 也有飛鳥在背上停[02:20.18] 我有著太冷太清的天性[02:23.90] 對天上的她動過情[02:27.95] 而云朵太遠太輕[02:32.21] 輾轉之後各安天命[02:36.50] 我未入過繁華之境[02:40.35] 未聽過喧囂的聲音[02:44.05] 未見過太多生靈[02:46.24] 未有過滾燙心情[02:48.77] 所以也未覺大洋正中[02:52.58] 有多麼安靜[02:57.10] 你的衣衫破舊[02:59.02] 而歌聲卻溫柔[03:01.18] 陪我漫無目的四處漂流[03:05.32] 我的背脊如荒丘[03:07.34] 而你卻微笑擺首[03:10.16] 把它當成整個宇宙03:13.96] 你與太陽揮手[03:15.97] 也同海鷗問候[03:18.13] 陪我愛天愛地的四處風流[03:22.12] 只是遺憾你終究[03:24.20] 無法躺在我胸口[03:27.06] 欣賞夜空最遼闊的不朽[03:30.54] 把星子放入眸[03:34.73] 你的指尖輕柔[03:36.91] 撫摸過我所有[03:39.15] 風浪衝撞出的醜陋瘡口[03:43.03] 你眼中有春與秋[03:45.40] 勝過我見過愛過[03:47.78] 的一切山川與河流[03:51.98] 曾以為我肩頭[03:53.90] 是那麼的寬厚[03:55.92] 足夠撐起海底那座瓊樓[03:59.75] 而在你到來之後[04:02.09] 它顯得如此清瘦[04:04.55] 我想給你能奔跑的岸頭[04:08.20] 讓你如同王后"},{'name':"被馴服的象",'img':'img/photo3.jpg','audio_src':'song/蔡健雅-被馴服的象.mp3','content':"[00:00.00]被馴服的象[00:04.64]蔡健雅[00:09.74][00:22.46]到底要笑得多虛偽&emsp;才能夠融入這世界[00:28.13]每個人的臉上都像是貼了張一樣的假面[00:33.71]想不起我在做什麼&emsp;想不起我在想什麼[00:39.12]想不起靈魂深處&emsp;到底發生了什麼[00:43.95]迷霧 迷霧 在迷霧&emsp;我驚覺自己在原地踏步[00:49.03]到底是誰把我心矇住&emsp;不想再糊塗[00:54.63]迷路 迷路 迷了路&emsp;我就徹底被這團迷霧困住[00:59.92]誰能夠指引我一條路&emsp;帶我走上正途[01:07.94][01:16.94]裝不出融入的態度&emsp;空氣裡充斥著虛無[01:22.68]說什麼都掩飾不了我這局外人的侷促[01:28.21]想不通自己怎麼了&emsp;想不通世界怎麼了[01:33.61]想不通心靈深處&emsp;到底變成什麼了[01:38.30]迷霧 迷霧 在迷霧&emsp;我驚覺自己在原地踏步[01:43.54]到底是誰把我心矇住&emsp;不想再糊塗[01:49.24]迷路 迷路 迷了路&emsp;我就徹底被這團迷霧困住[01:54.46]誰能夠指引我一條路&emsp;帶我走上正途[02:00.34]掌聲 若需要掌聲&emsp;只要你願當被馴服的象[02:08.16]這舞臺你就可以上&emsp;榮耀 勝過被嘲笑[02:15.60]所以拋開自尊&emsp;咬緊牙根硬撐[02:21.92]迷霧 迷霧 在迷霧&emsp;我驚覺自己在原地踏步[02:27.11]到底是誰把我心矇住&emsp;不想再糊塗[02:32.89]迷路 迷路 迷了路&emsp;我就徹底被這團迷霧困住[02:38.08]誰能夠指引我一條路&emsp;帶我走上正途[02:44.13]迷路 迷路 迷了路&emsp;我就徹底被這團迷霧困住[02:48.94]誰能夠指引我一條路&emsp;帶我走上正途[02:59.51]"}]
    window.onload=function()
    {
        var play_btn=document.getElementById("play_btn");
        var prev_btn=document.getElementById("prev_btn");
        var next_btn=document.getElementById("next_btn");
        var audio=document.getElementsByTagName("audio")[0];
        var initTime=document.getElementsByTagName("time")[0];
        var time=document.getElementsByTagName("time")[1];
        var progress_bar=document.getElementById("progress_bar");
        var progress_cube=document.getElementById("progress_cube");
        var vol_bar=document.getElementById("vol_bar");
        var vol_cube=document.getElementById("vol_cube");
        var lyric_con=document.getElementById("lyric_con");
        var lyric_txt=document.getElementById("lyric_txt");
        var photo_pic=document.getElementById("photo_pic");
        var icon1=document.getElementById("icon1");
        var icon2=document.getElementById("icon2");
        var lyric_tit=document.getElementById("lyric_tit");
        var list_con=document.getElementById("list_con");
        var list_item=list_con.getElementsByTagName("p");
        var songIndex=0;
        var container=document.getElementById("container");
        var obj;        
        function config()
        {
            this.play_mark=true;
            this.duration=audio.duration;
            this.play_btn="";
            this.vol=audio.volume;
            this.timer=null;
            this.rotateSum=0;
            this.icon1=icon1.innerHTML;
            this.icon2=icon2.innerHTML;
            this.icon1_co=icon1.style.color;
            this.endplay_btn="";
            this.endicon1=icon1.innerHTML;
            this.endicon2="";
        }

        obj= new config();
        //列表控制

        var allSong="";
        for(var song=0;song<lyric.length;song++)
        {
            allSong+="<p>"+lyric[song].name+"</p>"
        }
        list_con.innerHTML=allSong;
        list_con.style.height=lyric.length*30+"px";
        for(var listIndex=0;listIndex<list_item.length;listIndex++)
            {
                list_item[listIndex].index=listIndex;
                list_item[listIndex].onclick=function(ev)
                {
                    var ev=ev||window.event;
                    ev.stopPropagation();
                    songIndex=this.index;
                    change_music();
                }
            }
        list_con.style.display="none";
        list.onclick=function()
        {
            if(list_con.style.display=="none")
            {
                list_con.style.display="block";
            }
            else{
                list_con.style.display="none";
            }
        }
        //下一首
        next_btn.onclick=function(){
            songIndex++;
            change_music();
        }
        prev_btn.onclick=function(){
            songIndex--;
            change_music();
        }
        function change_music()
        {
            clearInterval(obj.timer);
            if(songIndex>=lyric.length)
                {songIndex=0}
            else if(songIndex<0)
                {songIndex=lyric.length}
            obj= new config();      
            iconinit();
            audioInit();
            playedTime();
            lyric_ctrl();
        }
        //初始化總時長、音量等
        function audioInit()
        {
            time.innerHTML=format(audio.duration);
            audio.volume=0.5;
            play_btn.innerHTML=obj.play_btn;
            vol_cube.style.left=audio.volume*vol_bar.offsetWidth+"px";
            lyric_tit.innerText=lyric[songIndex].name;
            photo_pic.style.background="url("+lyric[songIndex].img+")";
            audio.src=lyric[songIndex].audio_src;           
            progress_cube.style.left=0;
        }
        audioInit();
        //播放時間
        audio.addEventListener("timeupdate",function()
        {
            playedTime();
        })
        function playedTime(){
            if(audio.currentTime==audio.duration)
            {
                next_btn.onclick();
                play_btn.onclick();
            }
            var n=audio.currentTime/audio.duration;
            progress_cube.style.left=n*progress_bar.offsetWidth+"px";
            initTime.innerHTML=format(audio.currentTime);
            var id_num=parseInt(audio.currentTime);
            var lyric_p=document.getElementsByTagName("p");
            for(var i=0;i<lyric_p.length;i++)
                {
                    lyric_p[i].index=i;
                }
            if(document.getElementById("lyric"+id_num))
            {               
                var obj=document.getElementById("lyric"+id_num);
                for(var i=0;i<obj.index;i++)
                {
                    lyric_p[i].className="played";
                }
                for(var j=obj.index;j<lyric_p.length;j++)
                {
                    lyric_p[j].className="";
                }
                obj.className="yellow active";                
                lyric_txt.style.top=lyric_con.offsetHeight/2-obj.offsetTop+"px";          
            }
        }
        function format(time)
        {
            var time=parseInt(time);
            var m=parseInt(time/60);
            var s=parseInt(time%60);
            m=zero(m);
            s=zero(s);
            function zero(num)
            {
                if(num<10)
                {
                    num="0"+num;
                }
                return num;
            }
            return m+":"+s;
        }
        //拖拽進度條
        progress_cube.onmousedown=function(ev)
        {
            var ev=ev||window.event;
            var initX=ev.clientX-this.offsetLeft;
            this.onmousemove=function(ev)
            {
                var ev=ev||window.event;
                var x=ev.clientX-initX;
                if(x<0){x=0}
                    if(x>progress_bar.offsetWidth-14){x=progress_bar.offsetWidth-14}
                play_ctrl(x);
            }
            document.onmouseup=function()
            {
                document.onmousemove=null;
                progress_cube.onmousemove=null;
            }
        }
        function play_ctrl(x){
                var timego=x/progress_bar.offsetWidth*audio.duration;
                progress_cube.style.left=x+"px";
                audio.currentTime=timego;
                playedTime();
        }
        //點選進度條位置
        progress_bar.onclick=function(ev)
        {
            var ev=ev||window.event;
            var dis=ev.clientX-(container.offsetLeft+progress_bar.offsetLeft)-7;
            progress_cube.style.left=dis+"px";
            play_ctrl(dis);
        }/**/
        //拖動音量鍵
        vol_cube.onmousedown=function(ev)
        {
            var ev=ev||window.event;
            var initX=ev.clientX-vol_cube.offsetLeft;
            this.onmousemove=function(ev)
            {
                var ev=ev||window.event;
                var x=ev.clientX-initX;
                if(x<0){x=0}
                    if(x>vol_bar.offsetWidth-11){x=vol_bar.offsetWidth-11}
                var volresult=x/vol_bar.offsetWidth;
                this.style.left=x+"px";
                audio.volume=volresult;
            }
            document.onmouseup=function()
            {
                document.onmousemove=null;
                vol_cube.onmousemove=null;
            }
        }       
        //點選播放
        play_btn.onclick=function()
        {
            clearInterval(obj.timer);
            if(obj.play_mark)
            {
                this.innerHTML=obj.endplay_btn;
                audio.play();
                obj.timer=setInterval(function()
                {   obj.rotateSum=obj.rotateSum+1;
                    photo_pic.style.transform="rotate("+obj.rotateSum+"deg)";
                },30)
            }
            else{
                this.innerHTML=obj.play_btn;
                audio.pause();
            }
            obj.play_mark=!obj.play_mark;
        }
        //歌詞處理
        function lyric_ctrl()
        {
            var lyricObj=lyric[songIndex].content;
            var temp=lyricObj.split("[");
            var html="";
            for(var i=0;i<temp.length;i++)
            {
                var arr=temp[i].split("]");
                var text=(arr[1]);
                var time=arr[0].split(",");
                var temp2=time[0].split(".");
                var ms=temp2[1];//毫秒
                var temp3=temp2[0].split(":");            
                var s=temp3[1];//秒
                var m=temp3[0];//分
                var s_sum=parseInt(m*60)+parseInt(s);
                if(text)
                {
                    html+="<p id='lyric"+s_sum+"'>"+text+"</p>";
                }   
            }
            lyric_txt.innerHTML=html;
        }
        lyric_ctrl();
        function iconinit(){
            icon1.className="icon";
            icon1.innerHTML=obj.icon1;
            icon1.style.color="#fff";
            icon2.className="icon";
            icon2.style.color="#fff";
        }
        //喜歡 收藏
        icon2.onclick=function()
        {
            if(this.innerHTML==obj.icon2)
            {
                this.innerHTML=obj.endicon2;
                this.style.color="yellow";
                this.className="icon yellow";
            }
            else{ 
                this.innerHTML=obj.icon2;
                this.style.color="#fff";  
                this.className="icon";            
            }
        }
        icon1.onclick=function()
        {
            if(this.style.color==obj.icon1_co)
            {
                this.innerHTML=obj.endicon1;
                this.style.color="#f7759f";
                this.className="icon pink";
            }
            else{ 
                this.innerHTML=obj.icon1;
                this.style.color=obj.icon1_co;  
                this.className="icon";            
            }
        }
    }
</script>
複製程式碼

相關文章