🎩 You're Invited:Meet the Socket team at Black Hat in Las Vegas, August 3-6.RSVP
Sign In

lyrics.js

Package Overview
Dependencies
Maintainers
1
Versions
7
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

lyrics.js - npm Package Compare versions

Comparing version
0.3.5
to
0.4.0
+143
-142
lyrics.js
(function(root, factory) {
'use strict';
if (typeof define === 'function' && define.amd) {
// AMD support.
define([], factory);
} else if (typeof exports === 'object') {
// NodeJS support.
module.exports = factory();
} else {
// Browser global support.
root.Lyrics = factory();
}
'use strict';
if (typeof define === 'function' && define.amd) {
// AMD support.
define([], factory);
} else if (typeof exports === 'object') {
// NodeJS support.
module.exports = factory();
} else {
// Browser global support.
root.Lyrics = factory();
}
}(this, function() {
'use strict';
var Lyrics = function(text_lrc){
/* Private */
var _proto = Lyrics.prototype;
var timestamp_offset = 0;
var lyrics_all = undefined;
var meta_info = undefined;
var setTimestampOffset = function(offset){
timestamp_offset = isNaN(offset) ? 0 : Number(offset) / 1000;
return Number(offset);
}
var isEmpty = function(obj) {
for(var prop in obj) {
if(obj.hasOwnProperty(prop)) {
return false;
}
}
return true;
}
var ID_TAGS = [
{name:'artist',id:'ar'},
{name:'album',id:'al'},
{name:'title',id:'ti'},
{name:'author',id:'au'},
{name:'length',id:'length'},
{name:'by',id:'by'},
{name:'offset',id:'offset', handler:setTimestampOffset},
{name:'createdBy',id:'re'},
{name:'createdByVersion',id:'ve'},
];
'use strict';
var Lyrics = function (text_lrc) {
/* Private */
this.timestamp_offset = 0;
this.lyrics_all = undefined;
this.meta_info = undefined;
this.ID_TAGS = [
{name: 'artist', id: 'ar'},
{name: 'album', id: 'al'},
{name: 'title', id: 'ti'},
{name: 'author', id: 'au'},
{name: 'length', id: 'length'},
{name: 'by', id: 'by'},
{name: 'offset', id: 'offset', handler: this.setTimestampOffset},
{name: 'createdBy', id: 're'},
{name: 'createdByVersion', id: 've'}
];
_proto.load = function(text_lrc){
lyrics_all = new Array();
meta_info = new Object();
timestamp_offset = 0;
/* Initialization */
for (var i = 0; i < this.ID_TAGS.length; i++) {
this.ID_TAGS[i].re = new RegExp('\\[' + this.ID_TAGS[i].id + ':(.*)\\]$', 'g');
}
if (text_lrc) {
this.load(text_lrc);
}
};
var lines_all = String(text_lrc).split('\n');
for (var i = 0; i < lines_all.length; i++) {
var line = lines_all[i].replace(/(^\s*)|(\s*$)/g,'');
if (!line) {
continue;
}
//Parse ID Tags
var is_id_tag = false;
for (var j = 0; j < ID_TAGS.length; j++) {
var match = ID_TAGS[j].re.exec(line);
if (!match || match.length < 2) {
continue;
}
Lyrics.prototype = {
constructor: Lyrics,
load: function (text_lrc) {
this.lyrics_all = new Array();
this.meta_info = new Object();
this.timestamp_offset = 0;
is_id_tag = true;
var value = match[1].replace(/(^\s*)|(\s*$)/g,'');
if (typeof ID_TAGS[j].handler == 'function') {
meta_info[String(ID_TAGS[j].name)] = ID_TAGS[j].handler.call(this, value);
} else {
meta_info[String(ID_TAGS[j].name)] = String(value);
}
}
if (is_id_tag) {
continue;
}
var lines_all = String(text_lrc).split('\n');
for (var i = 0; i < lines_all.length; i++) {
var line = lines_all[i].replace(/(^\s*)|(\s*$)/g, '');
if (!line) {
continue;
}
//Parse lyric
var timestamp_all = Array();
while (true) {
var match = /^(\[\d+:\d+(.\d+)?\])(.*)/g.exec(line);
if (match) {
timestamp_all.push(match[1]);
line = match[match.length-1].replace(/(^\s*)|(\s*$)/g,'');
} else {
break;
}
}
for (var j = 0; j < timestamp_all.length; j++) {
var ts_match = /^\[(\d{1,2}):(\d|[0-5]\d)(\.(\d+))?\]$/g.exec(timestamp_all[j]);
if (ts_match) {
lyrics_all.push({
timestamp:Number(ts_match[1])*60 + Number(ts_match[2]) + (ts_match[4] ? Number('0.'+ts_match[4]) : 0),
text:line
});
}
}
}
//Parse ID Tags
var is_id_tag = false;
for (var j = 0; j < this.ID_TAGS.length; j++) {
var match = this.ID_TAGS[j].re.exec(line);
if (!match || match.length < 2) {
continue;
}
lyrics_all.sort(function(a,b){
return (a.timestamp > b.timestamp ? 1 : -1);
});
if (!lyrics_all.length) {
lyrics_all = undefined;
}
if (isEmpty(meta_info)) {
meta_info = undefined;
}
return (lyrics_all !== undefined || meta_info !== undefined) ? true : false;
}
is_id_tag = true;
var value = match[1].replace(/(^\s*)|(\s*$)/g, '');
if (typeof this.ID_TAGS[j].handler == 'function') {
this.meta_info[String(this.ID_TAGS[j].name)] = this.ID_TAGS[j].handler.call(this, value);
} else {
this.meta_info[String(this.ID_TAGS[j].name)] = String(value);
}
}
if (is_id_tag) {
continue;
}
/* Public */
_proto.getLyrics = function(){
return lyrics_all;
}
_proto.getLyric = function(idx){
try{
return lyrics_all[idx];
}catch(e){
return undefined;
}
}
_proto.getIDTags = function(){
return meta_info;
}
_proto.select = function(ts){
if (isNaN(ts)) {
return -1;
}
var timestamp = Number(ts) + timestamp_offset;
var i = 0;
if (timestamp < lyrics_all[0].timestamp) {
return -1;
}
for (i = 0; i < (lyrics_all.length - 1); i++) {
if (lyrics_all[i].timestamp <= timestamp
&& lyrics_all[i+1].timestamp > timestamp) {
break;
}
}
return i;
}
//Parse lyric
var timestamp_all = Array();
while (true) {
var match = /^(\[\d+:\d+(.\d+)?\])(.*)/g.exec(line);
if (match) {
timestamp_all.push(match[1]);
line = match[match.length - 1].replace(/(^\s*)|(\s*$)/g, '');
} else {
break;
}
}
for (var j = 0; j < timestamp_all.length; j++) {
var ts_match = /^\[(\d{1,2}):(\d|[0-5]\d)(\.(\d+))?\]$/g.exec(timestamp_all[j]);
if (ts_match) {
this.lyrics_all.push({
timestamp: Number(ts_match[1]) * 60 + Number(ts_match[2]) + (ts_match[4] ? Number('0.' + ts_match[4]) : 0),
text: line
});
}
}
}
/* Initialization */
for (var i = 0; i < ID_TAGS.length; i++) {
ID_TAGS[i].re = new RegExp('\\['+ID_TAGS[i].id+':(.*)\\]$', 'g');
}
if (text_lrc) {
this.load(text_lrc);
}
}
return Lyrics;
}));
this.lyrics_all.sort(function (a, b) {
return (a.timestamp > b.timestamp ? 1 : -1);
});
if (!this.lyrics_all.length) {
this.lyrics_all = undefined;
}
if (this.isEmpty(this.meta_info)) {
this.meta_info = undefined;
}
return (this.lyrics_all !== undefined || this.meta_info !== undefined) ? true : false;
},
getLyrics: function () {
return this.lyrics_all;
},
getLyric: function (idx) {
try {
return this.lyrics_all[idx];
} catch (e) {
return undefined;
}
},
getIDTags: function () {
return this.meta_info;
},
select: function (ts) {
if (isNaN(ts)) {
return -1;
}
var timestamp = Number(ts) + this.timestamp_offset;
var i = 0;
if (timestamp < this.lyrics_all[0].timestamp) {
return -1;
}
for (i = 0; i < (this.lyrics_all.length - 1); i++) {
if (this.lyrics_all[i].timestamp <= timestamp
&& this.lyrics_all[i + 1].timestamp > timestamp) {
break;
}
}
return i;
},
setTimestampOffset: function (offset) {
this.timestamp_offset = isNaN(offset) ? 0 : Number(offset) / 1000;
return Number(offset);
},
isEmpty: function (obj) {
for (var prop in obj) {
if (obj.hasOwnProperty(prop)) {
return false;
}
}
return true;
}
};
return Lyrics;
}));

