完整打造一个多功能音乐播放器项目(初步设想跟酷狗类似)

本人目前准备利用闲暇时间打造一个完整的音乐播放器项目,主要用于学习及分享!原创不易,转载请注明出处。

这是一个什么样的音乐播放器呢?整体的架构跟酷狗差不多吧,我的方式呢,是一个个组件一个个模块先做好,最后组合成完整的项目,最后项目会放在本人的github上,等项目完毕后会发布链接。

模块①、歌词同步:(为了方便测试,先用了h5集成好的audio标签,我们只做歌词功能),初步效果是这样:(另外直接在酷狗下载歌词文件就可以用了)

       这个其实不难,不过呢,咱用点最笨的办法(关于解析字符串,不用正则匹配),酷狗都用过吧,里面的歌词文件是.krc文件,这种文件是加密过的,所以呢,从酷狗下载下来的歌词文件需要先转化成lrc文件,推荐下面的软件:

krc文件点开是这样的:

转化成lrc文件后是这样的:

扫描二维码关注公众号,回复: 973618 查看本文章

注意这时候lrc文件的字符编码不是utf-8,各位需要自行另存为utf-8文件,好了,歌词文件准备好了,可以开始我们的歌词模块了。

css及js文件我全部放在html里,完善后会逐步封装,css会采用less代替。

  1 <!DOCTYPE html>
  2 <html lang="en">
  3 <head>
  4     <meta charset="UTF-8">
  5     <title>基于js的更高级常用函数封装</title>
  6     <script src="../js/jquery-3.3.1.min.js" type="text/javascript"></script>
  7     <script src="../js/mine/dc-handle-function.js" type="text/javascript"></script>
  8     <style>
  9         .preload{
 10             width:200px;
 11             height:100px;
 12             position:absolute;
 13             top:35%;
 14             left:40%;
 15         }
 16         .preload img{
 17             width:100%;
 18             height:100%;
 19         }
 20         .lyric{
 21             width:400px;
 22             height:500px;
 23             margin:0 auto;
 24             display:none;
 25             overflow-y:auto;
 26             overflow-x:hidden;
 27             font:18px "华文楷体";
 28             color:black;
 29             text-align: center;
 30             box-shadow:-2px 2px 15px #fff;
 31             background:rgba(0,255,255,0.3);
 32         }
 33         .music{
 34             width:400px;
 35             margin:0 auto;
 36         }
 37         .music audio{
 38             width:100%;
 39         }
 40         body{
 41             overflow:scroll;
 42             background:url("../resource/bg.jpg") fixed no-repeat;background-size:cover;
 43         }
 44     </style>
 45     <script>
 46         $(function(){
 47             dorseyHf.dc_ajax_g('../resource/av/ChiQingZhong1.lrc?t='+new Date().getTime(),
 48                     function(str){
 49                         //这个函数以后也是会封装的。
 50                         var str1=str.split("[");
 51                         var str2=[];
 52                         var lyric=$(".lyric");
 53                         for(var i=1;i<str1.length;i++){
 54                             str2[i-1]=str1[i].split("]");
 55                         }
 56                         for(let i=0;i<str2.length;i++){
 57                             if(lyric.children('p').length==0){
 58                                 lyric.append('<p></p>');
 59                             }
 60                             lyric.children('p').eq(i).html(str2[i][1]);
 61                             lyric.append('<p></p>');
 62                         }
 63                         lyric.css("display","block");
 64                         //str3: "00:00.09",即获取到歌词的前半部分[时间];
 65                         var str3=[],str4=[],str5=[];
 66                         for(var i=2;i<str2.length;i++){
 67                             str3[i-2]=str2[i][0];
 68                         }
 69                         //str4:  str4[i][0]="00";str4[i][1]="00.09"
 70                         //str5:计算str4转化后min:sec的值,单位(s),用于后续与当前时间比较。
 71                         for(var i=0;i<str3.length;i++){
 72                             str4[i]=str3[i].split(":");
 73                             str5[i]=(parseFloat(str4[i][0])*60)+parseFloat(str4[i][1]);
 74                             console.log("p"+i+":"+lyric.children('p').eq(i+2).offset().top);
 75                         }
 76                         $('audio').on("timeupdate",function(){
 77                             var scale=this.currentTime;
 78                             var k=[];
 79                                 for(var i=0;i<str5.length;i++){
 80                                     if(scale>=str5[i]){
 81                                         lyric.children('p').eq(i+2).css("color","red").siblings().css("color","");
 82                                         lyric.children('p').eq(i+2).css("transform","scale(1.4)").siblings().css("transform","");
 83                                         k[i]=i;
 84 //                                      lyric.scrollTop(lyric.children('p').eq(i).offset().top);
 85                                     }
 86                                 }
 87                             var music=k.length;
 88                             console.log(music+": "+lyric.children('p').eq(music).offset().top);
 89                         });
 90             },$('img'));
 91         })
 92     </script>
 93 </head>
 94 <body>
 95 <div class="music">
 96     <audio src="../resource/av/ChiQingZhong.mp3" controls="controls"></audio>
 97 </div>
 98 <div class="preload">
 99     <img src="../resource/preload.gif" alt="">
