Skip to content

Commit 75de24c

Browse files
authored
修复:多次实例化构造函数时,歌词的中间变量会变成最后一个,导致无法实现双语歌词
模拟触发Bug: var firstLine = new Lyrics(`[00:04.050] firstLine `); var secondLine = new Lyrics(`[00:04.050] secondLine `); 原因:构造函数的书写方式有问题。
1 parent 7a7558a commit 75de24c

File tree

2 files changed

+144
-143
lines changed

2 files changed

+144
-143
lines changed

lyrics.js

+143-142
Original file line numberDiff line numberDiff line change
@@ -1,152 +1,153 @@
11
(function(root, factory) {
2-
'use strict';
3-
if (typeof define === 'function' && define.amd) {
4-
// AMD support.
5-
define([], factory);
6-
} else if (typeof exports === 'object') {
7-
// NodeJS support.
8-
module.exports = factory();
9-
} else {
10-
// Browser global support.
11-
root.Lyrics = factory();
12-
}
2+
'use strict';
3+
if (typeof define === 'function' && define.amd) {
4+
// AMD support.
5+
define([], factory);
6+
} else if (typeof exports === 'object') {
7+
// NodeJS support.
8+
module.exports = factory();
9+
} else {
10+
// Browser global support.
11+
root.Lyrics = factory();
12+
}
1313
}(this, function() {
14-
'use strict';
15-
var Lyrics = function(text_lrc){
16-
/* Private */
17-
var _proto = Lyrics.prototype;
18-
var timestamp_offset = 0;
19-
var lyrics_all = undefined;
20-
var meta_info = undefined;
21-
var setTimestampOffset = function(offset){
22-
timestamp_offset = isNaN(offset) ? 0 : Number(offset) / 1000;
23-
return Number(offset);
24-
}
25-
var isEmpty = function(obj) {
26-
for(var prop in obj) {
27-
if(obj.hasOwnProperty(prop)) {
28-
return false;
29-
}
30-
}
31-
return true;
32-
}
33-
var ID_TAGS = [
34-
{name:'artist',id:'ar'},
35-
{name:'album',id:'al'},
36-
{name:'title',id:'ti'},
37-
{name:'author',id:'au'},
38-
{name:'length',id:'length'},
39-
{name:'by',id:'by'},
40-
{name:'offset',id:'offset', handler:setTimestampOffset},
41-
{name:'createdBy',id:'re'},
42-
{name:'createdByVersion',id:'ve'},
43-
];
14+
'use strict';
15+
var Lyrics = function (text_lrc) {
16+
/* Private */
17+
this.timestamp_offset = 0;
18+
this.lyrics_all = undefined;
19+
this.meta_info = undefined;
20+
this.ID_TAGS = [
21+
{name: 'artist', id: 'ar'},
22+
{name: 'album', id: 'al'},
23+
{name: 'title', id: 'ti'},
24+
{name: 'author', id: 'au'},
25+
{name: 'length', id: 'length'},
26+
{name: 'by', id: 'by'},
27+
{name: 'offset', id: 'offset', handler: this.setTimestampOffset},
28+
{name: 'createdBy', id: 're'},
29+
{name: 'createdByVersion', id: 've'}
30+
];
4431

45-
_proto.load = function(text_lrc){
46-
lyrics_all = new Array();
47-
meta_info = new Object();
48-
timestamp_offset = 0;
32+
/* Initialization */
33+
for (var i = 0; i < this.ID_TAGS.length; i++) {
34+
this.ID_TAGS[i].re = new RegExp('\\[' + this.ID_TAGS[i].id + ':(.*)\\]$', 'g');
35+
}
36+
if (text_lrc) {
37+
this.load(text_lrc);
38+
}
39+
};
4940

50-
var lines_all = String(text_lrc).split('\n');
51-
for (var i = 0; i < lines_all.length; i++) {
52-
var line = lines_all[i].replace(/(^\s*)|(\s*$)/g,'');
53-
if (!line) {
54-
continue;
55-
}
5641

57-
//Parse ID Tags
58-
var is_id_tag = false;
59-
for (var j = 0; j < ID_TAGS.length; j++) {
60-
var match = ID_TAGS[j].re.exec(line);
61-
if (!match || match.length < 2) {
62-
continue;
63-
}
42+
Lyrics.prototype = {
43+
constructor: Lyrics,
44+
load: function (text_lrc) {
45+
this.lyrics_all = new Array();
46+
this.meta_info = new Object();
47+
this.timestamp_offset = 0;
6448

65-
is_id_tag = true;
66-
var value = match[1].replace(/(^\s*)|(\s*$)/g,'');
67-
if (typeof ID_TAGS[j].handler == 'function') {
68-
meta_info[String(ID_TAGS[j].name)] = ID_TAGS[j].handler.call(this, value);
69-
} else {
70-
meta_info[String(ID_TAGS[j].name)] = String(value);
71-
}
72-
}
73-
if (is_id_tag) {
74-
continue;
75-
}
49+
var lines_all = String(text_lrc).split('\n');
50+
for (var i = 0; i < lines_all.length; i++) {
51+
var line = lines_all[i].replace(/(^\s*)|(\s*$)/g, '');
52+
if (!line) {
53+
continue;
54+
}
7655

77-
//Parse lyric
78-
var timestamp_all = Array();
79-
while (true) {
80-
var match = /^(\[\d+:\d+(.\d+)?\])(.*)/g.exec(line);
81-
if (match) {
82-
timestamp_all.push(match[1]);
83-
line = match[match.length-1].replace(/(^\s*)|(\s*$)/g,'');
84-
} else {
85-
break;
86-
}
87-
}
88-
for (var j = 0; j < timestamp_all.length; j++) {
89-
var ts_match = /^\[(\d{1,2}):(\d|[0-5]\d)(\.(\d+))?\]$/g.exec(timestamp_all[j]);
90-
if (ts_match) {
91-
lyrics_all.push({
92-
timestamp:Number(ts_match[1])*60 + Number(ts_match[2]) + (ts_match[4] ? Number('0.'+ts_match[4]) : 0),
93-
text:line
94-
});
95-
}
96-
}
97-
}
56+
//Parse ID Tags
57+
var is_id_tag = false;
58+
for (var j = 0; j < this.ID_TAGS.length; j++) {
59+
var match = this.ID_TAGS[j].re.exec(line);
60+
if (!match || match.length < 2) {
61+
continue;
62+
}
9863

99-
lyrics_all.sort(function(a,b){
100-
return (a.timestamp > b.timestamp ? 1 : -1);
101-
});
102-
if (!lyrics_all.length) {
103-
lyrics_all = undefined;
104-
}
105-
if (isEmpty(meta_info)) {
106-
meta_info = undefined;
107-
}
108-
return (lyrics_all !== undefined || meta_info !== undefined) ? true : false;
109-
}
64+
is_id_tag = true;
65+
var value = match[1].replace(/(^\s*)|(\s*$)/g, '');
66+
if (typeof this.ID_TAGS[j].handler == 'function') {
67+
this.meta_info[String(this.ID_TAGS[j].name)] = this.ID_TAGS[j].handler.call(this, value);
68+
} else {
69+
this.meta_info[String(this.ID_TAGS[j].name)] = String(value);
70+
}
71+
}
72+
if (is_id_tag) {
73+
continue;
74+
}
11075

111-
/* Public */
112-
_proto.getLyrics = function(){
113-
return lyrics_all;
114-
}
115-
_proto.getLyric = function(idx){
116-
try{
117-
return lyrics_all[idx];
118-
}catch(e){
119-
return undefined;
120-
}
121-
}
122-
_proto.getIDTags = function(){
123-
return meta_info;
124-
}
125-
_proto.select = function(ts){
126-
if (isNaN(ts)) {
127-
return -1;
128-
}
129-
var timestamp = Number(ts) + timestamp_offset;
130-
var i = 0;
131-
if (timestamp < lyrics_all[0].timestamp) {
132-
return -1;
133-
}
134-
for (i = 0; i < (lyrics_all.length - 1); i++) {
135-
if (lyrics_all[i].timestamp <= timestamp
136-
&& lyrics_all[i+1].timestamp > timestamp) {
137-
break;
138-
}
139-
}
140-
return i;
141-
}
76+
//Parse lyric
77+
var timestamp_all = Array();
78+
while (true) {
79+
var match = /^(\[\d+:\d+(.\d+)?\])(.*)/g.exec(line);
80+
if (match) {
81+
timestamp_all.push(match[1]);
82+
line = match[match.length - 1].replace(/(^\s*)|(\s*$)/g, '');
83+
} else {
84+
break;
85+
}
86+
}
87+
for (var j = 0; j < timestamp_all.length; j++) {
88+
var ts_match = /^\[(\d{1,2}):(\d|[0-5]\d)(\.(\d+))?\]$/g.exec(timestamp_all[j]);
89+
if (ts_match) {
90+
this.lyrics_all.push({
91+
timestamp: Number(ts_match[1]) * 60 + Number(ts_match[2]) + (ts_match[4] ? Number('0.' + ts_match[4]) : 0),
92+
text: line
93+
});
94+
}
95+
}
96+
}
14297

143-
/* Initialization */
144-
for (var i = 0; i < ID_TAGS.length; i++) {
145-
ID_TAGS[i].re = new RegExp('\\['+ID_TAGS[i].id+':(.*)\\]$', 'g');
146-
}
147-
if (text_lrc) {
148-
this.load(text_lrc);
149-
}
150-
}
151-
return Lyrics;
152-
}));
98+
this.lyrics_all.sort(function (a, b) {
99+
return (a.timestamp > b.timestamp ? 1 : -1);
100+
});
101+
if (!this.lyrics_all.length) {
102+
this.lyrics_all = undefined;
103+
}
104+
if (this.isEmpty(this.meta_info)) {
105+
this.meta_info = undefined;
106+
}
107+
return (this.lyrics_all !== undefined || this.meta_info !== undefined) ? true : false;
108+
},
109+
getLyrics: function () {
110+
return this.lyrics_all;
111+
},
112+
getLyric: function (idx) {
113+
try {
114+
return this.lyrics_all[idx];
115+
} catch (e) {
116+
return undefined;
117+
}
118+
},
119+
getIDTags: function () {
120+
return this.meta_info;
121+
},
122+
select: function (ts) {
123+
if (isNaN(ts)) {
124+
return -1;
125+
}
126+
var timestamp = Number(ts) + this.timestamp_offset;
127+
var i = 0;
128+
if (timestamp < this.lyrics_all[0].timestamp) {
129+
return -1;
130+
}
131+
for (i = 0; i < (this.lyrics_all.length - 1); i++) {
132+
if (this.lyrics_all[i].timestamp <= timestamp
133+
&& this.lyrics_all[i + 1].timestamp > timestamp) {
134+
break;
135+
}
136+
}
137+
return i;
138+
},
139+
setTimestampOffset: function (offset) {
140+
this.timestamp_offset = isNaN(offset) ? 0 : Number(offset) / 1000;
141+
return Number(offset);
142+
},
143+
isEmpty: function (obj) {
144+
for (var prop in obj) {
145+
if (obj.hasOwnProperty(prop)) {
146+
return false;
147+
}
148+
}
149+
return true;
150+
}
151+
};
152+
return Lyrics;
153+
}));

lyrics.min.js

+1-1
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)