当前位置:   article > 正文

HTML5+JavaScript+CSS实现音乐播放器——难点二:自己设计一个控制音乐播放的控制器_javascript音乐播放器原理

javascript音乐播放器原理

       我们都知道HTML5给我们提供了"controls"这个插件,可是这个插件却比较丑,还不能实现上一首下一首的播放,以及进度条的手动改变等功能,那么如何自己设计一个控制音乐播放的控制器呢?下图是我设计的控制器。

1.获取总时间以及当前播放时间的实现:

  1. var oTotal=document.getElementsByClassName("total_time")[0];
  2. window.οnlοad=function () {
  3. oAudio.addEventListener("canplay", function() {
  4. oTotal.innerHTML=format(oAudio.duration); //获取总时间
  5. });
  6. }

        这里添加监听器的目的是解决获取到的总时间显示为NaN:NaN,其中还用到一个format函数,因为通过oAudio.duration获得的是以秒为单位的数据,所以要将其转化成分:秒的格式需要一个格式转换函数:

  1. //时间的格式化
  2. function format(t) {
  3. var m=Math.floor(t/60);
  4. var s=Math.floor(t%60);
  5. if(m<=9) //小于10时,在前面填0
  6. m="0"+m;
  7. if(s<=9)
  8. s="0"+s;
  9. return m+":"+s;
  10. }

2.播放、暂停上一首下一首的设置:

此功能的实现比较简单,在JS中只需通过onClick点击事件给audio的src赋值。

HTML代码:

  1. <audio src="" id="audio"></audio>
  2. <div class="foot">
  3. <i class="iconfont icon-kuaitui" title="上一首"></i>
  4. <span class="play"><i class="iconfont icon-zanting" title="播放"></i></span>
  5. <i class="iconfont icon-kuaijin" title="下一首"></i>
  6. <div class="progress">
  7. <span class="current_time">00:00</span>
  8. <div class="progress_range"><div class="range"></div><div class="circle"></div></div>
  9. <span class="total_time">00:00</span>
  10. </div>
  11. <div class="model">
  12. <div class="volume"><span class="iconfont icon-shengyin" title="静音"></span></div>
  13. <div class="volume_range"><div class="range"></div><div class="circle"></div></div>
  14. <div class="bofangModel"><span class="iconfont icon-suiji" title="随机播放"></span></div>
  15. </div>
  16. </div>

这样在JS中需要通过onClick点击事件给audio的src赋值,下面以播放暂停按钮为例。

  1. var oAudio=document.getElementById("audio");
  2. var oPlay=document.getElementByClassName("play")[0];
  3. var clickNum=0; //用于判断是要播放还是暂停
  4. oAudio.setAttribute("src","/audioFile/1.mp3"); //给audio对象设置src属性
  5. oPlay.onclick()=function(){
  6. if(clickNum==0){
  7. oAudio.play(); //播放
  8. oPlay.innerHTML="<i class='iconfont icon-bofang' title='暂停'></i>"; //改变图标
  9. clickNum=1;
  10. }else{
  11. oAudio.pause(); //暂停
  12. oPlay.innerHTML="<i class='iconfont icon-zanting' title='播放'></i>";
  13. clickNum=0;
  14. }
  15. }

3.手动改变进度的实现:

总体思路即通过windows的ev对象获取鼠标的移动位置,判断其距本模块最左端的位置,从而设置颜色、小圆的位置以及currentTime

  1. var oProgress=document.getElementsByClassName("range")[0];
  2. var oMaxProgress=document.getElementsByClassName("progress")[0];
  3. var oProgress_circle=document.getElementsByClassName("circle")[0];
  4. var oCurrent=document.getElementsByClassName("current_time")[0];
  5. oAudio.play();
  6. setInterval(setProgress,1000); //通过定时器设置进度的自动改变
  7. //设置进度的自动移动
  8. function setProgress() {
  9. oCurrent.innerHTML=format(oAudio.currentTime); //设置当前时间的显示
  10. oProgress.style.width=(oAudio.currentTime)/(oAudio.duration)*780+"px"; //780px是总宽度
  11. oProgress_circle.style.left=oProgress.style.width;
  12. }
  13. //可以点击轨道改变进度
  14. oMaxProgress.οnmοusedοwn=function (ev) {
  15. changeProgress(ev);
  16. }
  17. //鼠标拖动小圆改变进度
  18. oProgress_circle.οnmοusedοwn=function (ev) {
  19. document.οnmοusemοve=function (ev) {
  20. changeProgress(ev);
  21. }
  22. document.onmouseup = function () { //当鼠标松开后关闭移动事件和自身事件
  23. document.onmousemove = null;
  24. document.onmouseup = null;
  25. }
  26. return false;
  27. }
  28. function changeProgress(ev){
  29. var ev=ev||event;
  30. var l = ev.clientX - 270; //获取圆距左端的距离
  31. if(l<0){
  32. l=0;
  33. }
  34. else if (l > 780) {
  35. l = 780;
  36. }
  37. oProgress_circle.style.left=l+"px";
  38. oProgress.style.width=l+"px";
  39. oAudio.currentTime=(l/780)*oAudio.duration; //设置当前时间,以改变真正的播放进度
  40. oCurrent.innerHTML=format(oAudio.currentTime); //当前时间
  41. }

4.播放模式的切换:

播放模式有三种:随机播放、单曲循环、列表循环。

(1)随机播放的实现需要用到随机数生成函数,将生成的随机数作为歌曲的一个下标,获取响应的歌曲信息,从而播放。

(2)单曲循环的实现比较简单,只需要将audio对象的loop属性设置成true即可。

(3)列表循环的实现只需要触发下一首的点击事件即可。

在做时发现歌曲播放完毕并不会自动切换到下一首,需要对audio的"ended"属性添加监听事件。

  1. var oBofangModel=document.getElementsByClassName("bofangModel")[0];
  2. var clickNum3=0;
  3. //刚加载,clickNum3=0,不触发点击事件,默认初始为随机播放
  4. if(clickNum3==0){
  5. oAudio.loop=false;
  6. oAudio.addEventListener("ended", suiji, false); //监听函数不能加括号
  7. }
  8. //播放模式的切换
  9. oBofangModel.οnclick=function () {
  10. if(clickNum3==0){
  11. oBofangModel.innerHTML="<span class='iconfont icon-liebiaoxunhuan' title='列表循环'></span>";
  12. clickNum3=1;
  13. oAudio.loop=false;
  14. // oAudio.removeEventListener("ended",function () {..},false); //匿名取消事件无效
  15. oAudio.removeEventListener("ended",suiji,false);
  16. oAudio.addEventListener("ended", liebiao, false);
  17. }
  18. else if(clickNum3==1){
  19. oBofangModel.innerHTML="<span class='iconfont icon-danquxunhuan1' title='单曲循环'></span>";
  20. clickNum3=2;
  21. oAudio.loop=true;
  22. }
  23. else if(clickNum3==2){
  24. oBofangModel.innerHTML="<span class='iconfont icon-suiji' title='随机播放'></span>";
  25. clickNum3=0;
  26. if(oAudio!=null){
  27. oAudio.loop=false;
  28. oAudio.removeEventListener("ended",liebiao,false);
  29. oAudio.addEventListener("ended", suiji, false);
  30. }
  31. }
  32. }
  33. //列表循环,触发下一首的点击事件
  34. function liebiao(){
  35. oNext.onclick();
  36. }
  37. //产生随机数,自动播放
  38. function suiji() {
  39. var m=Math.floor(Math.random()*oMusic.length);//产生随机数,范围为0到oMusic.length-1,
  40. playSong(m);
  41. }
  42. //播放当前歌曲
  43. function playSong(index) {
  44. localStorage.setItem("index",index); //存储到本地,方便存取
  45. setInfo();
  46. oAudio.play();
  47. setInterval(setProgress,1000);
  48. }
  49. //设置列表信息
  50. function setInfo() {
  51. var m=parseInt(localStorage.getItem("index"));
  52. oAudio.setAttribute("src",oMusic[m].src);
  53. }


声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/盐析白兔/article/detail/247645
推荐阅读
相关标签
  

闽ICP备14008679号