• 简单的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) + '
    ';
     51         });
     52 
     53         tmpArr = txt.split('
    ');
     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
  • 相关阅读:
    基于Redis的短链接设计思路
    再谈对协变和逆变的理解(Updated)
    Java基础—ClassLoader的理解
    遇到个小问题,Java泛型真的是鸡肋吗?
    一次失败升级后的反思
    JVM是如何分配和回收内存?有实例!
    一个Java对象到底占用多大内存?
    《深入理解Java虚拟机》读书笔记:垃圾收集器与内存分配策略
    快速掌握RabbitMQ(二)——四种Exchange介绍及代码演示
    快速掌握RabbitMQ(一)——RabbitMQ的基本概念、安装和C#驱动
  • 原文地址:https://www.cnblogs.com/undefined000/p/5118673.html
Copyright © 2020-2023  润新知