设为首页收藏本站

Scripts 学盟

 找回密码
 加入学盟

QQ登录

只需一步,快速开始

查看: 6496|回复: 8

[JavaScript]网页中音乐LRC歌词同步显示 [复制链接]

管理员

超级大菜鸟

Rank: 9Rank: 9Rank: 9

Alvin 实名认证  发表于 2011-4-13 23:26:05 |显示全部楼层
lrc.jpg
  1. function LRCPlayer(wmp, strLRC, container, width, height, color1, color2) {
  2.         this.wmp = wmp;
  3.         this.height = height;
  4.        
  5.         this.checkInterval = 0;
  6.         this.transInterVal = 0;
  7.         this.currentFocus  = -1;
  8.        
  9.         var ls = this.ls = this.parseLRC(strLRC);
  10.         var div = document.createElement('div');
  11.         div.style.cssText = "display:block;width:"+width+"px; height:" + height + "px; overflow:hidden; background:#000;";
  12.         var lrcPanel = this.lrcPanel = document.createElement('div');
  13.         div.appendChild(lrcPanel);
  14.         container.appendChild(div);
  15.         this.colorTrans = this.colorCal(color1, color2);
  16.         this.color1 = color1;
  17.         var span = document.createElement('div');
  18.         span.style.cssText = "height:" + (height/2) + "px;";
  19.         lrcPanel.appendChild(span);
  20.         for (var i=0; i<ls.length; i++) {
  21.                 span = document.createElement('div');
  22.                 span.style.cssText = 'font-size:12px; height:16px; line-height:16px; text-align:center; overflow: hidden; white-space: nowrap; color:#' + color1;
  23.                 span.appendChild(document.createTextNode(ls[i].text));
  24.                 lrcPanel.appendChild(span);
  25.         }
  26.         span = document.createElement('div');
  27.         span.style.cssText = "height:" + (height/2) + "px;";
  28.         lrcPanel.appendChild(span);
  29.         this.start();
  30. }

  31. $.extend(LRCPlayer.prototype, {
  32.         start: function() {
  33.                 var me = this;
  34.                 !function() {
  35.                         setTimeout(arguments.callee, 128);
  36.                         me.checkPos();
  37.                 }();
  38.         }
  39.         , stop: function() {
  40.                 if (this.checkInterval)
  41.                         clearTimeout(this.checkInterval);
  42.         }
  43.         , checkPos: function() {
  44.                 try {
  45.                         var cPos = this.wmp.controls.currentPosition;
  46.                         if (isNaN(cPos)) return;
  47.                         if (this.currentFocus<this.ls.length-1 && cPos > this.ls[this.currentFocus+1].pos) {
  48.                                 this.focusThis(this.currentFocus+1);
  49.                         } else if (this.currentFocus>-1 && cPos<this.ls[this.currentFocus].pos) {
  50.                                 this.focusThis(this.currentFocus-1);
  51.                         }
  52.                         if (this.currentFocus >= this.ls.length-1) return;
  53.                         var pos = this.ls[this.currentFocus].pos;
  54.                         var nPos = this.ls[this.currentFocus+1].pos;
  55.                         var lrct = (cPos - pos)/(nPos - pos);
  56.                         lrct = Math.max(Math.min(lrct, 1), 0);
  57.                         this.lrcPanel.parentNode.scrollTop = (this.currentFocus+lrct) * 16;
  58.                 } catch(e) { }
  59.         }
  60.         , focusThis: function(index) {
  61.                 if (this.transInterVal) {
  62.                         clearTimeout(this.transInterVal);
  63.                 }
  64.                 if (this.currentFocus > -1) {
  65.                         this.lrcPanel.childNodes[this.currentFocus+1].style.color = '#'+this.color1;
  66.                 }
  67.                 this.currentFocus = index;
  68.                 var me = this;
  69.                 var i = 0;
  70.                 !function() {
  71.                         if (i>=8) return;
  72.                         me.lrcPanel.childNodes[me.currentFocus+1].style.color = '#' + me.colorTrans[i++];
  73.                         me.transInterVal = setTimeout(arguments.callee, 128);
  74.                 }();
  75.         }

  76.         , colorCal: function(c1, c2) {
  77.                 var oC2 = c2;
  78.                 c1 = parseInt(c1, 16); c2 = parseInt(c2, 16);
  79.                 var r1 = c1 >> 16, g1 = (c1 >> 8) & 0xff; b1 = c1 & 0xff;
  80.                 var r2 = c2 >> 16, g2 = (c2 >> 8) & 0xff; b2 = c2 & 0xff;
  81.                 var cs = [], d1 = r2 - r1, d2 = g2 - g1, d3 = b2 - b1, r, g, b;
  82.                 for (var i=1; i<8; i++) {
  83.                         r = r1+parseInt(Math.round(d1*i*0.125, 0));
  84.                         g = g1+parseInt(Math.round(d2*i*0.125, 0));
  85.                         b = b1+parseInt(Math.round(d3*i*0.125, 0));
  86.                         cs.push( ("00000"+((r<<16)|(g<<8)|b).toString(16)).slice(-6) );
  87.                 }
  88.                 return cs.concat(oC2);
  89.         }
  90.        
  91.         , parseLRC: function(str) {
  92.                 var map = {'ti':'标题:', 'ar':'艺术家:', 'al':'专辑:', 'by':'歌词制作:'};
  93.                 str = str.replace(/\[(ti|ar|al|by):([^[\]]*)\]/ig, function($, $1, $2) {
  94.                         return '[00:00.00]' + (map[$1.toLowerCase()]||'') + $2;
  95.                 });
  96.                 var offset = 0;
  97.                 str = str.replace(/\[offset:(-?\d+)\]/gi, function($, $1) {
  98.                         offset = parseInt($1, 10) * 0.001;
  99.                 });
  100.                 var regex1 = /(\[[^[\]]+\])(\[[^[\]]+\])([^[\]]*?)$/m;
  101.                 var regex2 = /(\[[^[\]]+\])(\[[^[\]]+\])([^[\]]*?)$/mg;
  102.                 while (regex1.test(str)) {
  103.                         str = str.replace(regex2, "$1$3\n$2$3");
  104.                 }
  105.                 var ls = [];
  106.                 str.replace(/\[(\d+):([\d.]+)\](.*)/g, function($, $1, $2, $3) {
  107.                         ls.push({ pos:parseInt($1,10)*60+parseFloat($2,10)*1+offset, text:$3 });
  108.                 });
  109.                 ls.sort(function(a, b) {
  110.                         return a.pos-b.pos;
  111.                 });
  112.                 return ls;
  113.         }
  114. });
