cqjjjzr / MusicBee-DesktopLyrics

Show the lyrics on your desktop from MusicBee!
Apache License 2.0
92 stars 5 forks source link

fix: display last lyric when the music not have lyric; perf: reduce loop #21

Open tumuyan opened 9 months ago

tumuyan commented 9 months ago

fix: still display last lyric when the music does not have lyric

  1. music have lyric -> music not have lyric
  2. lyric not contains [0:0.00]first line

perf: reduce loop

cqjjjzr commented 9 months ago

emm 没太看懂这个pr在做什么,能稍微说明下吗(

tumuyan commented 9 months ago

从有歌词的音乐播放到没有歌词的音乐时,或者从有歌词的音乐播放到第一行歌词不是从时间戳记为0的位置开始时,会发生仍然显示上一个音乐的最后一行歌词的bug。 bug的原因是更新歌词数据返回了null,然后没有做任何处理。 pr中返回了内容为空的歌词数据,从而进行了正常更新。

另一方面原先在更新需要显示的歌词时,是把整个lyricEntry进行遍历的,pr保留了上一次获取数据时的遍历的index,当时间点还在这行歌词所在范围内时,就跳过了遍历。当时间点大于这个范围,从下一行歌词开始遍历。当时间点小于这个范围时,从第一行歌词开始遍历。

这2部分都可以再study调优。

cqjjjzr commented 9 months ago

第1个部分,按理说DesktopLyrics.cs:233行这里在LyricsController.UpdateLyrics函数返回null的时候是做了处理的……加上在我的机器上也没成功复现(无论有没有打开“无歌词时隐藏歌词窗口”选项)。

第2个部分我后续看看重构下就合并,thx

tumuyan commented 9 months ago

我的选项如下 image

我在line 233位置添加了log print,

                if (entry == null && _line1 != "")
                {
                    Debug.WriteLine("UpdateLyrics(): entry == null && _line1 != \"\"");
                    _line1 = "";
                    _frmLyrics.Clear();
                    return;
                }

                if (entry == null)
                {
                    Debug.WriteLine("UpdateLyrics(): entry == null");
                    return; 
                }
                if (entry.LyricLine1 == _line1 && entry.LyricLine2 == _line2) return;
                _frmLyrics.BeginInvoke(new Action<string, string>((line1, line2) => _frmLyrics.UpdateLyrics(line1, line2)), entry.LyricLine1, entry.LyricLine2);
                _line1 = entry.LyricLine1;
                _line2 = entry.LyricLine2;

                Debug.WriteLine("UpdateLyrics(): _line1="+_line1);

这是切换音乐时的输出(没有等到播放结束,直接点无歌词的下一首进行切换,因此和lrc应该是无关的)

UpdateLyrics(): _line1=破旧的浆 被划破的海浪
UpdateLyrics(): _line1=罗盘已失去磁场 只剩星光
线程 0x3128 已退出,返回值为 0 (0x0)。
引发的异常:“System.InvalidOperationException”(位于 System.Windows.Forms.dll 中)
引发的异常:“System.Reflection.TargetInvocationException”(位于 mscorlib.dll 中)
引发的异常:“System.InvalidOperationException”(位于 System.Windows.Forms.dll 中)
引发的异常:“System.Reflection.TargetInvocationException”(位于 mscorlib.dll 中)
线程 0x1bdc 已退出,返回值为 0 (0x0)。
UpdateLyrics(): entry == null && _line1 != ""
引发的异常:“System.InvalidOperationException”(位于 System.Windows.Forms.dll 中)
UpdateLyrics(): entry == null
UpdateLyrics(): entry == null

单步debug时在TimerTick()函数内发生了崩溃,这是崩溃信息

此异常最初是在此调用堆栈中引发的: 
    System.Windows.Forms.Control.Handle.get() - 位于 Control.cs
    System.Windows.Forms.Control.SetBoundsCore(int, int, int, int, System.Windows.Forms.BoundsSpecified) - 位于 Control.cs
    System.Windows.Forms.Form.SetBoundsCore(int, int, int, int, System.Windows.Forms.BoundsSpecified) - 位于 Form.cs
    System.Windows.Forms.Control.SetBounds(int, int, int, int, System.Windows.Forms.BoundsSpecified) - 位于 Control.cs
    System.Windows.Forms.Control.Height.set(int) - 位于 Control.cs
    MusicBeePlugin.FrmLyrics.DrawLyrics1Line(string) - 位于 FrmLyrics.cs
    MusicBeePlugin.FrmLyrics.Clear() - 位于 FrmLyrics.cs
    MusicBeePlugin.Plugin.UpdateLyrics() - 位于 DesktopLyrics.cs
    MusicBeePlugin.Plugin.TimerTick(object, System.Timers.ElapsedEventArgs) - 位于 DesktopLyrics.cs

我对c#不是很熟悉,可能clear()函数不能直接调用,需要使用Invoke的方式?