@@ -1,1 +0,1 @@

!function(e,r){"use strict";"function"==typeof define&&define.amd?define([],r):"object"==typeof exports?module.exports=r():e.Lyrics=r()}(this,function(){"use strict";var e=function(r){var t=e.prototype,n=0,i=void 0,a=void 0,o=function(e){return n=isNaN(e)?0:Number(e)/1e3,Number(e)},u=function(e){for(var r in e)if(e.hasOwnProperty(r))return!1;return!0},f=[{name:"artist",id:"ar"},{name:"album",id:"al"},{name:"title",id:"ti"},{name:"author",id:"au"},{name:"length",id:"length"},{name:"by",id:"by"},{name:"offset",id:"offset",handler:o},{name:"createdBy",id:"re"},{name:"createdByVersion",id:"ve"}];t.load=function(e){i=new Array,a=new Object,n=0;for(var r=String(e).split("\n"),t=0;t<r.length;t++){var o=r[t].replace(/(^\s*)|(\s*$)/g,"");if(o){for(var s=!1,d=0;d<f.length;d++){var c=f[d].re.exec(o);if(c&&!(c.length<2)){s=!0;var m=c[1].replace(/(^\s*)|(\s*$)/g,"");"function"==typeof f[d].handler?a[String(f[d].name)]=f[d].handler.call(this,m):a[String(f[d].name)]=String(m)}}if(!s){for(var l=Array();;){var c=/^(\[\d+:\d+(.\d+)?\])(.*)/g.exec(o);if(!c)break;l.push(c[1]),o=c[c.length-1].replace(/(^\s*)|(\s*$)/g,"")}for(var d=0;d<l.length;d++){var g=/^\[(\d{1,2}):(\d|[0-5]\d)(\.(\d+))?\]$/g.exec(l[d]);g&&i.push({timestamp:60*Number(g[1])+Number(g[2])+(g[4]?Number("0."+g[4]):0),text:o})}}}}return i.sort(function(e,r){return e.timestamp>r.timestamp?1:-1}),i.length||(i=void 0),u(a)&&(a=void 0),void 0!==i||void 0!==a},t.getLyrics=function(){return i},t.getLyric=function(e){try{return i[e]}catch(e){return}},t.getIDTags=function(){return a},t.select=function(e){if(isNaN(e))return-1;var r=Number(e)+n,t=0;if(r<i[0].timestamp)return-1;for(t=0;t<i.length-1&&!(i[t].timestamp<=r&&i[t+1].timestamp>r);t++);return t};for(var s=0;s<f.length;s++)f[s].re=new RegExp("\\["+f[s].id+":(.*)\\]$","g");r&&this.load(r)};return e});
!function(t,i){"use strict";"function"==typeof define&&define.amd?define([],i):"object"==typeof exports?module.exports=i():t.Lyrics=i()}(this,function(){"use strict";var t=function(t){this.timestamp_offset=0,this.lyrics_all=void 0,this.meta_info=void 0,this.ID_TAGS=[{name:"artist",id:"ar"},{name:"album",id:"al"},{name:"title",id:"ti"},{name:"author",id:"au"},{name:"length",id:"length"},{name:"by",id:"by"},{name:"offset",id:"offset",handler:this.setTimestampOffset},{name:"createdBy",id:"re"},{name:"createdByVersion",id:"ve"}];for(var i=0;i<this.ID_TAGS.length;i++)this.ID_TAGS[i].re=new RegExp("\\["+this.ID_TAGS[i].id+":(.*)\\]$","g");t&&this.load(t)};return t.prototype={constructor:t,load:function(t){this.lyrics_all=new Array,this.meta_info=new Object,this.timestamp_offset=0;for(var i=String(t).split("\n"),e=0;e<i.length;e++){var r=i[e].replace(/(^\s*)|(\s*$)/g,"");if(r){for(var s=!1,n=0;n<this.ID_TAGS.length;n++){var a=this.ID_TAGS[n].re.exec(r);if(a&&!(a.length<2)){s=!0;var l=a[1].replace(/(^\s*)|(\s*$)/g,"");"function"==typeof this.ID_TAGS[n].handler?this.meta_info[String(this.ID_TAGS[n].name)]=this.ID_TAGS[n].handler.call(this,l):this.meta_info[String(this.ID_TAGS[n].name)]=String(l)}}if(!s){for(var h=Array();;){var a=/^(\[\d+:\d+(.\d+)?\])(.*)/g.exec(r);if(!a)break;h.push(a[1]),r=a[a.length-1].replace(/(^\s*)|(\s*$)/g,"")}for(var n=0;n<h.length;n++){var f=/^\[(\d{1,2}):(\d|[0-5]\d)(\.(\d+))?\]$/g.exec(h[n]);f&&this.lyrics_all.push({timestamp:60*Number(f[1])+Number(f[2])+(f[4]?Number("0."+f[4]):0),text:r})}}}}return this.lyrics_all.sort(function(t,i){return t.timestamp>i.timestamp?1:-1}),this.lyrics_all.length||(this.lyrics_all=void 0),this.isEmpty(this.meta_info)&&(this.meta_info=void 0),void 0!==this.lyrics_all||void 0!==this.meta_info},getLyrics:function(){return this.lyrics_all},getLyric:function(t){try{return this.lyrics_all[t]}catch(t){return}},getIDTags:function(){return this.meta_info},select:function(t){if(isNaN(t))return-1;var i=Number(t)+this.timestamp_offset,e=0;if(i<this.lyrics_all[0].timestamp)return-1;for(e=0;e<this.lyrics_all.length-1&&!(this.lyrics_all[e].timestamp<=i&&this.lyrics_all[e+1].timestamp>i);e++);return e},setTimestampOffset:function(t){return this.timestamp_offset=isNaN(t)?0:Number(t)/1e3,Number(t)},isEmpty:function(t){for(var i in t)if(t.hasOwnProperty(i))return!1;return!0}},t});
{
"name": "lyrics.js",
"version": "0.3.5",
"version": "0.4.0",
"description": "A JavaScript for parsing LRC file and synchronize lyrics.",

@@ -5,0 +5,0 @@ "main": "",

@@ -81,2 +81,31 @@ <!DOCTYPE html>

[04:37.410]Ah! 光を追いかけてきたんだよ…</script>
<script id='sample_complex_chinese' type='text/plain'>[00:27.540][04:31.520]Ah!由微小的预感拉开序幕
[00:32.970]Ah!希望在星空中穿梭
[00:38.450]像花朵绽放般的笑容
[00:43.920]一如既往的友情的笑容
[00:49.160]
[00:49.510]无法忘记 一直不会忘记
[00:54.940]我们的心这样连在一起
[01:00.410]见证这个世界上的快乐并为之歌唱
[01:09.940]直到最后(我们合而为一)
[01:16.660]
[01:17.040][03:37.800]小鸟的翅膀终于变得丰满
[01:25.010][03:45.640]展翅高飞踏上旅程
[01:28.130][03:48.760]暖色的海洋不断地延伸
[01:36.050][03:56.730]恍若曾几何时梦中描绘的景色
[01:40.300][04:00.990]此时感到有些伤感,是否要将时光倒转?
[01:52.490][04:13.240]No No No 现在是最好的时刻!
[01:58.620][02:42.890]
[02:20.460]与大家相遇相识让我非常开心
[02:27.090]我真的不想和大家分离
[02:31.550]我们不需要眼泪 就这么走下去吧
[02:36.980]挥挥手,再挥挥手
[02:45.370]正因为我们如此努力地追逐着光芒
[02:53.190]所以无需再说什么分别
[02:56.320]再度相会的时候,你是否还能喊出我的名字?
[03:04.320]在美好的未来中 我们紧紧相连的梦想
[03:08.560]你和我的Live and Life
[03:15.430][04:30.500][04:48.410]
[04:18.670]因为此时此刻就是最好的!
[04:37.410]Ah!我们一起追逐着那道光芒</script>
<script id='abnormal' type='text/plain'>[ar:Artist]

@@ -131,2 +160,3 @@ [ti:Title]

sample_complex = document.getElementById('sample_complex').innerHTML;
sample_complex_chinese = document.getElementById('sample_complex_chinese').innerHTML;
abnormal = document.getElementById('abnormal').innerHTML;

@@ -133,0 +163,0 @@ id_tags_only = document.getElementById('id_tags_only').innerHTML;

@@ -75,2 +75,32 @@ sample = `[ti:僕たちはひどつの光]

`
sample_complex_chinese = `[00:27.540][04:31.520]Ah!由微小的预感拉开序幕
[00:32.970]Ah!希望在星空中穿梭
[00:38.450]像花朵绽放般的笑容
[00:43.920]一如既往的友情的笑容
[00:49.160]
[00:49.510]无法忘记 一直不会忘记
[00:54.940]我们的心这样连在一起
[01:00.410]见证这个世界上的快乐并为之歌唱
[01:09.940]直到最后(我们合而为一)
[01:16.660]
[01:17.040][03:37.800]小鸟的翅膀终于变得丰满
[01:25.010][03:45.640]展翅高飞踏上旅程
[01:28.130][03:48.760]暖色的海洋不断地延伸
[01:36.050][03:56.730]恍若曾几何时梦中描绘的景色
[01:40.300][04:00.990]此时感到有些伤感,是否要将时光倒转?
[01:52.490][04:13.240]No No No 现在是最好的时刻!
[01:58.620][02:42.890]
[02:20.460]与大家相遇相识让我非常开心
[02:27.090]我真的不想和大家分离
[02:31.550]我们不需要眼泪 就这么走下去吧
[02:36.980]挥挥手,再挥挥手
[02:45.370]正因为我们如此努力地追逐着光芒
[02:53.190]所以无需再说什么分别
[02:56.320]再度相会的时候,你是否还能喊出我的名字?
[03:04.320]在美好的未来中 我们紧紧相连的梦想
[03:08.560]你和我的Live and Life
[03:15.430][04:30.500][04:48.410]
[04:18.670]因为此时此刻就是最好的!
[04:37.410]Ah!我们一起追逐着那道光芒
`
abnormal = `[ar:Artist]

@@ -77,0 +107,0 @@ [ti:Title]

@@ -81,2 +81,31 @@ <!DOCTYPE html>

[04:37.410]Ah! 光を追いかけてきたんだよ…</script>
<script id='sample_complex_chinese' type='text/plain'>[00:27.540][04:31.520]Ah!由微小的预感拉开序幕
[00:32.970]Ah!希望在星空中穿梭
[00:38.450]像花朵绽放般的笑容
[00:43.920]一如既往的友情的笑容
[00:49.160]
[00:49.510]无法忘记 一直不会忘记
[00:54.940]我们的心这样连在一起
[01:00.410]见证这个世界上的快乐并为之歌唱
[01:09.940]直到最后(我们合而为一)
[01:16.660]
[01:17.040][03:37.800]小鸟的翅膀终于变得丰满
[01:25.010][03:45.640]展翅高飞踏上旅程
[01:28.130][03:48.760]暖色的海洋不断地延伸
[01:36.050][03:56.730]恍若曾几何时梦中描绘的景色
[01:40.300][04:00.990]此时感到有些伤感,是否要将时光倒转?
[01:52.490][04:13.240]No No No 现在是最好的时刻!
[01:58.620][02:42.890]
[02:20.460]与大家相遇相识让我非常开心
[02:27.090]我真的不想和大家分离
[02:31.550]我们不需要眼泪 就这么走下去吧
[02:36.980]挥挥手,再挥挥手
[02:45.370]正因为我们如此努力地追逐着光芒
[02:53.190]所以无需再说什么分别
[02:56.320]再度相会的时候,你是否还能喊出我的名字?
[03:04.320]在美好的未来中 我们紧紧相连的梦想
[03:08.560]你和我的Live and Life
[03:15.430][04:30.500][04:48.410]
[04:18.670]因为此时此刻就是最好的!
[04:37.410]Ah!我们一起追逐着那道光芒</script>
<script id='abnormal' type='text/plain'>[ar:Artist]

@@ -131,2 +160,3 @@ [ti:Title]

sample_complex = document.getElementById('sample_complex').innerHTML;
sample_complex_chinese = document.getElementById('sample_complex_chinese').innerHTML;
abnormal = document.getElementById('abnormal').innerHTML;

@@ -133,0 +163,0 @@ id_tags_only = document.getElementById('id_tags_only').innerHTML;

@@ -159,1 +159,25 @@ function htmlspecialchars(s){

});
QUnit.test("Test Multiple Instances of Lyrics()", function(assert){
var lrc_1 = new Lyrics('[00:04.050] firstLine');
var lrc_2 = new Lyrics('[00:04.050] secondLine');
assert.deepEqual(lrc_1.getLyrics(), [{timestamp:4.05,text:'firstLine'}]);
assert.deepEqual(lrc_2.getLyrics(), [{timestamp:4.05,text:'secondLine'}]);
assert.strictEqual(lrc_1.getLyric(lrc_1.select(3)), undefined);
assert.deepEqual(lrc_1.getLyric(lrc_1.select(4.1)), {timestamp:4.05,text:'firstLine'});
assert.strictEqual(lrc_2.getLyric(lrc_2.select(3)), undefined);
assert.deepEqual(lrc_2.getLyric(lrc_2.select(4.1)), {timestamp:4.05,text:'secondLine'});
});
QUnit.test("Test Multiple Instances of Lyrics()", function(assert){
var lrc_1 = new Lyrics(sample_complex);
var lrc_2 = new Lyrics(sample_complex_chinese);
assert.deepEqual(lrc_1.getLyric(0), {timestamp:27.540,text:'Ah! ほのかな予感から始まり'});
assert.deepEqual(lrc_1.getLyric(4), {timestamp:49.160,text:''});
assert.deepEqual(lrc_2.getLyric(0), {timestamp:27.540,text:'Ah!由微小的预感拉开序幕'});
assert.deepEqual(lrc_2.getLyric(4), {timestamp:49.160,text:''});
assert.deepEqual(lrc_1.getLyric(4), {timestamp:49.160,text:''});
assert.deepEqual(lrc_2.getLyric(4), {timestamp:49.160,text:''});
assert.deepEqual(lrc_1.getLyric(0), {timestamp:27.540,text:'Ah! ほのかな予感から始まり'});
assert.deepEqual(lrc_2.getLyric(0), {timestamp:27.540,text:'Ah!由微小的预感拉开序幕'});
});

Sorry, the diff of this file is not supported yet