@@ -320,8 +320,6 @@ export class Player {
320320 this . isPaused = false
321321
322322 if ( ! wasResuming && ! this . _isRestoring ) {
323- this . _lyricsBasePackets =
324- this . connection ?. statistics ?. packetsExpected ?? 0
325323 this . _fading ( 'trackStart' )
326324 this . _emitTrackStart ( )
327325 }
@@ -771,6 +769,8 @@ export class Player {
771769 resource . setVolume ( this . volumePercent / 100 )
772770 }
773771 this . _lyricsBasePosition = startTime
772+ this . _lyricsBasePackets =
773+ this . connection ?. statistics ?. packetsExpected ?? 0
774774 this . _fading ( 'trackStartArm' , { resource } )
775775 this . _fading ( 'trackEndSchedule' , { startPosition : startTime || 0 } )
776776
@@ -957,7 +957,7 @@ export class Player {
957957 clearTimeout ( this . _lyricsMarkerTimer )
958958 this . _lyricsMarkerTimer = null
959959 }
960- if ( this . isLyricsSubscribed ) this . _recalculateLyricsIndex ( )
960+ if ( this . isLyricsSubscribed ) this . _recalculateLyricsIndex ( undefined , undefined , true )
961961 this . _fading ( 'seek' )
962962 this . _fading ( 'trackEndSchedule' , { startPosition : this . position } )
963963 }
@@ -1047,6 +1047,9 @@ export class Player {
10471047 'Player' ,
10481048 `Playing resource for guild ${ this . guildId } after source seek`
10491049 )
1050+ this . _lyricsBasePosition = position
1051+ this . _lyricsBasePackets =
1052+ this . connection ?. statistics ?. packetsExpected ?? 0
10501053 this . connection . play ( resource )
10511054 await this . waitEvent ( 'playerStateChange' , ( s ) => s . status === 'playing' )
10521055
@@ -1099,6 +1102,10 @@ export class Player {
10991102 this . _fading ( 'seekPrepare' , { resource } )
11001103 resource . setFilters ( this . filters )
11011104
1105+ this . _lyricsBasePosition = position
1106+ this . _lyricsBasePackets =
1107+ this . connection ?. statistics ?. packetsExpected ?? 0
1108+
11021109 const oldStream = this . connection . play ( resource )
11031110 await this . waitEvent ( 'playerStateChange' , ( s ) => s . status === 'playing' )
11041111 if ( oldStream ) {
@@ -1214,6 +1221,9 @@ export class Player {
12141221 'Player' ,
12151222 `Playing resource for guild ${ this . guildId } after legacy seek`
12161223 )
1224+ this . _lyricsBasePosition = position
1225+ this . _lyricsBasePackets =
1226+ this . connection ?. statistics ?. packetsExpected ?? 0
12171227 this . connection . play ( resource )
12181228 await this . waitEvent ( 'playerStateChange' , ( s ) => s . status === 'playing' )
12191229
@@ -1603,16 +1613,25 @@ export class Player {
16031613 )
16041614
16051615 if ( lyricsData && lyricsData . loadType === 'lyrics' ) {
1616+ const lines = lyricsData . data . lines . map ( ( line ) => ( {
1617+ timestamp : line . time ,
1618+ duration : line . duration || 0 ,
1619+ line : line . text ,
1620+ words : line . words || [ ] ,
1621+ plugin : { }
1622+ } ) )
1623+
1624+ for ( let i = 0 ; i < lines . length - 1 ; i ++ ) {
1625+ if ( lines [ i ] . duration === 0 ) {
1626+ lines [ i ] . duration = lines [ i + 1 ] . timestamp - lines [ i ] . timestamp
1627+ }
1628+ }
1629+
16061630 const payload = {
16071631 sourceName : this . track . info . sourceName ,
16081632 provider : lyricsData . data . provider ,
16091633 text : lyricsData . data . lines . map ( ( l ) => l . text ) . join ( '\n' ) ,
1610- lines : lyricsData . data . lines . map ( ( line ) => ( {
1611- timestamp : line . time ,
1612- duration : line . duration ,
1613- line : line . text ,
1614- plugin : { }
1615- } ) ) ,
1634+ lines,
16161635 plugin : { }
16171636 }
16181637
@@ -1623,7 +1642,7 @@ export class Player {
16231642 clearTimeout ( this . _lyricsMarkerTimer )
16241643 this . _lyricsMarkerTimer = null
16251644 }
1626- this . _recalculateLyricsIndex ( )
1645+ this . _recalculateLyricsIndex ( undefined , undefined , true )
16271646 this . _syncLyrics ( true )
16281647 } else {
16291648 this . currentLyrics = null
@@ -1635,16 +1654,12 @@ export class Player {
16351654 if ( ! this . isLyricsSubscribed || ! this . currentLyrics || ! this . currentLyrics . lines ) return
16361655 if ( this . _lyricsMarkerTimer && ! force ) return
16371656
1638- const stats = this . connection ?. statistics
1639- if ( ! stats ) return
16401657 const timescale = this . filters . filters ?. timescale || {
16411658 speed : 1.0 ,
16421659 rate : 1.0
16431660 }
16441661 const playbackSpeed = ( timescale . speed || 1.0 ) * ( timescale . rate || 1.0 )
1645- const packets = stats . packetsExpected ?? this . _lyricsBasePackets
1646- const deltaPackets = Math . max ( 0 , packets - this . _lyricsBasePackets )
1647- const position = this . _lyricsBasePosition + deltaPackets * 20 * playbackSpeed
1662+ const position = this . _getLyricsPosition ( playbackSpeed )
16481663 const lines = this . currentLyrics . lines
16491664 this . _recalculateLyricsIndex ( position , lines )
16501665
@@ -1657,19 +1672,18 @@ export class Player {
16571672 this . _lyricsMarkerTimer = setTimeout ( ( ) => {
16581673 this . _lyricsMarkerTimer = null
16591674 if ( ! this . isLyricsSubscribed || ! this . currentLyrics || ! this . currentLyrics . lines ) return
1660- const nowStats = this . connection ?. statistics
1661- if ( ! nowStats ) return
1662- const nowPackets = nowStats . packetsExpected ?? this . _lyricsBasePackets
1663- const nowDeltaPackets = Math . max ( 0 , nowPackets - this . _lyricsBasePackets )
1664- const nowPosition =
1665- this . _lyricsBasePosition + nowDeltaPackets * 20 * playbackSpeed
1675+ const nowPosition = this . _getLyricsPosition ( playbackSpeed )
16661676 const drift = nowPosition - nextTimestamp
16671677
16681678 if ( drift < - 15 ) {
16691679 this . _syncLyrics ( true )
16701680 return
16711681 }
16721682
1683+ if ( Math . abs ( drift ) > 100 ) {
1684+ this . _lyricsBasePosition -= drift * 0.25
1685+ }
1686+
16731687 this . lyricsLineIndex = nextIndex
16741688 this . emitEvent ( 'LyricsLineEvent' , {
16751689 lineIndex : nextIndex ,
@@ -1680,23 +1694,26 @@ export class Player {
16801694 } , delayMs )
16811695 }
16821696
1683- _recalculateLyricsIndex ( positionOverride , linesOverride ) {
1697+ _getLyricsPosition ( playbackSpeed ) {
1698+ const stats = this . connection ?. statistics
1699+ const packets = stats ?. packetsExpected ?? this . _lyricsBasePackets
1700+ const deltaPackets = Math . max ( 0 , packets - this . _lyricsBasePackets )
1701+
1702+ return this . _lyricsBasePosition + deltaPackets * 20 * playbackSpeed
1703+ }
1704+ _recalculateLyricsIndex ( positionOverride , linesOverride , allowBackward = false ) {
16841705 if ( ! this . currentLyrics || ! this . currentLyrics . lines ) return
16851706
16861707 const lines = linesOverride || this . currentLyrics . lines
16871708 let position = positionOverride
16881709
16891710 if ( position === undefined ) {
1690- const stats = this . connection ?. statistics
1691- if ( ! stats ) return
16921711 const timescale = this . filters . filters ?. timescale || {
16931712 speed : 1.0 ,
16941713 rate : 1.0
16951714 }
16961715 const playbackSpeed = ( timescale . speed || 1.0 ) * ( timescale . rate || 1.0 )
1697- const packets = stats . packetsExpected ?? this . _lyricsBasePackets
1698- const deltaPackets = Math . max ( 0 , packets - this . _lyricsBasePackets )
1699- position = this . _lyricsBasePosition + deltaPackets * 20 * playbackSpeed
1716+ position = this . _getLyricsPosition ( playbackSpeed )
17001717 }
17011718
17021719 let foundIndex = - 1
@@ -1709,6 +1726,10 @@ export class Player {
17091726 }
17101727 }
17111728
1729+ if ( ! allowBackward && foundIndex < this . lyricsLineIndex ) {
1730+ return
1731+ }
1732+
17121733 if ( foundIndex !== this . lyricsLineIndex ) {
17131734 const skipped = foundIndex > this . lyricsLineIndex + 1
17141735 this . lyricsLineIndex = foundIndex
0 commit comments