100 </div>
101 <div class="lyric">
102 </div>
103 </body>
104 </html>

 这里引用了一些封装函数,需引入这个文件,jq的压缩版自行百度:

 1 ;(function(win){ //前面这分号别去掉哦,防止多个js文件合并压缩时因上一个js文件末尾少";"而带来的问题。
 2 
 3     "use strict"; //严格模式,一般写自己类库的时候最好加上,减少一些代码不规范引起的错误。
 4 
 5     /*模块说明:dorseyHf作为一切处理函数的入口*/
 6     let dorseyHf=function(){
 7         return new dorseyHf.fn.init();
 8     };
 9     dorseyHf.fn=dorseyHf.prototype={
10         constructor:dorseyHf, //接口名:是dorsey-handle-function的缩写。意为函数处理
11         init:function(){
12             return this;
13         },
14         math:{//数学相关处理函数,注意需要通过接口dorseyHf来调用,如dorseyHf.math.random(100,200);
15             random:function(min,max){//生成一个指定范围大小的随机数,默认值小数点后15位
16                 return Math.random()*(max-min)+min;
17             },
18             randomAccuracy:function(min,max,dec){ //生成一个可以任意指定精度的随机数
19                 return Math.round((Math.random()*(max-min)+min)*Math.pow(10,dec))/Math.pow(10,dec);
20             }
21         },
22         dc_ajax_g:function(url,fnSucceed,preObj,fnFail){//ajax获取操作
23             /**
24              * url:可以是后台接口,json数据,也可以是json文件位置
25              * fnSucceed:ajax获取成功后的操作
26              * preObj:预加载,ajax由于要与后台服务器做交互,这需要时间,特别是前后交互数据较大时,用于提醒用户
27              *         现在在做加载,请稍后...一般是一个gif,或者干脆一个请稍后都行,注意的是基于JQuery的$(select)对象。
28              * fnFail:ajax获取失败后返回的操作,一般类似于404这样的东西。
29              * */
30             preObj.css("display","block");
31             setTimeout(function(){
32                 var oAjax = new XMLHttpRequest();
33                 oAjax.open('GET',url,true);
34                 oAjax.send();
35                 oAjax.onreadystatechange=function(){
36                     if(oAjax.readyState==4){
37                         if(oAjax.status==200){
38                             fnSucceed(oAjax.responseText);//获取文本或者json数据
39                             preObj.css("display","none");
40                         }
41                         else{
42                             if(fnFail){
43                                 fnFail(oAjax.status);
44                             }
45                         }
46                     }
47                 };
48             },1500);//这个延迟最好改为0,或者干脆把setTimeout去掉,这样加的原因是方便那些ajax获取过快的
49             // 用户可以查看到这个预加载的效果。
50         }
51     };
52     dorseyHf=dorseyHf.fn.init.fn=dorseyHf.fn;
53     win.dorseyHf=dorseyHf;
54 })(window);

后续每个模块写好了会逐步更新,等项目最终完毕了会挂载到github,各位到时可自行下载。

猜你喜欢

转载自www.cnblogs.com/dorseych/p/9070092.html
今日推荐