1919using Microsoft . UI . Xaml ;
2020using Microsoft . UI . Xaml . Controls ;
2121using System ;
22+ using System . Collections . Generic ;
2223using System . Linq ;
2324using System . Numerics ;
2425using Windows . Foundation ;
@@ -96,6 +97,7 @@ public sealed partial class LyricsCanvas : UserControl,
9697 easingType : EasingType . EaseInOutSine
9798 ) ;
9899
100+ private TimeSpan _songPositionWithOffset ;
99101 private TimeSpan _songPosition ; // 当前歌曲时刻
100102 private TimeSpan _totalPlayedTime ; // 当前歌曲播放总时长(包括来来回回重复播放的时间)
101103 private bool _isLastFMTracked = false ;
@@ -112,7 +114,7 @@ public sealed partial class LyricsCanvas : UserControl,
112114 private bool _isMousePressing = false ;
113115 private bool _isMouseScrolling = false ;
114116
115- private LyricsData ? _lyricsData ;
117+ private List < RenderLyricsLine > ? _renderLyricsLines = null ;
116118
117119 private bool _isLayoutChanged = true ;
118120 private bool _isMouseScrollingChanged = false ;
@@ -123,7 +125,7 @@ public sealed partial class LyricsCanvas : UserControl,
123125
124126 public TimeSpan SongPosition => _songPosition ;
125127 public double CurrentCanvasYScroll => _canvasYScrollTransition . Value ;
126- public double ActualLyricsHeight => LyricsLayoutManager . CalculateActualHeight ( _lyricsData ? . LyricsLines ) ;
128+ public double ActualLyricsHeight => LyricsLayoutManager . CalculateActualHeight ( _renderLyricsLines ) ;
127129 public int CurrentHoveringLineIndex => _mouseHoverLineIndex ;
128130
129131 // 歌词区域起始横 X 坐标
@@ -316,8 +318,6 @@ private void Canvas_Draw(ICanvasAnimatedControl sender, CanvasAnimatedDrawEventA
316318 double songDuration = _mediaSessionsService . CurrentSongInfo ? . DurationMs ?? 0 ;
317319 bool isForceWordByWord = _settingsService . AppSettings . GeneralSettings . IsForceWordByWordEffect ;
318320
319- double fixedSongPositionMs = _songPosition . TotalMilliseconds + ( _mediaSessionsService . CurrentMediaSourceProviderInfo ? . PositionOffset ?? 0 ) ;
320-
321321 var lyricsThemeColors = _mediaSessionsService . AlbumArtThemeColors ;
322322
323323 Color overlayColor ;
@@ -355,7 +355,7 @@ private void Canvas_Draw(ICanvasAnimatedControl sender, CanvasAnimatedDrawEventA
355355 _lyricsRenderer . Draw (
356356 control : sender ,
357357 ds : args . DrawingSession ,
358- lyricsData : _lyricsData ,
358+ lines : _renderLyricsLines ,
359359 playingLineIndex : _playingLineIndex ,
360360 mouseHoverLineIndex : _mouseHoverLineIndex ,
361361 isMousePressing : _isMousePressing ,
@@ -374,15 +374,15 @@ private void Canvas_Draw(ICanvasAnimatedControl sender, CanvasAnimatedDrawEventA
374374 fgColor : lyricsThemeColors . FgFontColor ,
375375 getPlaybackState : ( lineIndex ) =>
376376 {
377- if ( _lyricsData == null ) return new LinePlaybackState ( ) ;
377+ if ( _renderLyricsLines == null ) return new LinePlaybackState ( ) ;
378378
379- var line = _lyricsData . LyricsLines . ElementAtOrDefault ( lineIndex ) ;
379+ var line = _renderLyricsLines . ElementAtOrDefault ( lineIndex ) ;
380380 if ( line == null ) return new LinePlaybackState ( ) ;
381381
382- var nextLine = _lyricsData . LyricsLines . ElementAtOrDefault ( lineIndex + 1 ) ;
382+ var nextLine = _renderLyricsLines . ElementAtOrDefault ( lineIndex + 1 ) ;
383383
384384 return _synchronizer . GetLinePlayingProgress (
385- fixedSongPositionMs ,
385+ _songPositionWithOffset . TotalMilliseconds ,
386386 line ,
387387 nextLine ,
388388 songDuration ,
@@ -411,12 +411,12 @@ private void Canvas_Draw(ICanvasAnimatedControl sender, CanvasAnimatedDrawEventA
411411 args . DrawingSession . DrawText (
412412 $ "Lyrics render start pos: ({ ( int ) _renderLyricsStartX } , { ( int ) _renderLyricsStartY } )\n " +
413413 $ "Lyrics render size: [{ ( int ) _renderLyricsWidth } x { ( int ) _renderLyricsHeight } ]\n " +
414- $ "Lyrics actual height: { LyricsLayoutManager . CalculateActualHeight ( _lyricsData ? . LyricsLines ) } \n " +
414+ $ "Lyrics actual height: { LyricsLayoutManager . CalculateActualHeight ( _renderLyricsLines ) } \n " +
415415 $ "Playing line (idx): { _playingLineIndex } \n " +
416416 $ "Mouse hovering line (idx): { _mouseHoverLineIndex } \n " +
417417 $ "Visible lines range (idx): [{ _visibleRange . Start } , { _visibleRange . End } ]\n " +
418- $ "Total line count: { LyricsLayoutManager . CalculateMaxRange ( _lyricsData ? . LyricsLines ) . End + 1 } \n " +
419- $ "Played: { TimeSpan . FromMilliseconds ( fixedSongPositionMs ) } / { TimeSpan . FromMilliseconds ( _mediaSessionsService . CurrentSongInfo ? . DurationMs ?? 0 ) } \n " +
418+ $ "Total line count: { LyricsLayoutManager . CalculateMaxRange ( _renderLyricsLines ) . End + 1 } \n " +
419+ $ "Played: { _songPosition } / { TimeSpan . FromMilliseconds ( _mediaSessionsService . CurrentSongInfo ? . DurationMs ?? 0 ) } \n " +
420420 $ "Y offset: { _canvasYScrollTransition . Value } \n " +
421421 $ "User scroll offset: { _mouseYScrollTransition . Value } ",
422422 new Vector2 ( 0 , 0 ) , Colors . Red ) ;
@@ -430,6 +430,7 @@ private void Canvas_Update(ICanvasAnimatedControl sender, CanvasAnimatedUpdateEv
430430 var lyricsStyle = _liveStatesService . LiveStates . LyricsWindowStatus . LyricsStyleSettings ;
431431 var lyricsEffect = _liveStatesService . LiveStates . LyricsWindowStatus . LyricsEffectSettings ;
432432 var albumArtThemeColors = _mediaSessionsService . AlbumArtThemeColors ;
433+ var lyricsData = _mediaSessionsService . CurrentLyricsData ;
433434
434435 TimeSpan elapsedTime = args . Timing . ElapsedTime ;
435436
@@ -447,7 +448,7 @@ private void Canvas_Update(ICanvasAnimatedControl sender, CanvasAnimatedUpdateEv
447448
448449 #region UpdatePlayingLineIndex
449450
450- int newPlayingIndex = _synchronizer . GetCurrentLineIndex ( _songPosition . TotalMilliseconds , _lyricsData ) ;
451+ int newPlayingIndex = _synchronizer . GetCurrentLineIndex ( _songPositionWithOffset . TotalMilliseconds , lyricsData ) ;
451452 bool isPlayingLineChanged = newPlayingIndex != _playingLineIndex ;
452453 _playingLineIndex = newPlayingIndex ;
453454
@@ -457,7 +458,7 @@ private void Canvas_Update(ICanvasAnimatedControl sender, CanvasAnimatedUpdateEv
457458
458459 if ( isPlayingLineChanged || _isLayoutChanged )
459460 {
460- var targetScroll = LyricsLayoutManager . CalculateTargetScrollOffset ( _lyricsData , _playingLineIndex ) ;
461+ var targetScroll = LyricsLayoutManager . CalculateTargetScrollOffset ( _renderLyricsLines , _playingLineIndex ) ;
461462 if ( targetScroll . HasValue ) _canvasTargetScrollOffset = targetScroll . Value ;
462463
463464 _canvasYScrollTransition . SetEasingType ( lyricsEffect . LyricsScrollEasingType ) ;
@@ -471,7 +472,7 @@ private void Canvas_Update(ICanvasAnimatedControl sender, CanvasAnimatedUpdateEv
471472 _mouseYScrollTransition . Update ( elapsedTime ) ;
472473
473474 _mouseHoverLineIndex = LyricsLayoutManager . FindMouseHoverLineIndex (
474- _lyricsData ? . LyricsLines ,
475+ _renderLyricsLines ,
475476 _isMouseInLyricsArea ,
476477 _mousePosition ,
477478 _canvasYScrollTransition . Value + _mouseYScrollTransition . Value ,
@@ -481,18 +482,18 @@ private void Canvas_Update(ICanvasAnimatedControl sender, CanvasAnimatedUpdateEv
481482 ) ;
482483
483484 _visibleRange = LyricsLayoutManager . CalculateVisibleRange (
484- _lyricsData ? . LyricsLines ,
485+ _renderLyricsLines ,
485486 _canvasYScrollTransition . Value + _mouseYScrollTransition . Value , // 当前滚动位置
486487 _renderLyricsStartY ,
487488 _renderLyricsHeight ,
488489 sender . Size . Height ,
489490 lyricsStyle . PlayingLineTopOffset / 100.0
490491 ) ;
491492
492- var maxRange = LyricsLayoutManager . CalculateMaxRange ( _lyricsData ? . LyricsLines ) ;
493+ var maxRange = LyricsLayoutManager . CalculateMaxRange ( _renderLyricsLines ) ;
493494
494495 _animator . UpdateLines (
495- _lyricsData ,
496+ _renderLyricsLines ,
496497 _isMouseScrolling ? maxRange . Start : _visibleRange . Start ,
497498 _isMouseScrolling ? maxRange . End : _visibleRange . End ,
498499 _playingLineIndex ,
@@ -591,11 +592,11 @@ private void DisposeAnalyzer()
591592
592593 private void TriggerRelayout ( )
593594 {
594- if ( _lyricsData == null || ! _isLayoutChanged ) return ;
595+ if ( _renderLyricsLines == null || ! _isLayoutChanged ) return ;
595596
596597 LyricsLayoutManager . MeasureAndArrange (
597598 resourceCreator : Canvas ,
598- lyricsData : _lyricsData ,
599+ lines : _renderLyricsLines ,
599600 status : _liveStatesService . LiveStates . LyricsWindowStatus ,
600601 appSettings : _settingsService . AppSettings ,
601602 canvasWidth : Canvas . Size . Width ,
@@ -611,6 +612,7 @@ private void UpdatePlaybackState(TimeSpan elapsedTime)
611612 {
612613 _songPosition += elapsedTime ;
613614 _totalPlayedTime += elapsedTime ;
615+ _songPositionWithOffset = _songPosition + TimeSpan . FromMilliseconds ( _mediaSessionsService . CurrentMediaSourceProviderInfo ? . PositionOffset ?? 0 ) ;
614616 CheckAndScrobbleLastFM ( ) ;
615617 }
616618 }
@@ -632,7 +634,7 @@ private void CheckAndScrobbleLastFM()
632634
633635 private void ResetPlaybackState ( )
634636 {
635- _totalPlayedTime = TimeSpan . Zero ;
637+ _songPosition = TimeSpan . Zero ;
636638 _totalPlayedTime = TimeSpan . Zero ;
637639 _isLastFMTracked = false ;
638640 }
@@ -694,7 +696,19 @@ public void Receive(PropertyChangedMessage<LyricsData?> message)
694696 {
695697 if ( message . PropertyName == nameof ( IMediaSessionsService . CurrentLyricsData ) )
696698 {
697- _lyricsData = message . NewValue ;
699+ _renderLyricsLines = null ;
700+ if ( _mediaSessionsService . CurrentLyricsData is LyricsData lyricsData )
701+ {
702+ _renderLyricsLines = lyricsData . LyricsLines . Select ( x => new RenderLyricsLine ( )
703+ {
704+ LyricsSyllables = x . LyricsSyllables ,
705+ StartMs = x . StartMs ,
706+ EndMs = x . EndMs ,
707+ PhoneticText = x . PhoneticText ,
708+ OriginalText = x . OriginalText ,
709+ TranslatedText = x . TranslatedText
710+ } ) . ToList ( ) ;
711+ }
698712 _isLayoutChanged = true ;
699713 }
700714 }
0 commit comments