很久沒發文,一直想寫點東西,整理整理這陣子的心得,很多筆記都在整理中。
最近給公司編寫的一個JS UI,用于歌詞同步,整理一下放出來,
核心腳本只負責處理lrc格式的歌詞和呈現,并提供同步功能。


外部呈現等均可以良好定制。
基本調用如下:
var lrc=new LRC({lyricTable:obj,lyricWrapper:obj,curRowClassName:'xx',lyric:'xxx',separator:'
'});
if(lrc.IsLyricValid()) lrc.DoSync(60);
DoSync(t)用于同步,參數t為當前播放進度,從播放器獲得。
IsLyricValid()返回歌詞是否合法的LRC格式。
貼出代碼,附件下載中包含2個定制示例。代碼在FF下跑不了,因為音樂播放插件跑不了~

Lrc UI
1
/**//*
2
* @author: huangxu
3
* @date: 2008-11
4
* @site: http://wsky.cnblogs.com
5
* @descript: sync display the lyric
6
* @usage:
7
* //import lrc.css
8
* var lrc=new LRC({lyricTable:obj,lyricWrapper:obj,curRowClassName:'xx',lyric:'xxx',separator:'
'});
9
* if(lrc.IsLyricValid()) lrc.DoSync(60);
10
*
11
* @note: 內部變量前綴lrc_,普通變量i,ii,index,arg..
12
*/
13
14
LRC=function()
{this.initialize.apply(this,arguments);}
15
LRC.prototype=
{
16
arrLyricTime:[],
17
arrLyric:[],//全局可用,必須執行初始化
18
initialize:function(arg)
{
19
//私有
20
this.lyricTable=arg.lyricTable;//目標歌詞table
21
this.lyricWrapper=arg.lyricWrapper;//目標歌詞容器div
22
this.curRowClassName=arg.curRowClassName;//選擇行css樣式名
23
this.separator=arg.separator;//歌詞行分隔符 如:
24
//執行初始化
25
this.arrLyricTime=[];
26
this.arrLyric=[];
27
this.initArray(arg.lyric);
28
this.arrLyricTime=this.sort(this.arrLyricTime);
29
this.setLyricTable(this.arrLyric);
30
},
31
initArray:function(lyric)
{
32
var lrc_re=new RegExp('/[[0-9:.]*/]','g');//g全局標志,獲取所有匹配結果必須
33
var lrc_arr=lyric.split(this.separator);
34
var lrc_temp=0;
35
var lrc_filter=0;//無效行過濾標記
36
for(var i=0;i<lrc_arr.length;i++)
{
37
var lrc_txt=lrc_arr[i].replace(//[[/w/W]*/]/g,'').Trim();//add to lyric text array
38
if(lrc_txt=='')
{
39
lrc_filter++;
40
continue;
41
}
42
this.arrLyric[i-lrc_filter]=lrc_txt;
43
while((lrc_result = lrc_re.exec(lrc_arr[i])) != null)
{
44
var lrc_second=this.parseSecond(lrc_result.toString().replace(//[|/]/g,''));
45
if(!isNaN(lrc_second))
46
this.arrLyricTime[lrc_temp++]=(i-lrc_filter)+'|'+lrc_second;//arrLyricTime格式為"行號|秒",如:1|50,2|60
47
}
48
}
49
},
50
/////////////////////////////////////////////////////////////////////////////////////////
51
// 公開函數
52
// IsLyricValid()判斷是否合法lrc歌詞
53
// DoSync()定位歌詞
54
/////////////////////////////////////////////////////////////////////////////////////////
55
IsLyricValid:function(arrLyricTime)
{
56
return this.arrLyricTime.length>0;
57
},
58
DoSync:function(curPosition)
{
59
var lrc_times=this.arrLyricTime;
60
for(var i=0;i<lrc_times.length;i++)
{
61
var lrc_arrPre=lrc_times[i].split('|');
62
63
if(i==0&&curPosition<lrc_arrPre[1]) break;//防止抖動
64
65
if(lrc_times[i+1]==undefined)
{
66
this.setRow(lrc_arrPre[0]);
67
break;
68
}
69
70
var lrc_arrNext=lrc_times[i+1].split('|');
71
if(curPosition>=lrc_arrPre[1]&&curPosition<lrc_arrNext[1])
{
72
this.setRow(lrc_arrPre[0]);
73
break;
74
}
75
}
76
},
77
/////////////////////////////////////////////////////////////////////////////////////////
78
//以下為內部輔助函數
79
/////////////////////////////////////////////////////////////////////////////////////////
80
parseSecond:function(time)
{
81
try
{
82
var lrc_arr=time.split(':');//time格式為時間格式 00:00
83
return parseInt(lrc_arr[0])*60+parseFloat(lrc_arr[1]);
84
}catch(ex)
{
85
return 0;
86
}
87
},
88
setLyricTable:function(arrLyric)
{
89
this.lyricWrapper.scrollTop=0;//滾動條置頂
90
91
if(this.lyricTable.rows.length>0)
{
92
this.clearTable(this.lyricTable);
93
}
94
for(var i=0;i<arrLyric.length;i++)
{
95
var lrc_tr=this.lyricTable.insertRow();
96
var lrc_cell=lrc_tr.insertCell(0);
97
lrc_cell.innerHTML=arrLyric[i];
98
}
99
},
100
clearTable:function(lyricTable)
{
101
var lrc_rowNum=lyricTable.rows.length;
102
for (var i=0;i<lrc_rowNum;i++)
{
103
lyricTable.deleteRow(i);
104
lrc_rowNum=lrc_rowNum-1;
105
i=i-1;
106
}
107
},
108
setRow:function(index)
{
109
this.setRowClass(index);
110
this.setScroll(index);
111
},
112
setRowClass:function(index)
{
113
var lrc_rows=this.lyricTable.rows;
114
for(var i=0;i<lrc_rows.length;i++)
{
115
lrc_rows[i].className='';//TODO:直接添加樣式至元素,防止外部css干擾
116
}
117
lrc_rows[index].className=this.curRowClassName;
118
},
119
setScroll:function(index)
{
120
this.lyricWrapper.scrollTop=this.lyricTable.rows[index].offsetTop-this.lyricWrapper.offsetHeight/3;
121
},
122
sort:function(arrLyricTime)
{
123
for(var i=0;i<arrLyricTime.length-1;i++)
{
124
for(var ii=i+1;ii<arrLyricTime.length;ii++)
{
125
var lrc_cur=parseFloat(arrLyricTime[i].split('|')[1]);
126
var lrc_next=parseFloat(arrLyricTime[ii].split('|')[1]);
127
if(lrc_cur>lrc_next)
{
128
var lrc_temp=arrLyricTime[i];
129
arrLyricTime[i]=arrLyricTime[ii];
130
arrLyricTime[ii]=lrc_temp;
131
}
132
}
133
}
134
return arrLyricTime;
135
}
136
}
137
138
139
/////////////////////////////////////////////////////////////
140
//外部函數
141
/////////////////////////////////////////////////////////////
142
String.prototype.Trim = function()
143

{
144
return this.replace(/^/s*|/s*$/g,"");
145
}
146
it知識庫:放一個歌詞同步的JS UI,轉載需保留來源!
鄭重聲明:本文版權歸原作者所有,轉載文章僅為傳播更多信息之目的,如作者信息標記有誤,請第一時間聯系我們修改或刪除,多謝。