@@ -4,6 +4,7 @@ import handleOption from './options';
44import Template from './template' ;
55import Bar from './bar' ;
66import User from './user' ;
7+ import Lrc from './lrc' ;
78
89const instances = [ ] ;
910
@@ -17,40 +18,11 @@ class APlayer {
1718 */
1819 constructor ( options ) {
1920 this . options = handleOption ( options ) ;
21+ this . container = this . options . container ;
2022
2123 this . audios = [ ] ;
2224 this . mode = this . options . mode ;
2325
24- // save lrc
25- this . container = this . options . container ;
26- if ( this . options . showlrc === 2 || this . options . showlrc === true ) {
27- this . savelrc = [ ] ;
28- const lrcEle = this . container . getElementsByClassName ( 'aplayer-lrc-content' ) ;
29- for ( let i = 0 ; i < lrcEle . length ; i ++ ) {
30- this . savelrc . push ( lrcEle [ i ] . innerHTML ) ;
31- }
32- }
33- this . lrcs = [ ] ;
34-
35- /**
36- * Update lrc
37- *
38- * @param {Number } currentTime
39- */
40- this . updateLrc = ( currentTime = this . audio . currentTime ) => {
41- if ( this . lrcIndex > this . lrc . length - 1 || currentTime < this . lrc [ this . lrcIndex ] [ 0 ] || ( ! this . lrc [ this . lrcIndex + 1 ] || currentTime >= this . lrc [ this . lrcIndex + 1 ] [ 0 ] ) ) {
42- for ( let i = 0 ; i < this . lrc . length ; i ++ ) {
43- if ( currentTime >= this . lrc [ i ] [ 0 ] && ( ! this . lrc [ i + 1 ] || currentTime < this . lrc [ i + 1 ] [ 0 ] ) ) {
44- this . lrcIndex = i ;
45- this . template . lrc . style . transform = `translateY(${ - this . lrcIndex * 16 } px)` ;
46- this . template . lrc . style . webkitTransform = `translateY(${ - this . lrcIndex * 16 } px)` ;
47- this . template . lrc . getElementsByClassName ( 'aplayer-lrc-current' ) [ 0 ] . classList . remove ( 'aplayer-lrc-current' ) ;
48- this . template . lrc . getElementsByTagName ( 'p' ) [ i ] . classList . add ( 'aplayer-lrc-current' ) ;
49- }
50- }
51- }
52- } ;
53-
5426 // define APlayer events
5527 const eventTypes = [ 'play' , 'pause' , 'canplay' , 'playing' , 'ended' , 'error' ] ;
5628 this . event = { } ;
@@ -96,6 +68,17 @@ class APlayer {
9668 this . container . classList . add ( 'aplayer-narrow' ) ;
9769 }
9870
71+ // save lrc
72+ this . container = this . options . container ;
73+ if ( this . options . showlrc === 2 || this . options . showlrc === true ) {
74+ const lrcEle = this . container . getElementsByClassName ( 'aplayer-lrc-content' ) ;
75+ for ( let i = 0 ; i < lrcEle . length ; i ++ ) {
76+ if ( this . options . music [ i ] ) {
77+ this . options . music [ i ] . lrc = lrcEle [ i ] . innerHTML ;
78+ }
79+ }
80+ }
81+
9982 this . template = new Template ( {
10083 container : this . container ,
10184 options : this . options ,
@@ -106,6 +89,15 @@ class APlayer {
10689 this . template . time . classList . add ( 'aplayer-time-narrow' ) ;
10790 }
10891
92+ if ( this . options . showlrc ) {
93+ this . lrc = new Lrc ( {
94+ container : this . template . lrc ,
95+ async : this . options . showlrc === 3 ,
96+ content : this . options . music . map ( ( item ) => item . lrc ) ,
97+ player : this ,
98+ } ) ;
99+ }
100+
109101 this . bar = new Bar ( this . template ) ;
110102
111103 // play and pause button
@@ -160,9 +152,7 @@ class APlayer {
160152 percentage = percentage > 0 ? percentage : 0 ;
161153 percentage = percentage < 1 ? percentage : 1 ;
162154 this . bar . set ( 'played' , percentage , 'width' ) ;
163- if ( this . options . showlrc ) {
164- this . updateLrc ( this . bar . get ( 'played' , 'width' ) * this . audio . duration ) ;
165- }
155+ this . lrc && this . lrc . update ( this . bar . get ( 'played' , 'width' ) * this . audio . duration ) ;
166156 this . template . ptime . innerHTML = utils . secondToTime ( percentage * this . audio . duration ) ;
167157 } ;
168158
@@ -176,9 +166,7 @@ class APlayer {
176166 this . audio . currentTime = this . bar . get ( 'played' , 'width' ) * this . audio . duration ;
177167 this . playedTime = setInterval ( ( ) => {
178168 this . bar . set ( 'played' , this . audio . currentTime / this . audio . duration , 'width' ) ;
179- if ( this . options . showlrc ) {
180- this . updateLrc ( ) ;
181- }
169+ this . lrc && this . lrc . update ( ) ;
182170 this . template . ptime . innerHTML = utils . secondToTime ( this . audio . currentTime ) ;
183171 this . trigger ( 'playing' ) ;
184172 } , 100 ) ;
@@ -344,9 +332,7 @@ class APlayer {
344332 }
345333 this . playedTime = setInterval ( ( ) => {
346334 this . bar . set ( 'played' , this . audio . currentTime / this . audio . duration , 'width' ) ;
347- if ( this . options . showlrc ) {
348- this . updateLrc ( ) ;
349- }
335+ this . lrc && this . lrc . update ( ) ;
350336 this . template . ptime . innerHTML = utils . secondToTime ( this . audio . currentTime ) ;
351337 this . trigger ( 'playing' ) ;
352338 } , 100 ) ;
@@ -448,109 +434,7 @@ class APlayer {
448434 this . audios [ indexMusic ] = this . audio ;
449435 }
450436
451- /**
452- * Parse lrc, suppose multiple time tag
453- *
454- * @param {String } lrc_s - Format:
455- * [mm:ss.xx]lyric
456- * [mm:ss.xxx]lyric
457- * [mm:ss.xx][mm:ss.xx][mm:ss.xx]lyric
458- *
459- * @return {String } [[time, text], [time, text], [time, text], ...]
460- */
461- const parseLrc = ( lrc_s ) => {
462- const lyric = lrc_s . split ( '\n' ) ;
463- const lrc = [ ] ;
464- const lyricLen = lyric . length ;
465- for ( let i = 0 ; i < lyricLen ; i ++ ) {
466- // match lrc time
467- const lrcTimes = lyric [ i ] . match ( / \[ ( \d { 2 } ) : ( \d { 2 } ) \. ( \d { 2 , 3 } ) ] / g) ;
468- // match lrc text
469- const lrcText = lyric [ i ] . replace ( / \[ ( \d { 2 } ) : ( \d { 2 } ) \. ( \d { 2 , 3 } ) ] / g, '' ) . replace ( / ^ \s + | \s + $ / g, '' ) ;
470-
471- if ( lrcTimes ) {
472- // handle multiple time tag
473- const timeLen = lrcTimes . length ;
474- for ( let j = 0 ; j < timeLen ; j ++ ) {
475- const oneTime = / \[ ( \d { 2 } ) : ( \d { 2 } ) \. ( \d { 2 , 3 } ) ] / . exec ( lrcTimes [ j ] ) ;
476- const lrcTime = oneTime [ 1 ] * 60 + parseInt ( oneTime [ 2 ] ) + parseInt ( oneTime [ 3 ] ) / ( ( oneTime [ 3 ] + '' ) . length === 2 ? 100 : 1000 ) ;
477- lrc . push ( [ lrcTime , lrcText ] ) ;
478- }
479- }
480- }
481- // sort by time
482- lrc . sort ( ( a , b ) => a [ 0 ] - b [ 0 ] ) ;
483- return lrc ;
484- } ;
485-
486- // fill in lrc
487- if ( this . options . showlrc ) {
488- const index = indexMusic ;
489-
490- if ( ! this . lrcs [ index ] ) {
491- let lrcs = '' ;
492- if ( this . options . showlrc === 1 ) {
493- lrcs = this . options . music [ index ] . lrc ;
494- }
495- else if ( this . options . showlrc === 2 || this . options . showlrc === true ) {
496- lrcs = this . savelrc [ index ] ;
497- }
498- else if ( this . options . showlrc === 3 ) {
499- const xhr = new XMLHttpRequest ( ) ;
500- xhr . onreadystatechange = ( ) => {
501- if ( xhr . readyState === 4 ) {
502- if ( xhr . status >= 200 && xhr . status < 300 || xhr . status === 304 ) {
503- lrcs = xhr . responseText ;
504- this . lrcs [ index ] = parseLrc ( lrcs ) ;
505- }
506- else {
507- console . log ( 'Request was unsuccessful: ' + xhr . status ) ;
508- this . lrcs [ index ] = [ [ '00:00' , 'Not available' ] ] ;
509- }
510- this . lrc = this . lrcs [ index ] ;
511- let lrcHTML = '' ;
512- for ( let i = 0 ; i < this . lrc . length ; i ++ ) {
513- lrcHTML += `<p>${ this . lrc [ i ] [ 1 ] } </p>` ;
514- }
515- this . template . lrc . innerHTML = lrcHTML ;
516- if ( ! this . lrcIndex ) {
517- this . lrcIndex = 0 ;
518- }
519- this . template . lrc . getElementsByTagName ( 'p' ) [ 0 ] . classList . add ( 'aplayer-lrc-current' ) ;
520- this . template . lrc . style . transform = 'translateY(0px)' ;
521- this . template . lrc . style . webkitTransform = 'translateY(0px)' ;
522- }
523- } ;
524- const apiurl = this . options . music [ index ] . lrc ;
525- xhr . open ( 'get' , apiurl , true ) ;
526- xhr . send ( null ) ;
527- }
528- if ( lrcs ) {
529- this . lrcs [ index ] = parseLrc ( lrcs ) ;
530- }
531- else {
532- if ( this . options . showlrc === 3 ) {
533- this . lrcs [ index ] = [ [ '00:00' , 'Loading' ] ] ;
534- }
535- else {
536- this . lrcs [ index ] = [ [ '00:00' , 'Not available' ] ] ;
537- }
538- }
539- }
540-
541- this . lrc = this . lrcs [ index ] ;
542- let lrcHTML = '' ;
543- for ( let i = 0 ; i < this . lrc . length ; i ++ ) {
544- lrcHTML += `<p>${ this . lrc [ i ] [ 1 ] } </p>` ;
545- }
546- this . template . lrc . innerHTML = lrcHTML ;
547- if ( ! this . lrcIndex ) {
548- this . lrcIndex = 0 ;
549- }
550- this . template . lrc . getElementsByTagName ( 'p' ) [ 0 ] . classList . add ( 'aplayer-lrc-current' ) ;
551- this . template . lrc . style . transform = 'translateY(0px)' ;
552- this . template . lrc . style . webkitTransform = 'translateY(0px)' ;
553- }
437+ this . lrc && this . lrc . switch ( indexMusic ) ;
554438
555439 // set duration time
556440 if ( this . audio . duration !== 1 ) { // compatibility: Android browsers will output 1 at first
0 commit comments