1. 程式人生 > >音樂播放器

音樂播放器

http 還原 單位 在那 由於 全局 star style tex

上次只做了音樂播放界面,現在實現下功能。

主要功能:

1、支持循環、隨機播放

  2、在播放的同時支持圖片的旋轉

3、支持點擊進度條調整播放的位置,以及調整音量

4、顯示音樂的播放時間

5、支持切歌:上一首、下一首、點擊歌名切歌;暫停播放

6、同步歌詞。

技術分享

添加音樂有兩種方式:

①可以用一個audo標簽,這樣應該把音樂的地址存放到一個數組中;

②第二種方式是,有幾首歌就添加幾個audo標簽,然後獲取所有的背景音樂(示例中我們先添加三首音樂,放到一個數組中,當然,大家可以挑選自己喜歡的任何歌曲)。

        <
audio id="play1"> <source src="auto/旅行.mp3"></source> </audio> <audio id="play2"> <source src="auto/薛明媛,朱賀 - 非酋.mp3"></source> </audio> <audio id="play3"> <source src="auto/楊宗緯 - 越過山丘.mp3"
></source> </audio>
        play1=document.getElementById("play1");
        play2=document.getElementById("play2");
        play3=document.getElementById("play3");
        play=[play1,play2,play3];

1點擊播放、暫停

首選我們應該清楚的是,在點擊按鈕播放的時候應該實現的有:

①音樂開始播放;

②進度條開始隨歌曲的播放往前走;

③圖片開始隨歌曲播放旋轉;

④播放時間開始計時;

那麽相對應的,再次點擊播放按鈕的時候,我們就可以讓它實現暫停:

①歌曲暫停;

②讓進度條同時暫停;

③讓播放時間計時同時暫停;

④圖片停止旋轉;

註意:上述開始暫停操作一定要同步!

理清楚我們的思路以後,就可以來一 一實現了~

點擊播放/暫停
                //點擊播放、暫停
                function start(){
                    minute=0;
                    if(flag){
                        imagePause();
                        play[index].pause();
                    }else{
                        rotate();
                        play[index].play();
                        reducejindutiao();
                        addtime();
                        jindutiao();
                        for (var i=0;i<play.length;i++) {
                            audioall[i].style.color="white";
                        }
                        audioall[index].style.color="red";
                    }
                }

因為播放和暫停在同一個按鈕上,所以都會調用上述方法,我們來詳細看一下各個函數都實現了怎樣的功能:

圖片旋轉
                //圖片旋轉,每30毫米旋轉5度
                function rotate(){
                    var deg=0;
                    flag=1;
                    timer=setInterval(function(){
                        image.style.transform="rotate("+deg+"deg)";
                        deg+=5;
                        if(deg>360){
                            deg=0;
                        }
                    },30);
                }

上述是圖片轉動的函數,當音樂播放的時候調用rotate()函數,就可以實現圖片的旋轉!

同樣清除定時器的函數,當音樂暫停的時候調用imagePause(),圖片旋轉的定時器被清除掉:

         function imagePause(){
                    clearInterval(timer);
                    flag=0;
                }

這樣圖片旋轉的功能我們就已經實現了~

進度條

先定義兩個寬度長度大小一樣 顏色不同的兩個div,利用currenttime屬性來過去當前的播放的時間,

設一個div一開始的長度為零,然後通過當前播放的事件來調整div長度大小就能實現滾動條的效果了。

                function jindutiao(){
                    //獲取當前歌曲的歌長
                    var lenth=play[index].duration;
                    timer1=setInterval(function(){
                        cur=play[index].currentTime;//獲取當前的播放時間
                        fillbar.style.width=""+parseFloat(cur/lenth)*300+"px";
                    },50)
                }

這樣,進度條就完成啦~

播放時間

音樂的播放時間也是利用currenttime來隨時改變,不過應該註意currenttime的計時單位為秒。

                //播放時間
                function addtime(){
                    timer2=setInterval(function(){
                        cur=parseInt(play[index].currentTime);//秒數
                        var temp=cur;
                        minute=parseInt(temp/60);
                        if(cur%60<10){
                            time.innerHTML=""+minute+":0"+cur%60+"";
                        }else{
                            time.innerHTML=""+minute+":"+cur%60+"";
                        }
                    },1000);
                }

2切歌

我做了兩種方式實現切歌:

①點擊上一曲、下一曲按鈕實現切歌;

                //上一曲
                function reduce(){
                    qingkong();
                    reducejindutiao();
                    pauseall();
                    index--;
                    if(index==-1){
                        index=play.length-1;
                    }
                    start();
                }
                //下一曲
                function add(){
                    qingkong();
                    reducejindutiao();
                    pauseall();
                    index++;
                    if(index>play.length-1){
                        index=0;
                    }
                    start();
                }

