简单的HTML5音乐播放器(带歌词滚动)

 

首先需要整理好lrc格式的歌词放到script标签中以供程序处理。然后把音乐链接放到audio的src属性里就可以了。

源码:

HTML部分

1 <div class="container">
2      <audio id="player" src="test.mp3" loop controls preload></audio>
3      <div id="lrcArea"></div>
4 </div>
5 
6 <script id="lrc" type="text">
7 //lrc歌词
8 </script>

 

JS部分

  1 var musicPlayer = function() {
  2     return this.init.apply(this, arguments);
  3 };
  4 
  5 musicPlayer.prototype = {
  6     constructor: musicPlayer,
  7     init: function(options) {
  8         if (isEmptyObj(options) || typeof options !== 'object') return;
  9         this.player = options.player;
 10         this.lrc = options.lrc;
 11         this.lrcArea = options.lrcArea;
 12         //用于保存歌词
 13         this.lrcArr = [];
 14         //用于保存时间戳
 15         this.timestamp = [];
 16         //处理歌词
 17         this.handleLrc(this.lrc);
 18         var that = this;
 19 
 20         this.player.addEventListener('play',
 21         function() {
 22             that.play();
 23         },
 24         false);
 25 
 26         this.player.addEventListener('pause',
 27         function() {
 28             that.pause();
 29         },
 30         false);
 31 
 32         //歌词索引
 33         this.idx = 0;
 34     },
 35     //格式化歌词
 36     handleLrc: function(lrc) {
 37         var re = /(\[.+\])(.+)?/gm,
 38         ul = cEl('ul'),
 39         frag = document.createDocumentFragment(),
 40         tmpArr,
 41         i,
 42         len;
 43         this.lrcArea.innerHTML = '';
 44         frag.appendChild(ul);
 45         ul.id = 'c';
 46         this.lrcArea.appendChild(frag);
 47 
 48         var txt = lrc.replace(re,
 49         function(a, b, c) {
 50             return b + (c === undefined ? '&nbsp;': c) + '\n';
 51         });
 52 
 53         tmpArr = txt.split('\n');
 54 
 55         //处理歌词
 56         for (i = 0, len = tmpArr.length; i < len; i++) {
 57             var item = trim(tmpArr[i]);
 58             if (item.length > 0) {
 59                 this.lrcArr.push(item);
 60             }
 61         }
 62 
 63         frag = document.createDocumentFragment();
 64 
 65         for (i = 0, len = this.lrcArr.length; i < len; i++) {
 66             var li = cEl('li');
 67             if (i === 0) {
 68                 li.className = 'cur';
 69             }
 70             li.innerHTML = this.lrcArr[i].replace(/\[.+\]/i, '');
 71             //处理时间
 72             this.timestamp.push(this.lrcArr[i].replace(re,
 73             function(a, b, c) {
 74                 return b;
 75             }).replace('[', '').replace(']', ''));
 76             frag.appendChild(li);
 77         }
 78 
 79         ul.appendChild(frag);
 80         this.li = $('lrcArea').getElementsByTagName('li');
 81     },
 82     //播放
 83     play: function() {
 84         this.stop = false;
 85         var that = this,
 86         player = this.player,
 87         i, len;
 88 
 89         this.t = setInterval(function() {
 90             if (that.stop) return;
 91             that.curTime = player.currentTime;
 92 
 93             for (i = 0, len = that.timestamp.length - 1; i < len; i++) {
 94                 var prevTime = that.formatTimeStamp(that.timestamp[i]),
 95                 nextTime = that.formatTimeStamp(that.timestamp[i + 1]);
 96                 //当前播放时间与前后歌词时间比较,如果位于这两者之间则转到该歌词
 97                 if (parseFloat(that.curTime) > prevTime && parseFloat(that.curTime) < nextTime) {
 98                     that.scrollToLrc(i);
 99                     return;
100                 }
101             }
102         },
103         300);
104     },
105     //暂停
106     pause: function() {
107         this.stop = true;
108         clearInterval(this.t);
109     },
110     //格式化时间
111     formatTimeStamp: function(timestamp) {
112         var re = /([0-9]+):([0-9]+)\.([0-9]+)/i,
113         seconds = timestamp.replace(re,
114         function(a, b, c, d) {
115             return Number(b * 60) + Number(c) + parseFloat('0.' + d);
116         });
117         return seconds;
118     },
119     //歌词滚动
120     scrollToLrc: function(idx) {
121         var ds = getOffset(this.li[idx]).top,
122         i,
123         len;
124         //如果歌词索引没有变动,则认为这句没有唱完,不处理
125         if (this.idx === idx) return;
126         //否则更新索引值并更新样式和位置
127         this.idx = idx;
128         for (i = 0, len = this.li.length; i < len; i++) {
129             this.li[i].className = '';
130         }
131         this.li[idx].className = 'cur';
132         this.lrcArea.scrollTop = ds - this.lrcArea.offsetHeight / 2;
133     }
134 };
135 
136 function $(id) {
137     return typeof id === 'string' ? document.getElementById(id) : id;
138 }
139 function cEl(el) {
140     return document.createElement(el);
141 }
142 function trim(str) {
143     return str.replace(/(^\s*)|(\s*$)/g, "");
144 }
145 function isEmptyObj(o) {
146     for (var p in o) return false;
147     return true;
148 }
149 function getOffset(el) {
150     var parent = el.offsetParent,
151     left = el.offsetLeft,
152     top = el.offsetTop;
153 
154     while (parent !== null) {
155         left += parent.offsetLeft;
156         top += parent.offsetTop;
157         parent = parent.offsetParent;
158     }
159 
160     return {
161         left: left,
162         top: top
163     };
164 }
165 
166 var p = new musicPlayer({
167     player: $('player'),
168     lrc: $('lrc').innerHTML,
169     lrcArea: $('lrcArea')
170 });
View Code

 

posted @ 2016-01-10 16:47  逐影  阅读(12663)  评论(4编辑  收藏  举报