zoukankan      html  css  js  c++  java
  • 音乐播放器

    上次只做了音乐播放界面,现在实现下功能。

    主要功能:

           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;
                //通过换行符来分割出所有的文本
    
                var arrays=content.split("
    ");
                //过滤掉前几个不带时间的数据
                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

  • 相关阅读:
    JavaScript之事件委托
    js中的事件委托(事件代理)详解
    CentOS已经安装命令,但提示找不到
    在Linux下创建7种类型的文件
    python源码安装的包的卸载
    新建文件所属组设置
    FFmpeg基础
    微服务架构概念
    一台 Java 服务器可以跑多少个线程?
    「学习的真正作用」​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​写出我心(一百三十八)
  • 原文地址:https://www.cnblogs.com/sin0/p/7822612.html
Copyright © 2011-2022 走看看