②點擊歌名,實現歌曲的切換;

                //點擊文字切歌
                function change(e){
                    var musicName=e.target;
                    //先清空所有的
                    for (var i=0;i<audioall.length;i++) {
                        audioall[i].style.color="white";
                        if(audioall[i]==musicName){
                            musicName.style.color="red";
                            qingkong();
                            reducejindutiao();
                            pauseall();
                            index=i;
                            start();
                        }
                    }
                }

註意:在切歌時不要忘了我們的進度條!

將進度條滾動的定時器清除掉,然後div的長度還原為0;

                //將進度條置0
                function reducejindutiao(){
                    clearInterval(timer1);
                    fillbar.style.width="0";
                }

同時音樂停止:

                //音樂停止
                function pauseall(){
                    for (var i=0;i<play.length;i++) {
                        if(play[i]){
                            play[i].pause();
                        }
                    }
                }

清空所有定時器:

                function qingkong(){//清空所有的計時器
                    imagePause();
                    clearInterval(timer2);
                }

3點擊進度條調整播放進度及音量

首先應該理清一下邏輯:當點擊進度條的時候,滾動條的寬度應該跟鼠標的offsetX一樣長,然後根據進度條的長度來調整聽該顯示的時間。

(1) 給滾動條的div添加一個事件,當滾動條長度變化的時候歌曲的當前播放的時間調整,300是滾動條的總長度;

                //調整播放進度
                function adjust(e){
                    var bar=e.target;
                    var x=e.offsetX;
                    var lenth=play[index].duration;
                    fillbar.style.width=x+"px";
                    play[index].currentTime=""+parseInt(x*lenth/300)+"";
                    play[index].play();
                }

(2) 改變音量的滾動條,跟改變播放時間類似,利用volume屬性(值為零到一);

                //調整音量大小
                function changeVolume(e){
                    var x=e.offsetX+20;
                    play[index].volume=parseFloat(x/200)*1;
                    //改變按鈕的位置
                    volume3.style.left=""+x+"px";
                }

4隨機、循環播放

循環播放音樂的時候,直接index++當index的範圍超過歌曲的長度的時候,index=0重新開始。

隨機播放的函數類似,當歌曲播放完畢的時候,隨機產生一個0到play.length的數字就可以了。

                //隨機播放歌曲
                function suiji(e){
                    var img=e.target;
                    img2.style.border="";
                    img.style.border="1px solid red";
                }
                //順序播放
                function shunxu(e){
                    var img=e.target;
                    img1.style.border="";
                    img.style.border="1px solid red";
                    clearInterval(suijiplay);
                    shunxuplay=setInterval(function(){
                        if(play[index].ended){
                            add();
                        }
                    },1000);
                }
    

5顯示歌詞

直接在audio標簽中添加controls屬性,這樣我們的音樂播放器就自帶工具欄了,也就是頂部的那一塊,

雖然不是太美觀,但是麻雀雖小五臟俱全,基本功能都可以實現,當然,大家可以自己寫樣式。

技術分享

<audio controls>
    <source src="auto/趙雷 - 成都.mp3" type="audio/mpeg"/>
</audio>
<span class="wordsbtn" onclick="showWords()">詞</span>

解析歌詞

首先我們需要下載一個lyric格式的歌詞,這一步很重要,因為在同步歌詞的時候需要通過時間來判斷顯示哪一句。我們以《成都》為例,把它放到預格式標簽中~

