上次只做了音乐播放界面,现在实现下功能。
主要功能:
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