1. 程式人生 > >一個小小的移動web版音樂播放器

一個小小的移動web版音樂播放器

這個小東西是在去年八月份就完成的啦,但是由於自己一拖再拖沒有來更新部落格,直到今天心血來潮想來更新下部落格。
今天就來記錄下自己做完這個小小的迷你小專案—music-player。
哈哈,由於自己藝術細胞有限,再加上是個簡潔控,自己粗略設計了一下,所以我的ui介面長這樣—

播放器介面

介面分割:至上而下是歌名-歌手-音樂封面-播放時間-播放進度條-控制按鈕

功能上實現:顯示歌曲總時間,顯示歌曲已播放時間,顯示歌曲進度,拉拽歌曲進度,上一曲,暫停,播放,下一曲

未實現功能:歌曲列表展示,迴圈播放等等

html整體架構

    <section class="main">
        <section
class="info">
<h1></h1> <h5></h5> </section> <section class="cd-ani"> <img src="images/singer.png" alt=""/> </section> <section class="progress"> <div class="pro-time clearfix"
>
<span id="had-time" class="fl">0:00</span> <span id="all-time" class="fr">0:00</span> </div> <div class="total"> <div class="had-play"><div class="bar" id="drag"></div></div>
</div> </section> <section class="audio"> <audio controls="controls" id="music" src=""></audio> </section> <section class="operate clearfix"> <div id="last"><img src="images/last.png" alt=""/></div> <div id="start"><img src="images/start.png" alt=""/></div> <div id="next"><img src="images/next.png" alt=""/></div> </section> </section>

樣式和圖片什麼的就不再詳細多說,因為就是那些一般常用的東西。。。哈哈哈
歌曲資訊是我之前從網易雲音樂上面拿下來的一大串json資料,現在被我儲存在本地裡,防止網易雲那邊有什麼變動之類的,對於跨域那些也沒有多大問題。
把json資料都拿下來之後,就開始動工處理這些密密麻麻的資料啦~~興奮。

js開始go~
首先我定義了一個物件(名稱空間)以防變數汙染 var music = {}

處理json

        ajax:function(){
                $.ajax({
                    cache:false,
                    dataType:'json',
                    type:'post',
                    url:'../Common/json/musicJson.php',
                    data:{},
                    success:function(obj){
                        var dataArr = obj.result.tracks,
                            musicUrl = dataArr[curSong].mp3Url,
                            musicName = dataArr[curSong].name,
                            singer = dataArr[curSong].artists[0].name;
                        $('#music').attr('src',musicUrl);
                        $('.info h1').html(musicName);
                        $('.info h5').html(singer);
                    },
                    error:function(){
                        console.log('error')
                    }
                });
            }

英文命名很明顯啦,就先把歌名,歌手,音樂連結都放上頁面。(取第一首,即curSong=0)
由於音訊不止一首,所以不要忘記很重要的一句程式碼:

var audio = $('#music').get(0)

播放音樂

    start:function(){
                audio.play();
                $('.cd-ani img').addClass('rotate');
            }

暫停音樂

    pause:function(){
                audio.pause();
                $('.cd-ani img').removeClass('rotate');
            }

其中$('.cd-ani img').removeClass('rotate')是音樂封面旋轉動畫效果

播放下一首

    next:function(){
                curSong ++;
                this.ajax();
            }

時間顯示

    time : function(){
                var allTime = audio.duration,
                    hadTime = audio.currentTime;
                $('#had-time').html(cutTime(hadTime / 60) + ":" + cutTime(hadTime % 60));
                $('#all-time').html(cutTime(allTime / 60) + ":" + cutTime(allTime % 60));
            }

處理時間顯示格式

超過60的時候往進一位數。

    function cutTime(time){
        var value = (time > 10 ? time + '' : '0' + time).substring(0, 2);
        return isNaN(value) ? '00' : value;
    }

進度條顯示

獲取音訊的duration屬性之後進行計算,將結果轉化為進度條的長度(樣式)

    function progress(){
        var cuT = audio.currentTime,
            toT = audio.duration,
            progress = (cuT/toT).toFixed(2)*375;
        $('.had-play').width(progress);
    }

拉拽進度條
最棘手的來了….對進度條的操作,手動拉拽進度條的部分

     function addListenTouch() {
        //var speed = $('.had-play');
        var drag = document.getElementById("drag");
        document.getElementById("drag").addEventListener("touchstart", touchStart, false);
        document.getElementById("drag").addEventListener("touchmove", touchMove, false);
        document.getElementById("drag").addEventListener("touchend", touchEnd, false);
    }
    function touchStart(e) {
        e.preventDefault();
        var touch = e.touches[0];
        startX = touch.pageX;
    }
    function touchMove(e) { //滑動
        e.preventDefault();
        var touch = e.touches[0];
        x = touch.pageX - startX; //滑動的距離
        //drag.style.webkitTransform = 'translate(' + 0+ 'px, ' + y + 'px)';
        var widthBar = aboveX + x;
        if(widthBar<320){
            drag.style.left = widthBar + "px";
            $('.had-play').width(widthBar);
        }//不讓進度條超出頁面
    }
    function touchEnd(e) { //手指離開螢幕
        e.preventDefault();
        aboveX = parseInt(drag.style.left);
        var touch = e.touches[0];
        var dragPaddingLeft = drag.style.left;
        var change = dragPaddingLeft.replace("px", "");
        numDragpaddingLeft = parseInt(change);
        var currentTime = (numDragpaddingLeft / (window.innerWidth - 30)) * audio.duration;//30是拖動圓圈的長度,減掉是為了讓歌曲結束的時候不會跑到window以外
        audio.currentTime = currentTime;
        console.log(currentTime);
        music.time();
    }

當我們手指在手機螢幕上滑動進度條的時候,可以分割成三個事件,分別是touchstart,touchmove,touchend,手指剛觸碰到螢幕時候觸法touchstart事件,呼叫函式touchstart()來記錄此時手指距離進度條最左邊的距離;滑動過程中出發touchmove事件,呼叫touchmove()函式,計算滑動距離,並且限制進度條拉伸超過最大範圍;手指滑動停止時候觸法touchend事件,呼叫touchend()函式計算最終長度並更改顯示歌曲播放時間。

初始化

    music.ajax();
    addListenTouch();
    audio.onloadedmetadata=function(){ music.time();}

總結

這次自己的小嚐試,認識關於html5中audio元素的很多知識點,包括對audio元素的dom操作,和相關屬性、方法的運用。過程中也出現很多問題,比如初始化時直接呼叫music.time() 會出錯,上網查閱相關資料後才知道要audio.onloadedmetadata=function(){ music.time();} 這樣呼叫才不會出錯。並且,一開始那個進度條拉拽的對於自己來說其實是最難的,因為有時候使勁拉的話,進度條會空出一截,即斷層了,這是個大大的bug,到現在還沒有解決哈哈哈,現在還在思索中,有看出什麼解決這個bug方法或者發現文中我的程式碼有誤的歡迎前來指正哈哈~~~