复制代码
具体使用例子,从下面地址下载:
http://u.115.com/file/f0faa8e20

附:
ASP 版的千千静听 LRC 歌词查询 [jscript]
http://www.iscripts.org/bbs/viewthread.php?tid=86

从千千静听的歌词服务器查询音乐的 LRC 歌词
http://www.iscripts.org/bbs/viewthread.php?tid=85

Rank: 8Rank: 8

momo 发表于 2011-4-14 10:29:32 |显示全部楼层
例子下载不了昂!
过了爱做梦的年纪
轰轰烈烈不如平静

使用道具 举报

管理员

超级大菜鸟

Rank: 9Rank: 9Rank: 9

Alvin 实名认证  发表于 2011-4-14 11:02:00 |显示全部楼层
回复 2# momo

可以的吧,U蛋的服务器难道坏了

使用道具 举报

管理员

超级大菜鸟

Rank: 9Rank: 9Rank: 9

Alvin 实名认证  发表于 2011-4-14 11:06:34 |显示全部楼层
那个电信下载的按钮,能下啊,我试了

使用道具 举报

Rank: 8Rank: 8

momo 发表于 2011-4-14 11:13:50 |显示全部楼层
回复 4# Alvin


    1.jpg
事实胜于雄辩
过了爱做梦的年纪
轰轰烈烈不如平静

使用道具 举报

管理员

超级大菜鸟

Rank: 9Rank: 9Rank: 9

Alvin 实名认证  发表于 2011-4-14 11:16:21 |显示全部楼层
u 蛋不给用迅雷的

使用道具 举报

Rank: 8Rank: 8

那个谁 发表于 2011-4-15 10:44:52 |显示全部楼层

使用道具 举报

Rank: 8Rank: 8

momo 发表于 2011-4-15 11:37:29 |显示全部楼层
回复 7# 那个谁
臭杰杰
哼哼哼
过了爱做梦的年纪
轰轰烈烈不如平静

使用道具 举报

Rank: 9Rank: 9Rank: 9

浴火凤凰 发表于 2011-4-15 11:51:00 |显示全部楼层

使用道具 举报

您需要登录后才可以回帖 登录 | 加入学盟

手机版|Scripts 学盟   |

GMT+8, 2024-4-16 14:16 , Processed in 1.108699 second(s), 17 queries .

Powered by Discuz! X2

© 2001-2011 Comsenz Inc.

回顶部