技術分享
<pre id="song1">
[ti:成都]
[ar:趙雷]
[al:無法長大]
[by:0]
[offset:0]
[00:01.34]成都
[00:02.09]
[00:03.96]作詞:趙雷
[00:03.96]作曲:趙雷
[00:05.99]編曲:趙雷,喜子
[00:09.04]演唱:趙雷
[00:12.90]
[00:17.65]讓我掉下眼淚的
[00:21.57]不止昨夜的酒
[00:25.82]讓我依依不舍的
[00:29.62]不止你的溫柔
[00:33.78]余路還要走多久
[00:37.64]你攥著我的手
[00:41.63]讓我感到為難的
[00:45.47]是掙紮的自由
[00:49.20]
[00:51.90]分別總是在九月
[00:55.38]回憶是思念的愁
[00:59.46]深秋嫩綠的垂柳
[01:03.32]親吻著我額頭
[01:07.31]在那座陰雨的小城裏
[01:11.44]我從未忘記你
[01:15.56]成都 帶不走的 只有你
[01:21.76]
[01:22.81]和我在成都的街頭走一走
[01:31.25]直到所有的燈都熄滅了也不停留
[01:38.88]你會挽著我的衣袖
[01:42.67]我會把手揣進褲兜
[01:46.56]走到玉林路的盡頭
[01:50.45]坐在小酒館的門口
[01:55.65]
[02:30.35]分別總是在九月
[02:34.31]回憶是思念的愁
[02:38.17]深秋嫩綠的垂柳
[02:42.48]親吻著我額頭
[02:46.66]在那座陰雨的小城裏
[02:50.34]我從未忘記你
[02:53.78]成都 帶不走的 只有你
[03:00.95]
[03:02.38]和我在成都的街頭走一走
[03:10.13]直到所有的燈都熄滅了也不停留
[03:18.32]你會挽著我的衣袖
[03:21.99]我會把手揣進褲兜
[03:25.99]走到玉林路的盡頭
[03:29.79]坐在小酒館的門口
[03:36.36]
[03:38.40]和我在成都的街頭走一走
[03:46.45]直到所有的燈都熄滅了也不停留
[03:54.27]和我在成都的街頭走一走
[04:02.30]直到所有的燈都熄滅了也不停留
[04:10.29]你會挽著我的衣袖
[04:13.57]我會把手揣進褲兜
[04:17.56]走到玉林路的盡頭
[04:21.77]坐在(走過)小酒館的門口
[04:27.72]
[04:36.02]和我在成都的街頭走一走
[04:43.67]直到所有的燈都熄滅了也不停留
[04:51.93]
</pre>
技術分享

這樣所有的HTML代碼部分就已經全部完成了,接下來就是我們的JS……

首先是解析歌詞,這是首先要做的準備工作,同樣也是最重要的一步,解析步驟大體如下:

①當頁面加載完的時候,獲取到歌詞

②將歌詞通過換行符將所有歌詞放到數組中

③通過for循環,循環遍歷每一行歌詞,將歌詞前不是時間的過濾掉

④由於audio標簽的currentTime是以秒來記數,所以我們需要將歌詞時間改為秒

⑤將每行歌詞秒數與歌詞內容封裝成對象,放入數組中

 //全局的歌詞數據
        var wordsArray=[];
        window.onload=function(){
            //獲取歌詞並且截取
            var content=document.getElementById("song1").innerHTML;
            //通過換行符來分割出所有的文本\n
            var arrays=content.split("\n");
            //過濾掉前幾個不帶時間的數據
            for(var i=0;i<arrays.length;i++){
                var temp=arrays[i];
                //根據分號分割過濾數據
                var tempNum=temp.split(":")[0].replace("[","");
                //是合法歌詞的時候
                if(!isNaN(tempNum)){
                    //重新根據]來分割 ,分離數據
                    var timeArray=temp.split("]")[0].replace("[","").split(":");//33:44
                    //計算分鐘數
                    var min=parseInt(timeArray[0]);
                    //計算總秒數
                    var second=parseFloat(timeArray[1])+min*60;
                    //獲取對應的歌詞內容
                    var content=temp.split("]")[1];

                    //封裝成歌詞對象放入數組
                    var obj={
                        time:second,
                        content:content
                    };
                    wordsArray.push(obj);
                }
            }
        }

這樣,我們的準備工作就完成了~

歌詞滾動

點擊span播放按鈕的時候,觸發一個showWords函數,將顯示歌詞的div顯示到界面中。將存在數組中的對象

的時間通過與當前播放時間currentTime進行對比,當當前播放時間大於數組中對象的時間,那麽久顯示這一句的歌詞。

具體實現:

①獲取到顯示歌詞的div將div顯示

②設置一個定時器,每秒比較一次(將當前播放時間與解析出的數組中的對象時間進行比較,如果播放的秒數大於數組中的秒數,播放前一句歌詞)

        function showWords(){
            var words=document.getElementsByClassName("words")[0];
            //控制歌div顯示或者隱藏
            if(words.style.display=="none"){
                words.style.display="block";
            }else{
                words.style.display="none";
            }
            //開始獲取歌詞並且展示到歌詞框
            var play=document.getElementsByTagName("audio")[0];
            setInterval(function(){
                var str=  getWordsByTime(play.currentTime);
                document.getElementsByClassName("words")[0].innerHTML=str;
            },1000);
        }

       //根據時間獲取當前應該顯示哪一句話
        function getWordsByTime(second){

            for(var i in  wordsArray){
                var obj=wordsArray[i];
                if(second>obj.time){  //播放時候的秒數大於數組中的秒數的時候,播放的應該是前一句歌詞
                    continue;
                }else{
                    return wordsArray[i-1].content;
                }
            }
        }

這樣,同步顯示歌詞的功能就完成了啦

原博文地址:

http://www.cnblogs.com/1996zy/p/7675232.html

音樂播放器