diff --git a/BetterLyrics.WinUI3/BetterLyrics.WinUI3 (Package)/Package.appxmanifest b/BetterLyrics.WinUI3/BetterLyrics.WinUI3 (Package)/Package.appxmanifest
index 3a487b9..1473f36 100644
--- a/BetterLyrics.WinUI3/BetterLyrics.WinUI3 (Package)/Package.appxmanifest
+++ b/BetterLyrics.WinUI3/BetterLyrics.WinUI3 (Package)/Package.appxmanifest
@@ -12,7 +12,7 @@
+ Version="1.2.247.0" />
diff --git a/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Constants/Time.cs b/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Constants/Time.cs
index 27bb86b..04ea75f 100644
--- a/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Constants/Time.cs
+++ b/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Constants/Time.cs
@@ -6,6 +6,7 @@ namespace BetterLyrics.WinUI3.Constants
{
public static readonly TimeSpan DebounceTimeout = TimeSpan.FromMilliseconds(250);
public static readonly TimeSpan AnimationDuration = TimeSpan.FromMilliseconds(350);
+ public static readonly TimeSpan LongAnimationDuration = TimeSpan.FromMilliseconds(650);
public static readonly TimeSpan WaitingDuration = TimeSpan.FromMilliseconds(300);
}
}
diff --git a/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Controls/LyricsCanvas.xaml.cs b/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Controls/LyricsCanvas.xaml.cs
index fa0f849..617750f 100644
--- a/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Controls/LyricsCanvas.xaml.cs
+++ b/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Controls/LyricsCanvas.xaml.cs
@@ -119,7 +119,7 @@ namespace BetterLyrics.WinUI3.Controls
private bool _isLayoutChanged = true;
private bool _isMouseScrollingChanged = false;
- private int _playingLineIndex;
+ private int _primaryPlayingLineIndex;
private (int Start, int End) _visibleRange;
private double _canvasTargetScrollOffset;
@@ -382,7 +382,6 @@ namespace BetterLyrics.WinUI3.Controls
control: sender,
ds: args.DrawingSession,
lines: _renderLyricsLines,
- playingLineIndex: _playingLineIndex,
mouseHoverLineIndex: _mouseHoverLineIndex,
isMousePressing: _isMousePressing,
startVisibleIndex: _visibleRange.Start,
@@ -411,8 +410,6 @@ namespace BetterLyrics.WinUI3.Controls
return _synchronizer.GetLinePlayingProgress(
_songPositionWithOffset.TotalMilliseconds,
line,
- nextLine,
- songDuration,
isForceWordByWord
);
}
@@ -476,17 +473,17 @@ namespace BetterLyrics.WinUI3.Controls
#region UpdatePlayingLineIndex
- int newPlayingIndex = _synchronizer.GetCurrentLineIndex(_songPositionWithOffset.TotalMilliseconds, _renderLyricsLines);
- bool isPlayingLineChanged = newPlayingIndex != _playingLineIndex;
- _playingLineIndex = newPlayingIndex;
+ int primaryPlayingIndex = _synchronizer.GetCurrentLineIndex(_songPositionWithOffset.TotalMilliseconds, _renderLyricsLines);
+ bool isPrimaryPlayingLineChanged = primaryPlayingIndex != _primaryPlayingLineIndex;
+ _primaryPlayingLineIndex = primaryPlayingIndex;
#endregion
#region UpdateTargetScrollOffset
- if (isPlayingLineChanged || _isLayoutChanged)
+ if (isPrimaryPlayingLineChanged || _isLayoutChanged)
{
- var targetScroll = LyricsLayoutManager.CalculateTargetScrollOffset(_renderLyricsLines, _playingLineIndex);
+ var targetScroll = LyricsLayoutManager.CalculateTargetScrollOffset(_renderLyricsLines, _primaryPlayingLineIndex);
if (targetScroll.HasValue) _canvasTargetScrollOffset = targetScroll.Value;
_canvasYScrollTransition.SetEasingType(lyricsEffect.LyricsScrollEasingType);
@@ -524,7 +521,7 @@ namespace BetterLyrics.WinUI3.Controls
_renderLyricsLines,
_isMouseScrolling ? maxRange.Start : _visibleRange.Start,
_isMouseScrolling ? maxRange.End : _visibleRange.End,
- _playingLineIndex,
+ _primaryPlayingLineIndex,
sender.Size.Height,
_canvasTargetScrollOffset,
lyricsStyle.PlayingLineTopOffset / 100.0,
@@ -536,7 +533,7 @@ namespace BetterLyrics.WinUI3.Controls
elapsedTime,
_isMouseScrolling,
_isLayoutChanged,
- isPlayingLineChanged,
+ isPrimaryPlayingLineChanged,
_isMouseScrollingChanged,
_songPositionWithOffset.TotalMilliseconds
);
@@ -669,15 +666,7 @@ namespace BetterLyrics.WinUI3.Controls
private void UpdateRenderLyricsLines()
{
_renderLyricsLines = null;
- var lines = _gsmtcService.CurrentLyricsData?.LyricsLines.Select(x => new RenderLyricsLine()
- {
- LyricsSyllables = x.LyricsSyllables,
- StartMs = x.StartMs,
- EndMs = x.EndMs,
- PhoneticText = x.PhoneticText,
- OriginalText = x.OriginalText,
- TranslatedText = x.TranslatedText
- }).ToList();
+ var lines = _gsmtcService.CurrentLyricsData?.LyricsLines.Select(x => new RenderLyricsLine(x)).ToList();
if (lines != null)
{
LyricsLayoutManager.CalculateLanes(lines);
diff --git a/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Controls/LyricsEffectSettingsControl.xaml b/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Controls/LyricsEffectSettingsControl.xaml
index 934af03..6883d36 100644
--- a/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Controls/LyricsEffectSettingsControl.xaml
+++ b/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Controls/LyricsEffectSettingsControl.xaml
@@ -108,6 +108,14 @@
Minimum="0"
Value="{x:Bind LyricsEffectSettings.LyricsFloatAnimationAmount, Mode=TwoWay}" />
+
+
+
diff --git a/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Controls/LyricsSearchControl.xaml b/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Controls/LyricsSearchControl.xaml
index f4f44b1..5dc2acd 100644
--- a/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Controls/LyricsSearchControl.xaml
+++ b/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Controls/LyricsSearchControl.xaml
@@ -291,7 +291,7 @@
-
+
diff --git a/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Controls/NowPlayingBar.xaml b/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Controls/NowPlayingBar.xaml
index 0fe8a6b..86c3b40 100644
--- a/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Controls/NowPlayingBar.xaml
+++ b/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Controls/NowPlayingBar.xaml
@@ -447,7 +447,7 @@
Foreground="{ThemeResource TextFillColorSecondaryBrush}"
Text="{x:Bind ViewModel.TimelineSliderThumbLyricsLine.StartMs, Converter={StaticResource MillisecondsToFormattedTimeConverter}, Mode=OneWay}" />
-
+
+
+
+
diff --git a/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Extensions/LyricsDataExtensions.cs b/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Extensions/LyricsDataExtensions.cs
index 011748b..c5793c9 100644
--- a/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Extensions/LyricsDataExtensions.cs
+++ b/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Extensions/LyricsDataExtensions.cs
@@ -19,7 +19,7 @@ namespace BetterLyrics.WinUI3.Extensions
{
StartMs = 0,
EndMs = (int)TimeSpan.FromMinutes(99).TotalMilliseconds,
- OriginalText = "● ● ●",
+ PrimaryText = "● ● ●",
},
],
LanguageCode = "N/A",
@@ -37,12 +37,12 @@ namespace BetterLyrics.WinUI3.Extensions
if (transLine != null)
{
// 此处 transLine.OriginalText 指翻译中的“原文”属性
- line.TranslatedText = transLine.OriginalText;
+ line.SecondaryText = transLine.PrimaryText;
}
else
{
// 没有匹配的翻译
- line.TranslatedText = "";
+ line.SecondaryText = "";
}
}
}
@@ -58,12 +58,12 @@ namespace BetterLyrics.WinUI3.Extensions
if (transLine != null)
{
// 此处 transLine.OriginalText 指音译中的“原文”属性
- line.PhoneticText = transLine.OriginalText;
+ line.TertiaryText = transLine.PrimaryText;
}
else
{
// 没有匹配的音译
- line.PhoneticText = "";
+ line.TertiaryText = "";
}
}
}
@@ -76,11 +76,11 @@ namespace BetterLyrics.WinUI3.Extensions
{
if (i >= translationArr.Count)
{
- line.TranslatedText = ""; // No translation available, keep empty
+ line.SecondaryText = ""; // No translation available, keep empty
}
else
{
- line.TranslatedText = translationArr[i];
+ line.SecondaryText = translationArr[i];
}
i++;
}
@@ -94,11 +94,11 @@ namespace BetterLyrics.WinUI3.Extensions
{
if (i >= transliterationArr.Count)
{
- line.PhoneticText = ""; // No transliteration available, keep empty
+ line.TertiaryText = ""; // No transliteration available, keep empty
}
else
{
- line.PhoneticText = transliterationArr[i];
+ line.TertiaryText = transliterationArr[i];
}
i++;
}
diff --git a/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Helper/MetadataComparer.cs b/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Helper/MetadataComparer.cs
index 1374c0f..3d5b343 100644
--- a/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Helper/MetadataComparer.cs
+++ b/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Helper/MetadataComparer.cs
@@ -1,4 +1,5 @@
using BetterLyrics.WinUI3.Models;
+using BetterLyrics.WinUI3.Models.Entities;
using F23.StringSimilarity;
using System;
using System.IO;
@@ -17,21 +18,31 @@ namespace BetterLyrics.WinUI3.Helper
// JaroWinkler 适合短字符串匹配
private static readonly JaroWinkler _algo = new();
- public static int CalculateScore(SongInfo local, LyricsCacheItem remote)
+ public static int CalculateScore(SongInfo songInfo, LyricsCacheItem remote)
{
- if (local == null || remote == null) return 0;
+ return CalculateScore(songInfo, remote.Title, remote.Artist, remote.Album, remote.Duration * 1000);
+ }
+ public static int CalculateScore(SongInfo songInfo, FilesIndexItem local)
+ {
+ return CalculateScore(songInfo, local.Title, local.Artist, local.Album, local.Duration * 1000, local.FileName);
+ }
+
+ public static int CalculateScore(
+ SongInfo songInfo,
+ string? compareTitle, string? compareArtist, string? compareAlbum, double? compareDurationMs, string? compareFileName = null)
+ {
double totalScore = 0;
- bool localHasMetadata = !string.IsNullOrWhiteSpace(local.Title);
- bool remoteHasMetadata = !string.IsNullOrWhiteSpace(remote.Title);
+ bool localHasMetadata = !string.IsNullOrWhiteSpace(songInfo.Title);
+ bool remoteHasMetadata = !string.IsNullOrWhiteSpace(compareTitle);
if (localHasMetadata && remoteHasMetadata)
{
- double titleScore = GetStringSimilarity(local.Title, remote.Title);
- double artistScore = GetStringSimilarity(local.Artist, remote.Artist);
- double albumScore = GetStringSimilarity(local.Album, remote.Album);
- double durationScore = GetDurationSimilarity(local.DurationMs, remote.Duration);
+ double titleScore = GetStringSimilarity(songInfo.Title, compareTitle);
+ double artistScore = GetStringSimilarity(songInfo.Artist, compareArtist);
+ double albumScore = GetStringSimilarity(songInfo.Album, compareAlbum);
+ double durationScore = GetDurationSimilarity(songInfo.DurationMs, compareDurationMs);
totalScore = (titleScore * WeightTitle) +
(artistScore * WeightArtist) +
@@ -41,12 +52,12 @@ namespace BetterLyrics.WinUI3.Helper
else
{
string? localQuery = localHasMetadata
- ? $"{local.Title} {local.Artist}"
- : Path.GetFileNameWithoutExtension(local.LinkedFileName);
+ ? $"{songInfo.Title} {songInfo.Artist}"
+ : Path.GetFileNameWithoutExtension(songInfo.LinkedFileName);
string? remoteQuery = remoteHasMetadata
- ? $"{remote.Title} {remote.Artist}"
- : null;
+ ? $"{compareTitle} {compareArtist}"
+ : Path.GetFileNameWithoutExtension(compareFileName);
string fp1 = CreateSortedFingerprint(localQuery);
string fp2 = CreateSortedFingerprint(remoteQuery);
diff --git a/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Helper/ValueTransition.cs b/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Helper/ValueTransition.cs
index a3e6f2f..452395b 100644
--- a/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Helper/ValueTransition.cs
+++ b/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Helper/ValueTransition.cs
@@ -64,6 +64,16 @@ namespace BetterLyrics.WinUI3.Helper
_durationSeconds = seconds;
}
+ public void SetDurationMs(double millionSeconds)
+ {
+ SetDuration(millionSeconds / 1000.0);
+ }
+
+ public void SetDuration(TimeSpan timeSpan)
+ {
+ SetDuration(timeSpan.TotalSeconds);
+ }
+
public void SetDelay(double seconds)
{
_delaySeconds = seconds;
diff --git a/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Logic/LyricsAnimator.cs b/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Logic/LyricsAnimator.cs
index ec8937e..7da6224 100644
--- a/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Logic/LyricsAnimator.cs
+++ b/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Logic/LyricsAnimator.cs
@@ -1,4 +1,5 @@
-using BetterLyrics.WinUI3.Helper;
+using BetterLyrics.WinUI3.Constants;
+using BetterLyrics.WinUI3.Helper;
using BetterLyrics.WinUI3.Models.Lyrics;
using BetterLyrics.WinUI3.Models.Settings;
using DevWinUI;
@@ -49,15 +50,15 @@ namespace BetterLyrics.WinUI3.Logic
var line = lines.ElementAtOrDefault(i);
if (line == null) continue;
- bool isSecondaryLinePlaying = line.StartMs <= currentPositionMs && currentPositionMs <= line.EndMs;
- if (i == primaryPlayingLineIndex) isSecondaryLinePlaying = true;
+ bool isSecondaryLinePlaying = line.GetIsPlaying(currentPositionMs);
bool isSecondaryLinePlayingChanged = line.IsPlayingLastFrame != isSecondaryLinePlaying;
line.IsPlayingLastFrame = isSecondaryLinePlaying;
+ // 行动画
if (isLayoutChanged || isPrimaryPlayingLineChanged || isMouseScrollingChanged || isSecondaryLinePlayingChanged)
{
int lineCountDelta = i - primaryPlayingLineIndex;
- double distanceFromPlayingLine = Math.Abs(line.OriginalPosition.Y - currentPlayingLine.OriginalPosition.Y);
+ double distanceFromPlayingLine = Math.Abs(line.PrimaryPosition.Y - currentPlayingLine.PrimaryPosition.Y);
double distanceFactor;
if (lineCountDelta < 0)
@@ -151,93 +152,115 @@ namespace BetterLyrics.WinUI3.Logic
line.YOffsetTransition.StartTransition(targetYScrollOffset);
}
- if (line.RenderLyricsOriginalChars != null)
+ var maxAnimationDurationMs = Math.Max(line.EndMs - currentPositionMs, 0);
+
+ // 字符动画
+ foreach (var renderChar in line.PrimaryRenderChars)
{
- foreach (var renderChar in line.RenderLyricsOriginalChars)
+ renderChar.ProgressPlayed = renderChar.GetPlayProgress(currentPositionMs);
+
+ bool isCharPlaying = renderChar.GetIsPlaying(currentPositionMs);
+ bool isCharPlayingChanged = renderChar.IsPlayingLastFrame != isCharPlaying;
+
+ if (isSecondaryLinePlayingChanged || isCharPlayingChanged)
{
- var syllable = line.LyricsSyllables.FirstOrDefault(x => x.StartIndex <= renderChar.Index && renderChar.Index <= x.EndIndex);
- if (syllable == null) continue;
-
- var avgCharDuration = syllable.DurationMs / syllable.Length;
- if (avgCharDuration == null || avgCharDuration == 0) continue;
-
- var charStartMs = syllable.StartMs + (renderChar.Index - syllable.StartIndex) * avgCharDuration.Value;
- var charEndMs = charStartMs + avgCharDuration;
- var progressPlayed = (currentPositionMs - charStartMs) / avgCharDuration.Value;
- progressPlayed = Math.Clamp(progressPlayed, 0, 1);
- renderChar.ProgressPlayed = progressPlayed;
-
- bool isCharPlaying = charStartMs <= currentPositionMs && currentPositionMs <= charEndMs;
- bool isCharPlayingChanged = renderChar.IsPlayingLastFrame != isCharPlaying;
-
- if (isSecondaryLinePlayingChanged || isCharPlayingChanged)
+ if (lyricsEffect.IsLyricsGlowEffectEnabled)
{
- if (lyricsEffect.IsLyricsScaleEffectEnabled)
+ double targetGlow = lyricsEffect.IsLyricsGlowEffectAmountAutoAdjust ? renderChar.LayoutRect.Height * 0.2 : lyricsEffect.LyricsGlowEffectAmount;
+ switch (lyricsEffect.LyricsGlowEffectScope)
{
- double targetScale =
- lyricsEffect.IsLyricsScaleEffectAmountAutoAdjust ? 1.15 : lyricsEffect.LyricsScaleEffectAmount / 100.0;
-
- if (isCharPlayingChanged)
- {
- if (syllable.DurationMs >= lyricsEffect.LyricsScaleEffectLongSyllableDuration)
+ case Enums.LyricsEffectScope.LineStartToCurrentChar:
+ if (isSecondaryLinePlayingChanged)
{
- renderChar.ScaleTransition.SetDuration((syllable.DurationMs ?? 0) / 1000.0 / 2);
- renderChar.ScaleTransition.StartTransition(isCharPlaying ? targetScale : 1);
+ renderChar.GlowTransition.SetDurationMs(Math.Min(Time.AnimationDuration.TotalMilliseconds, maxAnimationDurationMs));
+ renderChar.GlowTransition.StartTransition(isSecondaryLinePlaying ? targetGlow : 0);
}
- }
+ break;
+ default:
+ break;
}
-
- if (lyricsEffect.IsLyricsGlowEffectEnabled)
- {
- double targetGlow = lyricsEffect.IsLyricsGlowEffectAmountAutoAdjust ? renderChar.LayoutRect.Height * 0.2 : lyricsEffect.LyricsGlowEffectAmount;
- switch (lyricsEffect.LyricsGlowEffectScope)
- {
- case Enums.LyricsEffectScope.LongDurationSyllable:
- if (isCharPlayingChanged)
- {
- if (syllable.DurationMs >= lyricsEffect.LyricsGlowEffectLongSyllableDuration)
- {
- renderChar.GlowTransition.SetDuration((syllable.DurationMs ?? 0) / 1000.0 / 2);
- renderChar.GlowTransition.StartTransition(isCharPlaying ? targetGlow : 0);
- }
- }
- break;
- case Enums.LyricsEffectScope.LineStartToCurrentChar:
- if (isSecondaryLinePlayingChanged)
- {
- renderChar.GlowTransition.SetDuration(renderChar.AnimationDuration);
- renderChar.GlowTransition.StartTransition(isSecondaryLinePlaying ? targetGlow : 0);
- }
- break;
- default:
- break;
- }
- }
-
- if (lyricsEffect.IsLyricsFloatAnimationEnabled)
- {
- double targetFloat =
- lyricsEffect.IsLyricsFloatAnimationAmountAutoAdjust ? renderChar.LayoutRect.Height * 0.1 : lyricsEffect.LyricsFloatAnimationAmount;
-
- if (isSecondaryLinePlayingChanged)
- {
- renderChar.FloatTransition.StartTransition(isSecondaryLinePlaying ? targetFloat : 0);
- }
- if (isCharPlayingChanged)
- {
- renderChar.FloatTransition.StartTransition(0);
- }
- }
-
- renderChar.IsPlayingLastFrame = isCharPlaying;
}
- renderChar.ScaleTransition.Update(elapsedTime);
- renderChar.GlowTransition.Update(elapsedTime);
- renderChar.FloatTransition.Update(elapsedTime);
+ if (lyricsEffect.IsLyricsFloatAnimationEnabled)
+ {
+ double targetFloat =
+ lyricsEffect.IsLyricsFloatAnimationAmountAutoAdjust ? renderChar.LayoutRect.Height * 0.1 : lyricsEffect.LyricsFloatAnimationAmount;
+
+ if (isSecondaryLinePlayingChanged)
+ {
+ renderChar.FloatTransition.StartTransition(isSecondaryLinePlaying ? targetFloat : 0);
+ }
+ if (isCharPlayingChanged)
+ {
+ renderChar.FloatTransition.SetDurationMs(Math.Min(lyricsEffect.LyricsFloatAnimationDuration, maxAnimationDurationMs));
+ renderChar.FloatTransition.StartTransition(0);
+ }
+ }
+
+ if (isCharPlayingChanged)
+ {
+ renderChar.IsPlayingLastFrame = isCharPlaying;
+ }
}
}
+ // 音节动画
+ foreach (var syllable in line.PrimaryRenderSyllables)
+ {
+ bool isSyllablePlaying = syllable.GetIsPlaying(currentPositionMs);
+ bool isSyllablePlayingChanged = syllable.IsPlayingLastFrame != isSyllablePlaying;
+
+ if (isSyllablePlayingChanged)
+ {
+ var syllableHeight = syllable.ChildrenRenderLyricsChars.FirstOrDefault()?.LayoutRect.Height ?? 0;
+
+ if (lyricsEffect.IsLyricsScaleEffectEnabled)
+ {
+ double targetScale =
+ lyricsEffect.IsLyricsScaleEffectAmountAutoAdjust ? 1.15 : lyricsEffect.LyricsScaleEffectAmount / 100.0;
+
+ foreach (var renderChar in syllable.ChildrenRenderLyricsChars)
+ {
+ if (syllable.DurationMs >= lyricsEffect.LyricsScaleEffectLongSyllableDuration)
+ {
+ renderChar.ScaleTransition.SetDurationMs(Math.Min(syllable.DurationMs, maxAnimationDurationMs) / 2.0);
+ renderChar.ScaleTransition.StartTransition(isSyllablePlaying ? targetScale : 1);
+ }
+ }
+ }
+
+ if (lyricsEffect.IsLyricsGlowEffectEnabled)
+ {
+ double targetGlow = lyricsEffect.IsLyricsGlowEffectAmountAutoAdjust ? syllableHeight * 0.2 : lyricsEffect.LyricsGlowEffectAmount;
+ switch (lyricsEffect.LyricsGlowEffectScope)
+ {
+ case Enums.LyricsEffectScope.LongDurationSyllable:
+ if (syllable.DurationMs >= lyricsEffect.LyricsGlowEffectLongSyllableDuration)
+ {
+ foreach (var renderChar in syllable.ChildrenRenderLyricsChars)
+ {
+ renderChar.GlowTransition.SetDurationMs(Math.Min(syllable.DurationMs, maxAnimationDurationMs) / 2.0);
+ renderChar.GlowTransition.StartTransition(isSyllablePlaying ? targetGlow : 0);
+ }
+ }
+ break;
+ default:
+ break;
+ }
+ }
+
+ syllable.IsPlayingLastFrame = isSyllablePlaying;
+ }
+ }
+
+ // 更新动画
+ foreach (var renderChar in line.PrimaryRenderChars)
+ {
+ renderChar.ScaleTransition.Update(elapsedTime);
+ renderChar.GlowTransition.Update(elapsedTime);
+ renderChar.FloatTransition.Update(elapsedTime);
+ }
+
line.AngleTransition.Update(elapsedTime);
line.ScaleTransition.Update(elapsedTime);
line.BlurAmountTransition.Update(elapsedTime);
diff --git a/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Logic/LyricsLayoutManager.cs b/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Logic/LyricsLayoutManager.cs
index 3c8e342..786778d 100644
--- a/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Logic/LyricsLayoutManager.cs
+++ b/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Logic/LyricsLayoutManager.cs
@@ -79,52 +79,52 @@ namespace BetterLyrics.WinUI3.Logic
// 左上角坐标
line.TopLeftPosition = new Vector2(0, (float)currentY);
// 注音层
- line.PhoneticPosition = line.TopLeftPosition;
- if (line.PhoneticCanvasTextLayout != null)
+ line.TertiaryPosition = line.TopLeftPosition;
+ if (line.TertiaryTextLayout != null)
{
- currentY += line.PhoneticCanvasTextLayout.LayoutBounds.Height;
+ currentY += line.TertiaryTextLayout.LayoutBounds.Height;
// 间距
- currentY += (line.PhoneticCanvasTextLayout.LayoutBounds.Height / line.PhoneticCanvasTextLayout.LineCount) * 0.1;
+ currentY += (line.TertiaryTextLayout.LayoutBounds.Height / line.TertiaryTextLayout.LineCount) * 0.1;
- actualWidth = Math.Max(actualWidth, line.PhoneticCanvasTextLayout.LayoutBounds.Width);
+ actualWidth = Math.Max(actualWidth, line.TertiaryTextLayout.LayoutBounds.Width);
}
// 原文层
- line.OriginalPosition = new Vector2(0, (float)currentY);
- if (line.OriginalCanvasTextLayout != null)
+ line.PrimaryPosition = new Vector2(0, (float)currentY);
+ if (line.PrimaryTextLayout != null)
{
- currentY += line.OriginalCanvasTextLayout.LayoutBounds.Height;
+ currentY += line.PrimaryTextLayout.LayoutBounds.Height;
- actualWidth = Math.Max(actualWidth, line.OriginalCanvasTextLayout.LayoutBounds.Width);
+ actualWidth = Math.Max(actualWidth, line.PrimaryTextLayout.LayoutBounds.Width);
}
// 翻译层
- if (line.TranslatedCanvasTextLayout != null)
+ if (line.SecondaryTextLayout != null)
{
// 间距
- currentY += (line.TranslatedCanvasTextLayout.LayoutBounds.Height / line.TranslatedCanvasTextLayout.LineCount) * 0.1;
+ currentY += (line.SecondaryTextLayout.LayoutBounds.Height / line.SecondaryTextLayout.LineCount) * 0.1;
}
- line.TranslatedPosition = new Vector2(0, (float)currentY);
- if (line.TranslatedCanvasTextLayout != null)
+ line.SecondaryPosition = new Vector2(0, (float)currentY);
+ if (line.SecondaryTextLayout != null)
{
- currentY += line.TranslatedCanvasTextLayout.LayoutBounds.Height;
+ currentY += line.SecondaryTextLayout.LayoutBounds.Height;
- actualWidth = Math.Max(actualWidth, line.TranslatedCanvasTextLayout.LayoutBounds.Width);
+ actualWidth = Math.Max(actualWidth, line.SecondaryTextLayout.LayoutBounds.Width);
}
// 右下角坐标
line.BottomRightPosition = new Vector2(0 + (float)actualWidth, (float)currentY);
// 行间距
- if (line.OriginalCanvasTextLayout != null)
+ if (line.PrimaryTextLayout != null)
{
- currentY += (line.OriginalCanvasTextLayout.LayoutBounds.Height / line.OriginalCanvasTextLayout.LineCount) * style.LyricsLineSpacingFactor;
+ currentY += (line.PrimaryTextLayout.LayoutBounds.Height / line.PrimaryTextLayout.LineCount) * style.LyricsLineSpacingFactor;
}
// 更新中心点
line.UpdateCenterPosition(lyricsWidth, style.LyricsAlignmentType);
- line.RecalculateCharacterGeometries();
+ line.RecreateRenderChars();
}
}
@@ -140,9 +140,9 @@ namespace BetterLyrics.WinUI3.Logic
var currentLine = lines.ElementAtOrDefault(playingLineIndex);
var firstLine = lines.FirstOrDefault();
- if (currentLine?.OriginalCanvasTextLayout == null || firstLine == null) return null;
+ if (currentLine?.PrimaryTextLayout == null || firstLine == null) return null;
- return -currentLine.OriginalPosition.Y + firstLine.OriginalPosition.Y
+ return -currentLine.PrimaryPosition.Y + firstLine.PrimaryPosition.Y
- (currentLine.BottomRightPosition.Y - currentLine.TopLeftPosition.Y) / 2.0;
}
@@ -215,7 +215,7 @@ namespace BetterLyrics.WinUI3.Logic
lanesEndMs.Add(0);
}
- lanesEndMs[assignedLane] = end ?? 0;
+ lanesEndMs[assignedLane] = end;
line.LaneIndex = assignedLane;
}
}
@@ -241,7 +241,7 @@ namespace BetterLyrics.WinUI3.Logic
{
int mid = (left + right) / 2;
var line = lines[mid];
- if (line.OriginalCanvasTextLayout == null) break;
+ if (line.PrimaryTextLayout == null) break;
double value = offset + line.BottomRightPosition.Y;
if (value >= mousePosition.Y) { result = mid; right = mid - 1; }
else { left = mid + 1; }
@@ -267,7 +267,7 @@ namespace BetterLyrics.WinUI3.Logic
{
int mid = (left + right) / 2;
var line = lines[mid];
- if (line.OriginalCanvasTextLayout == null) break;
+ if (line.PrimaryTextLayout == null) break;
double value = offset + line.BottomRightPosition.Y;
// 理论上说应该使用下面这一行来精确计算视野内的首个可见行,但是考虑到动画视觉效果,还是注释掉了
//if (value >= lyricsY) { result = mid; right = mid - 1; }
@@ -284,7 +284,7 @@ namespace BetterLyrics.WinUI3.Logic
{
int mid = (left + right) / 2;
var line = lines[mid];
- if (line.OriginalCanvasTextLayout == null) break;
+ if (line.PrimaryTextLayout == null) break;
double value = offset + line.BottomRightPosition.Y;
// 同理
//if (value >= lyricsY + lyricsHeight) { result = mid; right = mid - 1; }
diff --git a/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Logic/LyricsSynchronizer.cs b/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Logic/LyricsSynchronizer.cs
index 3fb0cec..2b05cce 100644
--- a/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Logic/LyricsSynchronizer.cs
+++ b/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Logic/LyricsSynchronizer.cs
@@ -66,19 +66,14 @@ namespace BetterLyrics.WinUI3.Logic
public LinePlaybackState GetLinePlayingProgress(
double currentTimeMs,
- LyricsLine line,
- LyricsLine? nextLine,
- double songDurationMs,
+ RenderLyricsLine line,
bool isForceWordByWord)
{
var state = new LinePlaybackState { SyllableStartIndex = 0, SyllableLength = 0, SyllableProgress = 0 };
if (line == null) return state;
- double lineEndMs;
- if (line.EndMs != null) lineEndMs = line.EndMs.Value;
- else if (nextLine != null) lineEndMs = nextLine.StartMs;
- else lineEndMs = songDurationMs;
+ double lineEndMs = line.EndMs;
// 还没到
if (currentTimeMs < line.StartMs) return state;
@@ -87,42 +82,43 @@ namespace BetterLyrics.WinUI3.Logic
if (currentTimeMs > lineEndMs)
{
state.SyllableProgress = 1f;
- state.SyllableStartIndex = Math.Max(0, line.OriginalText.Length - 1);
+ state.SyllableStartIndex = Math.Max(0, line.PrimaryText.Length - 1);
state.SyllableLength = 1;
return state;
}
// 逐字
- if (line.LyricsSyllables != null && line.LyricsSyllables.Count > 1)
+ if (line.PrimaryRenderSyllables != null && line.PrimaryRenderSyllables.Count > 1)
{
return CalculateSyllableProgress(currentTimeMs, line, lineEndMs);
}
// 强制逐字
- if (isForceWordByWord && line.OriginalText.Length > 0)
+ if (isForceWordByWord && line.PrimaryText.Length > 0)
{
return CalculateSimulatedProgress(currentTimeMs, line, lineEndMs);
}
else
{
// 普通行
- state.SyllableStartIndex = line.OriginalText.Length;
+ state.SyllableStartIndex = line.PrimaryText.Length;
state.SyllableProgress = 1f;
return state;
}
}
- private LinePlaybackState CalculateSyllableProgress(double time, LyricsLine line, double lineEndMs)
+ private LinePlaybackState CalculateSyllableProgress(double time, RenderLyricsLine line, double lineEndMs)
{
var state = new LinePlaybackState();
- int count = line.LyricsSyllables.Count;
+ int count = line.PrimaryRenderSyllables.Count;
for (int i = 0; i < count; i++)
{
- var timing = line.LyricsSyllables[i];
- var nextTiming = (i + 1 < count) ? line.LyricsSyllables[i + 1] : null;
+ var timing = line.PrimaryRenderSyllables[i];
+ var nextTiming = (i + 1 < count) ? line.PrimaryRenderSyllables[i + 1] : null;
- double timingEndMs = timing.EndMs ?? nextTiming?.StartMs ?? lineEndMs;
+ //double timingEndMs = timing.EndMs ?? nextTiming?.StartMs ?? lineEndMs;
+ double timingEndMs = timing.EndMs;
// 在当前字范围内
if (time >= timing.StartMs && time <= timingEndMs)
@@ -146,10 +142,10 @@ namespace BetterLyrics.WinUI3.Logic
return state;
}
- private LinePlaybackState CalculateSimulatedProgress(double time, LyricsLine line, double lineEndMs)
+ private LinePlaybackState CalculateSimulatedProgress(double time, RenderLyricsLine line, double lineEndMs)
{
var state = new LinePlaybackState();
- int textLength = line.OriginalText.Length;
+ int textLength = line.PrimaryText.Length;
double progress = (time - line.StartMs) / (lineEndMs - line.StartMs);
progress = Math.Clamp(progress, 0, 1);
diff --git a/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Models/Lyrics/BaseLyrics.cs b/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Models/Lyrics/BaseLyrics.cs
new file mode 100644
index 0000000..fb4be92
--- /dev/null
+++ b/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Models/Lyrics/BaseLyrics.cs
@@ -0,0 +1,20 @@
+using System;
+using System.Collections.Generic;
+using System.Text;
+
+namespace BetterLyrics.WinUI3.Models.Lyrics
+{
+ public class BaseLyrics
+ {
+ public int StartMs { get; set; }
+ public int EndMs { get; set; }
+ public int DurationMs => EndMs - StartMs;
+
+ public string Text { get; set; } = "";
+ public int Length => Text.Length;
+
+ public int StartIndex { get; set; }
+ public int EndIndex => StartIndex + Length - 1;
+
+ }
+}
diff --git a/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Models/Lyrics/BaseRenderLyrics.cs b/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Models/Lyrics/BaseRenderLyrics.cs
new file mode 100644
index 0000000..385d370
--- /dev/null
+++ b/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Models/Lyrics/BaseRenderLyrics.cs
@@ -0,0 +1,22 @@
+using System;
+using System.Collections.Generic;
+using System.Text;
+
+namespace BetterLyrics.WinUI3.Models.Lyrics
+{
+ public class BaseRenderLyrics : BaseLyrics
+ {
+ public bool IsPlayingLastFrame { get; set; } = false;
+
+ public BaseRenderLyrics(BaseLyrics baseLyrics)
+ {
+ this.Text = baseLyrics.Text;
+ this.StartMs = baseLyrics.StartMs;
+ this.EndMs = baseLyrics.EndMs;
+ this.StartIndex = baseLyrics.StartIndex;
+ }
+
+ public bool GetIsPlaying(double currentMs) => this.StartMs <= currentMs && currentMs < this.EndMs;
+ public double GetPlayProgress(double currentMs) => Math.Clamp((currentMs - this.StartMs) / this.DurationMs, 0, 1);
+ }
+}
diff --git a/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Models/Lyrics/LyricsChar.cs b/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Models/Lyrics/LyricsChar.cs
deleted file mode 100644
index d622c88..0000000
--- a/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Models/Lyrics/LyricsChar.cs
+++ /dev/null
@@ -1,12 +0,0 @@
-namespace BetterLyrics.WinUI3.Models.Lyrics
-{
- public class LyricsChar
- {
- public int StartMs { get; set; }
- public int EndMs { get; set; }
- public int DurationMs => EndMs - StartMs;
-
- public string Text { get; set; } = "";
- public int Index { get; set; }
- }
-}
diff --git a/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Models/Lyrics/LyricsData.cs b/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Models/Lyrics/LyricsData.cs
index c9d3fd6..99bfa48 100644
--- a/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Models/Lyrics/LyricsData.cs
+++ b/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Models/Lyrics/LyricsData.cs
@@ -18,7 +18,7 @@ namespace BetterLyrics.WinUI3.Models.Lyrics
set => field = value;
}
public bool AutoGenerated { get; set; } = false;
- public string WrappedOriginalText => string.Join(StringHelper.NewLine, LyricsLines.Select(line => line.OriginalText));
+ public string WrappedOriginalText => string.Join(StringHelper.NewLine, LyricsLines.Select(line => line.PrimaryText));
public LyricsData()
{
@@ -35,7 +35,7 @@ namespace BetterLyrics.WinUI3.Models.Lyrics
{
StartMs = 0,
EndMs = (int)TimeSpan.FromMinutes(99).TotalMilliseconds,
- OriginalText = _localizationService.GetLocalizedString("LyricsNotFound"),
+ PrimaryText = _localizationService.GetLocalizedString("LyricsNotFound"),
}]);
}
diff --git a/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Models/Lyrics/LyricsLine.cs b/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Models/Lyrics/LyricsLine.cs
index ec097d9..bec7696 100644
--- a/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Models/Lyrics/LyricsLine.cs
+++ b/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Models/Lyrics/LyricsLine.cs
@@ -1,29 +1,46 @@
// 2025/6/23 by Zhe Fang
using System.Collections.Generic;
+using System.Linq;
namespace BetterLyrics.WinUI3.Models.Lyrics
{
- public class LyricsLine
+ public class LyricsLine : BaseLyrics
{
- public List LyricsSyllables { get; set; } = [];
+ public List PrimarySyllables { get; set; } = [];
+ public List SecondarySyllables { get; set; } = [];
+ public List TertiarySyllables { get; set; } = [];
- public int? DurationMs => EndMs - StartMs;
- public int? EndMs { get; set; }
- public int StartMs { get; set; }
+ public List PrimaryChars { get; private set; } = [];
+ public List SecondaryChars { get; private set; } = [];
+ public List TertiaryChars { get; private set; } = [];
- ///
- /// 原文
- ///
- public string OriginalText { get; set; } = "";
- ///
- /// 译文
- ///
- public string TranslatedText { get; set; } = "";
- ///
- /// 注音
- ///
- public string PhoneticText { get; set; } = "";
+ public string PrimaryText { get; set; } = "";
+ public string SecondaryText { get; set; } = "";
+ public string TertiaryText { get; set; } = "";
+
+ public LyricsLine()
+ {
+ for (int charStartIndex = 0; charStartIndex < PrimaryText.Length; charStartIndex++)
+ {
+ var syllable = PrimarySyllables.FirstOrDefault(x => x.StartIndex <= charStartIndex && charStartIndex <= x.EndIndex);
+ if (syllable == null) continue;
+
+ var avgCharDuration = syllable.DurationMs / syllable.Length;
+ if (avgCharDuration == 0) continue;
+
+ var charStartMs = syllable.StartMs + (charStartIndex - syllable.StartIndex) * avgCharDuration;
+ var charEndMs = charStartMs + avgCharDuration;
+
+ PrimaryChars.Add(new BaseLyrics
+ {
+ StartIndex = charStartIndex,
+ StartMs = charStartMs,
+ EndMs = charEndMs,
+ Text = PrimaryText[charStartIndex].ToString()
+ });
+ }
+ }
}
}
diff --git a/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Models/Lyrics/LyricsSyllable.cs b/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Models/Lyrics/LyricsSyllable.cs
deleted file mode 100644
index 7bac5e6..0000000
--- a/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Models/Lyrics/LyricsSyllable.cs
+++ /dev/null
@@ -1,19 +0,0 @@
-// 2025/6/23 by Zhe Fang
-
-namespace BetterLyrics.WinUI3.Models.Lyrics
-{
- public class LyricsSyllable
- {
- public string Text { get; set; } = string.Empty;
- public int Length => Text.Length;
-
- public int StartIndex { get; set; }
- public int EndIndex => StartIndex + Length - 1;
-
- public int StartMs { get; set; }
- public int? EndMs { get; set; }
-
- public int? DurationMs => EndMs - StartMs;
- public bool IsLongDuration => DurationMs >= 700;
- }
-}
diff --git a/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Models/Lyrics/RenderLyricsChar.cs b/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Models/Lyrics/RenderLyricsChar.cs
index c961138..c0fa3c4 100644
--- a/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Models/Lyrics/RenderLyricsChar.cs
+++ b/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Models/Lyrics/RenderLyricsChar.cs
@@ -1,14 +1,13 @@
-using BetterLyrics.WinUI3.Enums;
+using BetterLyrics.WinUI3.Constants;
+using BetterLyrics.WinUI3.Enums;
using BetterLyrics.WinUI3.Helper;
using Windows.Foundation;
namespace BetterLyrics.WinUI3.Models.Lyrics
{
- public class RenderLyricsChar : LyricsChar
+ public class RenderLyricsChar : BaseRenderLyrics
{
- public Rect LayoutRect { get; set; }
-
- public double AnimationDuration { get; set; } = 0.3;
+ public Rect LayoutRect { get; private set; }
public ValueTransition ScaleTransition { get; set; }
public ValueTransition GlowTransition { get; set; }
@@ -16,25 +15,24 @@ namespace BetterLyrics.WinUI3.Models.Lyrics
public double ProgressPlayed { get; set; } = 0; // 0~1
- public bool IsPlayingLastFrame { get; set; } = false;
-
- public RenderLyricsChar()
+ public RenderLyricsChar(BaseLyrics lyricsChars, Rect layoutRect) : base(lyricsChars)
{
ScaleTransition = new(
initialValue: 1.0,
- durationSeconds: AnimationDuration,
+ durationSeconds: Time.AnimationDuration.TotalSeconds,
easingType: EasingType.EaseInOutSine
);
GlowTransition = new(
initialValue: 0,
- durationSeconds: AnimationDuration,
+ durationSeconds: Time.AnimationDuration.TotalSeconds,
easingType: EasingType.EaseInOutSine
);
FloatTransition = new(
initialValue: 0,
- durationSeconds: AnimationDuration,
+ durationSeconds: Time.LongAnimationDuration.TotalSeconds,
easingType: EasingType.EaseInOutSine
);
+ LayoutRect = layoutRect;
}
}
}
diff --git a/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Models/Lyrics/RenderLyricsLine.cs b/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Models/Lyrics/RenderLyricsLine.cs
index ba86cc7..210c0d3 100644
--- a/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Models/Lyrics/RenderLyricsLine.cs
+++ b/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Models/Lyrics/RenderLyricsLine.cs
@@ -12,9 +12,10 @@ using Windows.UI;
namespace BetterLyrics.WinUI3.Models.Lyrics
{
- public class RenderLyricsLine : LyricsLine
+ public class RenderLyricsLine : BaseRenderLyrics
{
- public List RenderLyricsOriginalChars { get; set; } = [];
+ public List PrimaryRenderChars { get; private set; } = [];
+ public List PrimaryRenderSyllables { get; private set; }
public double AnimationDuration { get; set; } = 0.3;
@@ -28,22 +29,22 @@ namespace BetterLyrics.WinUI3.Models.Lyrics
public ValueTransition YOffsetTransition { get; set; }
public ValueTransition ColorTransition { get; set; }
- public CanvasTextLayout? OriginalCanvasTextLayout { get; private set; }
- public CanvasTextLayout? TranslatedCanvasTextLayout { get; private set; }
- public CanvasTextLayout? PhoneticCanvasTextLayout { get; private set; }
+ public CanvasTextLayout? PrimaryTextLayout { get; private set; }
+ public CanvasTextLayout? SecondaryTextLayout { get; private set; }
+ public CanvasTextLayout? TertiaryTextLayout { get; private set; }
///
/// 原文坐标(相对于坐标原点)
///
- public Vector2 OriginalPosition { get; set; }
+ public Vector2 PrimaryPosition { get; set; }
///
/// 译文坐标(相对于坐标原点)
///
- public Vector2 TranslatedPosition { get; set; }
+ public Vector2 SecondaryPosition { get; set; }
///
/// 注音坐标(相对于坐标原点)
///
- public Vector2 PhoneticPosition { get; set; }
+ public Vector2 TertiaryPosition { get; set; }
///
/// 顶部坐标(相对于坐标原点)
@@ -58,21 +59,21 @@ namespace BetterLyrics.WinUI3.Models.Lyrics
///
public Vector2 BottomRightPosition { get; set; }
- public CanvasGeometry? OriginalCanvasGeometry { get; private set; }
- public CanvasGeometry? TranslatedCanvasGeometry { get; private set; }
- public CanvasGeometry? PhoneticCanvasGeometry { get; private set; }
+ public CanvasGeometry? PrimaryCanvasGeometry { get; private set; }
+ public CanvasGeometry? SecondaryCanvasGeometry { get; private set; }
+ public CanvasGeometry? TertiaryCanvasGeometry { get; private set; }
+
+ public string PrimaryText { get; set; } = "";
+ public string SecondaryText { get; set; } = "";
+ public string TertiaryText { get; set; } = "";
///
/// 轨道索引 (0 = 主轨道, 1 = 第一副轨道, etc.)
/// 用于布局计算时的堆叠逻辑
///
public int LaneIndex { get; set; } = 0;
- ///
- /// 是否为背景人声/和声
- ///
- public bool IsPlayingLastFrame { get; set; } = false;
- public RenderLyricsLine()
+ public RenderLyricsLine(LyricsLine lyricsLine) : base(lyricsLine)
{
AngleTransition = new(
initialValue: 0,
@@ -119,11 +120,18 @@ namespace BetterLyrics.WinUI3.Models.Lyrics
durationSeconds: 0.3f,
interpolator: (from, to, progress) => Helper.ColorHelper.GetInterpolatedColor(progress, from, to)
);
+
+ StartMs = lyricsLine.StartMs;
+ EndMs = lyricsLine.EndMs;
+ TertiaryText = lyricsLine.TertiaryText;
+ PrimaryText = lyricsLine.PrimaryText;
+ SecondaryText = lyricsLine.SecondaryText;
+ PrimaryRenderSyllables = lyricsLine.PrimarySyllables.Select(x => new RenderLyricsSyllable(x)).ToList();
}
public void UpdateCenterPosition(double maxWidth, TextAlignmentType type)
{
- if (OriginalCanvasTextLayout == null)
+ if (PrimaryTextLayout == null)
{
return;
}
@@ -141,14 +149,14 @@ namespace BetterLyrics.WinUI3.Models.Lyrics
public void DisposeTextLayout()
{
- PhoneticCanvasTextLayout?.Dispose();
- PhoneticCanvasTextLayout = null;
+ TertiaryTextLayout?.Dispose();
+ TertiaryTextLayout = null;
- OriginalCanvasTextLayout?.Dispose();
- OriginalCanvasTextLayout = null;
+ PrimaryTextLayout?.Dispose();
+ PrimaryTextLayout = null;
- TranslatedCanvasTextLayout?.Dispose();
- TranslatedCanvasTextLayout = null;
+ SecondaryTextLayout?.Dispose();
+ SecondaryTextLayout = null;
}
public void RecreateTextLayout(
@@ -161,9 +169,9 @@ namespace BetterLyrics.WinUI3.Models.Lyrics
{
DisposeTextLayout();
- if (createPhonetic && PhoneticText != "")
+ if (createPhonetic && TertiaryText != "")
{
- PhoneticCanvasTextLayout = new CanvasTextLayout(control, PhoneticText, new CanvasTextFormat
+ TertiaryTextLayout = new CanvasTextLayout(control, TertiaryText, new CanvasTextFormat
{
HorizontalAlignment = CanvasHorizontalAlignment.Left,
VerticalAlignment = CanvasVerticalAlignment.Top,
@@ -173,10 +181,10 @@ namespace BetterLyrics.WinUI3.Models.Lyrics
{
HorizontalAlignment = type.ToCanvasHorizontalAlignment(),
};
- PhoneticCanvasTextLayout.SetFontFamily(PhoneticText, fontFamilyCJK, fontFamilyWestern);
+ TertiaryTextLayout.SetFontFamily(TertiaryText, fontFamilyCJK, fontFamilyWestern);
}
- OriginalCanvasTextLayout = new CanvasTextLayout(control, OriginalText, new CanvasTextFormat
+ PrimaryTextLayout = new CanvasTextLayout(control, PrimaryText, new CanvasTextFormat
{
HorizontalAlignment = CanvasHorizontalAlignment.Left,
VerticalAlignment = CanvasVerticalAlignment.Top,
@@ -186,11 +194,11 @@ namespace BetterLyrics.WinUI3.Models.Lyrics
{
HorizontalAlignment = type.ToCanvasHorizontalAlignment()
};
- OriginalCanvasTextLayout.SetFontFamily(OriginalText, fontFamilyCJK, fontFamilyWestern);
+ PrimaryTextLayout.SetFontFamily(PrimaryText, fontFamilyCJK, fontFamilyWestern);
- if (createTranslated && TranslatedText != "")
+ if (createTranslated && SecondaryText != "")
{
- TranslatedCanvasTextLayout = new CanvasTextLayout(control, TranslatedText, new CanvasTextFormat
+ SecondaryTextLayout = new CanvasTextLayout(control, SecondaryText, new CanvasTextFormat
{
HorizontalAlignment = CanvasHorizontalAlignment.Left,
VerticalAlignment = CanvasVerticalAlignment.Top,
@@ -200,60 +208,77 @@ namespace BetterLyrics.WinUI3.Models.Lyrics
{
HorizontalAlignment = type.ToCanvasHorizontalAlignment()
};
- TranslatedCanvasTextLayout.SetFontFamily(TranslatedText, fontFamilyCJK, fontFamilyWestern);
+ SecondaryTextLayout.SetFontFamily(SecondaryText, fontFamilyCJK, fontFamilyWestern);
}
}
public void DisposeTextGeometry()
{
- PhoneticCanvasGeometry?.Dispose();
- PhoneticCanvasGeometry = null;
+ TertiaryCanvasGeometry?.Dispose();
+ TertiaryCanvasGeometry = null;
- OriginalCanvasGeometry?.Dispose();
- OriginalCanvasGeometry = null;
+ PrimaryCanvasGeometry?.Dispose();
+ PrimaryCanvasGeometry = null;
- TranslatedCanvasGeometry?.Dispose();
- TranslatedCanvasGeometry = null;
+ SecondaryCanvasGeometry?.Dispose();
+ SecondaryCanvasGeometry = null;
}
public void RecreateTextGeometry()
{
DisposeTextGeometry();
- if (PhoneticCanvasTextLayout != null)
+ if (TertiaryTextLayout != null)
{
- PhoneticCanvasGeometry = CanvasGeometry.CreateText(PhoneticCanvasTextLayout);
+ TertiaryCanvasGeometry = CanvasGeometry.CreateText(TertiaryTextLayout);
}
- if (OriginalCanvasTextLayout != null)
+ if (PrimaryTextLayout != null)
{
- OriginalCanvasGeometry = CanvasGeometry.CreateText(OriginalCanvasTextLayout);
+ PrimaryCanvasGeometry = CanvasGeometry.CreateText(PrimaryTextLayout);
}
- if (TranslatedCanvasTextLayout != null)
+ if (SecondaryTextLayout != null)
{
- TranslatedCanvasGeometry = CanvasGeometry.CreateText(TranslatedCanvasTextLayout);
+ SecondaryCanvasGeometry = CanvasGeometry.CreateText(SecondaryTextLayout);
}
}
- public void RecalculateCharacterGeometries()
+ public void RecreateRenderChars()
{
- RenderLyricsOriginalChars.Clear();
- if (OriginalCanvasTextLayout == null) return;
+ PrimaryRenderChars.Clear();
+ if (PrimaryTextLayout == null) return;
- var textLength = OriginalText.Length;
-
- for (int i = 0; i < textLength; i++)
+ foreach (var syllable in PrimaryRenderSyllables)
{
- var region = OriginalCanvasTextLayout.GetCharacterRegions(i, 1).FirstOrDefault();
+ syllable.ChildrenRenderLyricsChars.Clear();
+ }
+
+ var textLength = PrimaryText.Length;
+
+ for (int startCharIndex = 0; startCharIndex < textLength; startCharIndex++)
+ {
+ var region = PrimaryTextLayout.GetCharacterRegions(startCharIndex, 1).FirstOrDefault();
var bounds = region.LayoutBounds;
- RenderLyricsOriginalChars.Add(new RenderLyricsChar()
+ var syllable = PrimaryRenderSyllables.FirstOrDefault(x => x.StartIndex <= startCharIndex && startCharIndex <= x.EndIndex);
+ if (syllable == null) continue;
+
+ var avgCharDuration = syllable.DurationMs / syllable.Length;
+ var charStartMs = syllable.StartMs + (startCharIndex - syllable.StartIndex) * avgCharDuration;
+ var charEndMs = charStartMs + avgCharDuration;
+
+ var renderLyricsChar = new RenderLyricsChar(new BaseLyrics
{
- Index = i,
- LayoutRect = bounds,
- Text = OriginalText[i].ToString()
- });
+ StartIndex = startCharIndex,
+ Text = PrimaryText[startCharIndex].ToString(),
+ StartMs = charStartMs,
+ EndMs = charEndMs,
+ }, bounds);
+
+ syllable.ChildrenRenderLyricsChars.Add(renderLyricsChar);
+
+ PrimaryRenderChars.Add(renderLyricsChar);
}
}
diff --git a/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Models/Lyrics/RenderLyricsSyllable.cs b/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Models/Lyrics/RenderLyricsSyllable.cs
new file mode 100644
index 0000000..479df8f
--- /dev/null
+++ b/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Models/Lyrics/RenderLyricsSyllable.cs
@@ -0,0 +1,13 @@
+using System;
+using System.Collections.Generic;
+using System.Text;
+
+namespace BetterLyrics.WinUI3.Models.Lyrics
+{
+ public class RenderLyricsSyllable : BaseRenderLyrics
+ {
+ public List ChildrenRenderLyricsChars { get; set; } = [];
+
+ public RenderLyricsSyllable(BaseLyrics lyricsSyllable) : base(lyricsSyllable) { }
+ }
+}
diff --git a/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Models/Settings/LyricsEffectSettings.cs b/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Models/Settings/LyricsEffectSettings.cs
index fbaceee..5be05ce 100644
--- a/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Models/Settings/LyricsEffectSettings.cs
+++ b/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Models/Settings/LyricsEffectSettings.cs
@@ -24,6 +24,7 @@ namespace BetterLyrics.WinUI3.Models.Settings
[ObservableProperty][NotifyPropertyChangedRecipients] public partial bool IsLyricsFloatAnimationEnabled { get; set; } = true;
[ObservableProperty][NotifyPropertyChangedRecipients] public partial bool IsLyricsFloatAnimationAmountAutoAdjust { get; set; } = true;
[ObservableProperty][NotifyPropertyChangedRecipients] public partial int LyricsFloatAnimationAmount { get; set; } = 8;
+ [ObservableProperty][NotifyPropertyChangedRecipients] public partial int LyricsFloatAnimationDuration { get; set; } = 450; // 450ms
[ObservableProperty][NotifyPropertyChangedRecipients] public partial EasingType LyricsScrollEasingType { get; set; }
[ObservableProperty][NotifyPropertyChangedRecipients] public partial int LyricsScrollDuration { get; set; }
@@ -71,6 +72,7 @@ namespace BetterLyrics.WinUI3.Models.Settings
IsLyricsFloatAnimationEnabled = this.IsLyricsFloatAnimationEnabled,
IsLyricsFloatAnimationAmountAutoAdjust = this.IsLyricsFloatAnimationAmountAutoAdjust,
LyricsFloatAnimationAmount = this.LyricsFloatAnimationAmount,
+ LyricsFloatAnimationDuration = this.LyricsFloatAnimationDuration,
LyricsScrollEasingType = this.LyricsScrollEasingType,
LyricsScrollDuration = this.LyricsScrollDuration,
diff --git a/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Models/Settings/LyricsSearchProviderInfo.cs b/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Models/Settings/LyricsSearchProviderInfo.cs
index f642239..95ef27f 100644
--- a/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Models/Settings/LyricsSearchProviderInfo.cs
+++ b/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Models/Settings/LyricsSearchProviderInfo.cs
@@ -11,6 +11,7 @@ namespace BetterLyrics.WinUI3.Models.Settings
[ObservableProperty][NotifyPropertyChangedRecipients] public partial LyricsSearchProvider Provider { get; set; }
[ObservableProperty][NotifyPropertyChangedRecipients] public partial bool IsMatchingThresholdOverwritten { get; set; } = false;
[ObservableProperty][NotifyPropertyChangedRecipients] public partial int MatchingThreshold { get; set; } = 40;
+ [ObservableProperty][NotifyPropertyChangedRecipients] public partial bool IgnoreCacheWhenSearching { get; set; } = false;
public LyricsSearchProviderInfo() { }
diff --git a/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Parsers/LyricsParser/LyricsParser.Lrc.cs b/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Parsers/LyricsParser/LyricsParser.Lrc.cs
index 7fe881c..3439efb 100644
--- a/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Parsers/LyricsParser/LyricsParser.Lrc.cs
+++ b/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Parsers/LyricsParser/LyricsParser.Lrc.cs
@@ -24,7 +24,7 @@ namespace BetterLyrics.WinUI3.Parsers.LyricsParser
foreach (var line in lines)
{
var matches = syllableRegex.Matches(line);
- var syllables = new List();
+ var syllables = new List();
int startIndex = 0;
for (int i = 0; i < matches.Count; i++)
@@ -36,7 +36,7 @@ namespace BetterLyrics.WinUI3.Parsers.LyricsParser
int totalMs = min * 60_000 + sec * 1000 + ms;
string text = match.Groups[6].Value;
- syllables.Add(new LyricsSyllable { StartMs = totalMs, Text = text, StartIndex = startIndex });
+ syllables.Add(new BaseLyrics { StartMs = totalMs, Text = text, StartIndex = startIndex });
startIndex += text.Length;
}
@@ -58,8 +58,8 @@ namespace BetterLyrics.WinUI3.Parsers.LyricsParser
{
StartMs = syllables[0].StartMs,
EndMs = lineEndMs,
- OriginalText = string.Concat(syllables.Select(s => s.Text)),
- LyricsSyllables = syllables
+ PrimaryText = string.Concat(syllables.Select(s => s.Text)),
+ PrimarySyllables = syllables
});
}
else
@@ -81,7 +81,7 @@ namespace BetterLyrics.WinUI3.Parsers.LyricsParser
content = bracketRegex!.Replace(line, "").Trim();
if (content == "//") content = "";
- lrcLines.Add(new LyricsLine { StartMs = lineStartMs, OriginalText = content });
+ lrcLines.Add(new LyricsLine { StartMs = lineStartMs, PrimaryText = content });
}
}
}
diff --git a/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Parsers/LyricsParser/LyricsParser.QrcKrc.cs b/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Parsers/LyricsParser/LyricsParser.QrcKrc.cs
index 41a4a25..7087ac6 100644
--- a/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Parsers/LyricsParser/LyricsParser.QrcKrc.cs
+++ b/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Parsers/LyricsParser/LyricsParser.QrcKrc.cs
@@ -17,12 +17,13 @@ namespace BetterLyrics.WinUI3.Parsers.LyricsParser
for (int lineIndex = 0; lineIndex < lines.Count; lineIndex++)
{
var lineRead = lines[lineIndex];
+ var nextLineRead = lines.ElementAtOrDefault(lineIndex + 1);
var lineWrite = new LyricsLine
{
StartMs = lineRead.StartTime ?? 0,
- EndMs = lineRead.EndTime ?? 0,
- OriginalText = lineRead.Text,
- LyricsSyllables = [],
+ EndMs = lineRead.EndTime ?? (nextLineRead?.StartTime ?? 0),
+ PrimaryText = lineRead.Text,
+ PrimarySyllables = [],
};
var syllables = (lineRead as Lyricify.Lyrics.Models.SyllableLineInfo)?.Syllables;
@@ -36,14 +37,14 @@ namespace BetterLyrics.WinUI3.Parsers.LyricsParser
)
{
var syllable = syllables[syllableIndex];
- var charTiming = new LyricsSyllable
+ var charTiming = new BaseLyrics
{
StartMs = syllable.StartTime,
EndMs = syllable.EndTime,
Text = syllable.Text,
StartIndex = startIndex,
};
- lineWrite.LyricsSyllables.Add(charTiming);
+ lineWrite.PrimarySyllables.Add(charTiming);
startIndex += syllable.Text.Length;
}
}
diff --git a/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Parsers/LyricsParser/LyricsParser.Ttml.cs b/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Parsers/LyricsParser/LyricsParser.Ttml.cs
index e9e42ff..b9ff6f5 100644
--- a/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Parsers/LyricsParser/LyricsParser.Ttml.cs
+++ b/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Parsers/LyricsParser/LyricsParser.Ttml.cs
@@ -93,7 +93,7 @@ namespace BetterLyrics.WinUI3.Parsers.LyricsParser
}
}
- var syllables = new List();
+ var syllables = new List();
int startIndex = 0;
var sbText = new System.Text.StringBuilder();
@@ -103,7 +103,7 @@ namespace BetterLyrics.WinUI3.Parsers.LyricsParser
int sEndMs = ParseTtmlTime(span.Attribute("end")?.Value);
string text = span.Value;
- syllables.Add(new LyricsSyllable
+ syllables.Add(new BaseLyrics
{
StartMs = sStartMs,
EndMs = sEndMs,
@@ -126,8 +126,8 @@ namespace BetterLyrics.WinUI3.Parsers.LyricsParser
{
StartMs = containerStartMs,
EndMs = containerEndMs,
- OriginalText = fullOriginalText,
- LyricsSyllables = syllables
+ PrimaryText = fullOriginalText,
+ PrimarySyllables = syllables
});
var transSpan = container.Elements()
@@ -151,7 +151,7 @@ namespace BetterLyrics.WinUI3.Parsers.LyricsParser
{
StartMs = startMs,
EndMs = endMs,
- OriginalText = text
+ PrimaryText = text
});
}
else
@@ -160,7 +160,7 @@ namespace BetterLyrics.WinUI3.Parsers.LyricsParser
{
StartMs = startMs,
EndMs = endMs,
- OriginalText = ""
+ PrimaryText = ""
});
}
}
diff --git a/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Parsers/LyricsParser/LyricsParser.cs b/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Parsers/LyricsParser/LyricsParser.cs
index 5a2095f..4748be6 100644
--- a/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Parsers/LyricsParser/LyricsParser.cs
+++ b/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Parsers/LyricsParser/LyricsParser.cs
@@ -167,14 +167,14 @@ namespace BetterLyrics.WinUI3.Parsers.LyricsParser
{
foreach (var item in main.LyricsLines)
{
- item.OriginalText = settings.IsTraditionalChineseEnabled ? ChineseHelper.ToTC(item.OriginalText) : ChineseHelper.ToSC(item.OriginalText);
+ item.PrimaryText = settings.IsTraditionalChineseEnabled ? ChineseHelper.ToTC(item.PrimaryText) : ChineseHelper.ToSC(item.PrimaryText);
}
}
if (settings.SelectedTargetLanguageCode == LanguageHelper.ChineseCode)
{
foreach (var item in main.LyricsLines)
{
- item.TranslatedText = settings.IsTraditionalChineseEnabled ? ChineseHelper.ToTC(item.TranslatedText) : ChineseHelper.ToSC(item.TranslatedText);
+ item.SecondaryText = settings.IsTraditionalChineseEnabled ? ChineseHelper.ToTC(item.SecondaryText) : ChineseHelper.ToSC(item.SecondaryText);
}
}
@@ -235,8 +235,8 @@ namespace BetterLyrics.WinUI3.Parsers.LyricsParser
{
StartMs = line.StartMs,
EndMs = line.EndMs,
- OriginalText = PhoneticHelper.ToPinyin(line.OriginalText),
- LyricsSyllables = line.LyricsSyllables.Select(c => new LyricsSyllable
+ PrimaryText = PhoneticHelper.ToPinyin(line.PrimaryText),
+ PrimarySyllables = line.PrimarySyllables.Select(c => new BaseLyrics
{
StartMs = c.StartMs,
EndMs = c.EndMs,
@@ -256,8 +256,8 @@ namespace BetterLyrics.WinUI3.Parsers.LyricsParser
{
StartMs = line.StartMs,
EndMs = line.EndMs,
- OriginalText = PhoneticHelper.ToJyutping(line.OriginalText),
- LyricsSyllables = line.LyricsSyllables.Select(c => new LyricsSyllable
+ PrimaryText = PhoneticHelper.ToJyutping(line.PrimaryText),
+ PrimarySyllables = line.PrimarySyllables.Select(c => new BaseLyrics
{
StartMs = c.StartMs,
EndMs = c.EndMs,
diff --git a/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Renderer/LyricsRenderer.cs b/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Renderer/LyricsRenderer.cs
index dd37de4..8246374 100644
--- a/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Renderer/LyricsRenderer.cs
+++ b/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Renderer/LyricsRenderer.cs
@@ -26,7 +26,6 @@ namespace BetterLyrics.WinUI3.Renderer
ICanvasAnimatedControl control,
CanvasDrawingSession ds,
IList? lines,
- int playingLineIndex,
int mouseHoverLineIndex,
bool isMousePressing,
int startVisibleIndex,
@@ -57,7 +56,6 @@ namespace BetterLyrics.WinUI3.Renderer
control,
layerDs,
lines,
- playingLineIndex,
mouseHoverLineIndex,
isMousePressing,
startVisibleIndex,
@@ -89,7 +87,6 @@ namespace BetterLyrics.WinUI3.Renderer
control,
ds,
lines,
- playingLineIndex,
mouseHoverLineIndex,
isMousePressing,
startVisibleIndex,
@@ -114,7 +111,6 @@ namespace BetterLyrics.WinUI3.Renderer
ICanvasAnimatedControl control,
CanvasDrawingSession ds,
IList? lines,
- int playingLineIndex,
int mouseHoverLineIndex,
bool isMousePressing,
int startVisibleIndex,
@@ -134,9 +130,6 @@ namespace BetterLyrics.WinUI3.Renderer
{
if (lines == null) return;
- var currentPlayingLine = lines.ElementAtOrDefault(playingLineIndex);
- if (currentPlayingLine == null) return;
-
var effectSettings = windowStatus.LyricsEffectSettings;
var styleSettings = windowStatus.LyricsStyleSettings;
@@ -148,8 +141,8 @@ namespace BetterLyrics.WinUI3.Renderer
var line = lines.ElementAtOrDefault(i);
if (line == null) continue;
- if (line.OriginalCanvasTextLayout == null) continue;
- if (line.OriginalCanvasTextLayout.LayoutBounds.Width <= 0) continue;
+ if (line.PrimaryTextLayout == null) continue;
+ if (line.PrimaryTextLayout.LayoutBounds.Width <= 0) continue;
double xOffset = lyricsX;
double yOffset = line.YOffsetTransition.Value + userScrollOffset + lyricsY + lyricsHeight * playingLineTopOffsetFactor;
@@ -167,8 +160,7 @@ namespace BetterLyrics.WinUI3.Renderer
using (var textOnlyLayer = RenderBaseTextLayer(control, line, styleSettings.LyricsFontStrokeWidth, strokeColor, line.ColorTransition.Value))
{
- bool isPlaying = currentProgressMs >= line.StartMs && currentProgressMs <= line.EndMs;
- if (i == playingLineIndex) isPlaying = true;
+ bool isPlaying = line.GetIsPlaying(currentProgressMs);
if (isPlaying)
{
@@ -206,14 +198,14 @@ namespace BetterLyrics.WinUI3.Renderer
{
if (strokeWidth > 0)
{
- DrawGeometrySafely(clds, line.PhoneticCanvasGeometry, line.PhoneticPosition, strokeColor, strokeWidth);
- DrawGeometrySafely(clds, line.OriginalCanvasGeometry, line.OriginalPosition, strokeColor, strokeWidth);
- DrawGeometrySafely(clds, line.TranslatedCanvasGeometry, line.TranslatedPosition, strokeColor, strokeWidth);
+ DrawGeometrySafely(clds, line.TertiaryCanvasGeometry, line.TertiaryPosition, strokeColor, strokeWidth);
+ DrawGeometrySafely(clds, line.PrimaryCanvasGeometry, line.PrimaryPosition, strokeColor, strokeWidth);
+ DrawGeometrySafely(clds, line.SecondaryCanvasGeometry, line.SecondaryPosition, strokeColor, strokeWidth);
}
- DrawTextLayoutSafely(clds, line.PhoneticCanvasTextLayout, line.PhoneticPosition, fillColor);
- DrawTextLayoutSafely(clds, line.OriginalCanvasTextLayout, line.OriginalPosition, fillColor);
- DrawTextLayoutSafely(clds, line.TranslatedCanvasTextLayout, line.TranslatedPosition, fillColor);
+ DrawTextLayoutSafely(clds, line.TertiaryTextLayout, line.TertiaryPosition, fillColor);
+ DrawTextLayoutSafely(clds, line.PrimaryTextLayout, line.PrimaryPosition, fillColor);
+ DrawTextLayoutSafely(clds, line.SecondaryTextLayout, line.SecondaryPosition, fillColor);
}
return commandList;
}
diff --git a/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Renderer/PlayingLineRenderer.cs b/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Renderer/PlayingLineRenderer.cs
index 05a5aba..41125e6 100644
--- a/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Renderer/PlayingLineRenderer.cs
+++ b/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Renderer/PlayingLineRenderer.cs
@@ -33,17 +33,17 @@ namespace BetterLyrics.WinUI3.Renderer
private void DrawPhonetic(CanvasDrawingSession ds, ICanvasImage source, RenderLyricsLine line)
{
- if (line.PhoneticCanvasTextLayout == null) return;
+ if (line.TertiaryTextLayout == null) return;
var opacity = line.PhoneticOpacityTransition.Value;
var blur = line.BlurAmountTransition.Value;
- var bounds = line.PhoneticCanvasTextLayout.LayoutBounds;
+ var bounds = line.TertiaryTextLayout.LayoutBounds;
if (double.IsNaN(opacity)) return;
var destRect = new Rect(
- bounds.X + line.PhoneticPosition.X,
- bounds.Y + line.PhoneticPosition.Y,
+ bounds.X + line.TertiaryPosition.X,
+ bounds.Y + line.TertiaryPosition.Y,
bounds.Width,
bounds.Height
);
@@ -67,17 +67,17 @@ namespace BetterLyrics.WinUI3.Renderer
private void DrawTranslated(CanvasDrawingSession ds, ICanvasImage source, RenderLyricsLine line)
{
- if (line.TranslatedCanvasTextLayout == null) return;
+ if (line.SecondaryTextLayout == null) return;
var opacity = line.TranslatedOpacityTransition.Value;
var blur = line.BlurAmountTransition.Value;
- var bounds = line.TranslatedCanvasTextLayout.LayoutBounds;
+ var bounds = line.SecondaryTextLayout.LayoutBounds;
if (double.IsNaN(opacity)) return;
var destRect = new Rect(
- bounds.X + line.TranslatedPosition.X,
- bounds.Y + line.TranslatedPosition.Y,
+ bounds.X + line.SecondaryPosition.X,
+ bounds.Y + line.SecondaryPosition.Y,
bounds.Width,
bounds.Height
);
@@ -109,12 +109,12 @@ namespace BetterLyrics.WinUI3.Renderer
Color fgColor,
LyricsEffectSettings settings)
{
- if (line.OriginalCanvasTextLayout == null) return;
+ if (line.PrimaryTextLayout == null) return;
var curCharIndex = state.SyllableStartIndex + state.SyllableLength * state.SyllableProgress;
- float fadeWidth = (1f / Math.Max(1, line.OriginalText.Length)) * 0.5f;
+ float fadeWidth = (1f / Math.Max(1, line.PrimaryText.Length)) * 0.5f;
- var lineRegions = line.OriginalCanvasTextLayout.GetCharacterRegions(0, line.OriginalText.Length);
+ var lineRegions = line.PrimaryTextLayout.GetCharacterRegions(0, line.PrimaryText.Length);
foreach (var subLineRegion in lineRegions)
{
@@ -139,8 +139,8 @@ namespace BetterLyrics.WinUI3.Renderer
var subLineLayoutBounds = subLineRegion.LayoutBounds;
Rect subLineRect = new(
- subLineLayoutBounds.X + line.OriginalPosition.X,
- subLineLayoutBounds.Y + line.OriginalPosition.Y,
+ subLineLayoutBounds.X + line.PrimaryPosition.X,
+ subLineLayoutBounds.Y + line.PrimaryPosition.Y,
subLineLayoutBounds.Width,
subLineLayoutBounds.Height
);
@@ -208,14 +208,14 @@ namespace BetterLyrics.WinUI3.Renderer
int charIndex,
ICanvasImage source)
{
- if (charIndex >= line.RenderLyricsOriginalChars.Count) return;
+ if (charIndex >= line.PrimaryRenderChars.Count) return;
- RenderLyricsChar renderChar = line.RenderLyricsOriginalChars[charIndex];
+ RenderLyricsChar renderChar = line.PrimaryRenderChars[charIndex];
var rect = renderChar.LayoutRect;
var sourceCharRect = new Rect(
- rect.X + line.OriginalPosition.X,
- rect.Y + line.OriginalPosition.Y,
+ rect.X + line.PrimaryPosition.X,
+ rect.Y + line.PrimaryPosition.Y,
rect.Width,
rect.Height
);
diff --git a/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Renderer/UnplayingLineRenderer.cs b/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Renderer/UnplayingLineRenderer.cs
index b9cf074..db67ac5 100644
--- a/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Renderer/UnplayingLineRenderer.cs
+++ b/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Renderer/UnplayingLineRenderer.cs
@@ -17,32 +17,32 @@ namespace BetterLyrics.WinUI3.Renderer
{
var blurAmount = (float)line.BlurAmountTransition.Value;
- if (line.PhoneticCanvasTextLayout != null)
+ if (line.TertiaryTextLayout != null)
{
var opacity = line.PhoneticOpacityTransition.Value;
DrawPart(ds, textOnlyLayer,
- line.PhoneticCanvasTextLayout,
- line.PhoneticPosition,
+ line.TertiaryTextLayout,
+ line.TertiaryPosition,
blurAmount,
(float)opacity);
}
- if (line.OriginalCanvasTextLayout != null)
+ if (line.PrimaryTextLayout != null)
{
double opacity = Math.Max(line.PlayedOriginalOpacityTransition.Value, line.UnplayedOriginalOpacityTransition.Value);
DrawPart(ds, textOnlyLayer,
- line.OriginalCanvasTextLayout,
- line.OriginalPosition,
+ line.PrimaryTextLayout,
+ line.PrimaryPosition,
blurAmount,
(float)opacity);
}
- if (line.TranslatedCanvasTextLayout != null)
+ if (line.SecondaryTextLayout != null)
{
var opacity = line.TranslatedOpacityTransition.Value;
DrawPart(ds, textOnlyLayer,
- line.TranslatedCanvasTextLayout,
- line.TranslatedPosition,
+ line.SecondaryTextLayout,
+ line.SecondaryPosition,
blurAmount,
(float)opacity);
}
diff --git a/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Services/GSMTCService/GSMTCService.LyricsUpdater.cs b/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Services/GSMTCService/GSMTCService.LyricsUpdater.cs
index 6e07066..049ff95 100644
--- a/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Services/GSMTCService/GSMTCService.LyricsUpdater.cs
+++ b/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Services/GSMTCService/GSMTCService.LyricsUpdater.cs
@@ -28,7 +28,7 @@ namespace BetterLyrics.WinUI3.Services.GSMTCService
if (CurrentSongInfo != SongInfoExtensions.Placeholder)
{
CurrentLyricsSearchResult = await Task.Run(async () => await _lyrcsSearchService.SearchSmartlyAsync(
- CurrentSongInfo, true, CurrentMediaSourceProviderInfo?.LyricsSearchType, token), token);
+ CurrentSongInfo, CurrentMediaSourceProviderInfo?.LyricsSearchType, token), token);
if (CurrentLyricsSearchResult != null)
{
diff --git a/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Services/LyricsCacheService/LyricsCacheService.cs b/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Services/LyricsCacheService/LyricsCacheService.cs
index da0e998..9612d91 100644
--- a/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Services/LyricsCacheService/LyricsCacheService.cs
+++ b/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Services/LyricsCacheService/LyricsCacheService.cs
@@ -32,7 +32,7 @@ namespace BetterLyrics.WinUI3.Services.LyricsCacheService
}
///
- /// Write cache to DB
+ /// Write or update cache to DB
///
public async Task SaveLyricsAsync(SongInfo songInfo, LyricsCacheItem result)
{
@@ -52,8 +52,18 @@ namespace BetterLyrics.WinUI3.Services.LyricsCacheService
}
else
{
- // No need to handle this case
- return;
+ existingItem.Title = result.Title;
+ existingItem.Artist = result.Artist;
+ existingItem.Album = result.Album;
+
+ existingItem.TransliterationProvider = result.TransliterationProvider;
+ existingItem.TranslationProvider = result.TranslationProvider;
+
+ existingItem.Raw = result.Raw;
+ existingItem.Translation = result.Translation;
+
+ existingItem.MatchPercentage = result.MatchPercentage;
+ existingItem.Reference = result.Reference;
}
await context.SaveChangesAsync();
diff --git a/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Services/LyricsSearchService/ILyricsSearchService.cs b/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Services/LyricsSearchService/ILyricsSearchService.cs
index e7f1c42..7af4196 100644
--- a/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Services/LyricsSearchService/ILyricsSearchService.cs
+++ b/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Services/LyricsSearchService/ILyricsSearchService.cs
@@ -10,7 +10,7 @@ namespace BetterLyrics.WinUI3.Services.LyricsSearchService
{
public interface ILyricsSearchService
{
- Task SearchSmartlyAsync(SongInfo songInfo, bool checkCache, LyricsSearchType? lyricsSearchType, CancellationToken token);
+ Task SearchSmartlyAsync(SongInfo songInfo, LyricsSearchType? lyricsSearchType, CancellationToken token);
Task> SearchAllAsync(SongInfo songInfo, bool checkCache, CancellationToken token);
}
diff --git a/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Services/LyricsSearchService/LyricsSearchService.cs b/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Services/LyricsSearchService/LyricsSearchService.cs
index d3f019d..d02f462 100644
--- a/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Services/LyricsSearchService/LyricsSearchService.cs
+++ b/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Services/LyricsSearchService/LyricsSearchService.cs
@@ -104,7 +104,7 @@ namespace BetterLyrics.WinUI3.Services.LyricsSearchService
}
}
- public async Task SearchSmartlyAsync(SongInfo songInfo, bool checkCache, LyricsSearchType? lyricsSearchType, CancellationToken token)
+ public async Task SearchSmartlyAsync(SongInfo songInfo, LyricsSearchType? lyricsSearchType, CancellationToken token)
{
if (lyricsSearchType == null)
{
@@ -112,8 +112,6 @@ namespace BetterLyrics.WinUI3.Services.LyricsSearchService
}
var lyricsSearchResult = new LyricsCacheItem();
- //lyricsSearchResult.Raw = File.ReadAllText("C:\\Users\\Zhe\\Desktop\\星河回响 (Tech Demo).lrc");
- //return lyricsSearchResult;
string overridenTitle = songInfo.Title;
string overridenArtist = songInfo.Artist;
@@ -150,7 +148,7 @@ namespace BetterLyrics.WinUI3.Services.LyricsSearchService
.WithTitle(overridenTitle)
.WithArtist(overridenArtist)
.WithAlbum(overridenAlbum),
- targetProvider.Value, checkCache, token);
+ targetProvider.Value, true, token);
}
}
@@ -172,7 +170,7 @@ namespace BetterLyrics.WinUI3.Services.LyricsSearchService
.WithTitle(overridenTitle)
.WithArtist(overridenArtist)
.WithAlbum(overridenAlbum),
- provider.Provider, checkCache, token);
+ provider.Provider, !provider.IgnoreCacheWhenSearching, token);
int matchingThreshold = mediaSourceProviderInfo.MatchingThreshold;
if (provider.IsMatchingThresholdOverwritten)
@@ -288,7 +286,7 @@ namespace BetterLyrics.WinUI3.Services.LyricsSearchService
private async Task SearchFile(SongInfo songInfo, LyricsFormat format)
{
- int maxScore = 0;
+ int maxScore = -1;
FilesIndexItem? bestFileEntity = null;
MediaFolder? bestFolderConfig = null;
@@ -316,7 +314,7 @@ namespace BetterLyrics.WinUI3.Services.LyricsSearchService
{
if (item.FileName.EndsWith(targetExt, StringComparison.OrdinalIgnoreCase))
{
- int score = MetadataComparer.CalculateScore(songInfo, new LyricsCacheItem { Reference = item.FileName });
+ int score = MetadataComparer.CalculateScore(songInfo, item);
if (score > maxScore)
{
@@ -363,13 +361,7 @@ namespace BetterLyrics.WinUI3.Services.LyricsSearchService
{
if (string.IsNullOrEmpty(item.EmbeddedLyrics)) continue;
- int score = MetadataComparer.CalculateScore(songInfo, new LyricsCacheItem
- {
- Title = item.Title,
- Artist = item.Artist,
- Album = item.Album,
- Duration = item.Duration
- });
+ int score = MetadataComparer.CalculateScore(songInfo, item);
if (score > maxScore)
{
@@ -444,6 +436,7 @@ namespace BetterLyrics.WinUI3.Services.LyricsSearchService
Title = title,
Artist = artist,
Album = album,
+ Duration = 0,
});
if (score > lyricsSearchResult.MatchPercentage)
{
diff --git a/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Strings/ar/Resources.resw b/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Strings/ar/Resources.resw
index d6fb2c8..a61435e 100644
--- a/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Strings/ar/Resources.resw
+++ b/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Strings/ar/Resources.resw
@@ -59,46 +59,46 @@
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
-
-
+
+
-
+
-
-
-
-
+
+
+
+
-
-
+
+
-
-
+
+
-
-
-
-
+
+
+
+
-
+
-
+
diff --git a/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Strings/de/Resources.resw b/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Strings/de/Resources.resw
index 17aaa44..d1c7efb 100644
--- a/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Strings/de/Resources.resw
+++ b/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Strings/de/Resources.resw
@@ -59,46 +59,46 @@
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
-
-
+
+
-
+
-
-
-
-
+
+
+
+
-
-
+
+
-
-
+
+
-
-
-
-
+
+
+
+
-
+
-
+
diff --git a/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Strings/en/Resources.resw b/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Strings/en/Resources.resw
index a96ea27..029e22e 100644
--- a/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Strings/en/Resources.resw
+++ b/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Strings/en/Resources.resw
@@ -243,6 +243,9 @@
e.g. http://localhost:5000
+
+ Duration
+
Loading lyrics...
diff --git a/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Strings/es/Resources.resw b/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Strings/es/Resources.resw
index b6aaf6a..352822e 100644
--- a/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Strings/es/Resources.resw
+++ b/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Strings/es/Resources.resw
@@ -59,46 +59,46 @@
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
-
-
+
+
-
+
-
-
-
-
+
+
+
+
-
-
+
+
-
-
+
+
-
-
-
-
+
+
+
+
-
+
-
+
diff --git a/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Strings/fr/Resources.resw b/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Strings/fr/Resources.resw
index 33a6a46..35186ff 100644
--- a/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Strings/fr/Resources.resw
+++ b/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Strings/fr/Resources.resw
@@ -59,46 +59,46 @@
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
-
-
+
+
-
+
-
-
-
-
+
+
+
+
-
-
+
+
-
-
+
+
-
-
-
-
+
+
+
+
-
+
-
+
diff --git a/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Strings/hi/Resources.resw b/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Strings/hi/Resources.resw
index 07df67b..d9505d8 100644
--- a/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Strings/hi/Resources.resw
+++ b/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Strings/hi/Resources.resw
@@ -59,46 +59,46 @@
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
-
-
+
+
-
+
-
-
-
-
+
+
+
+
-
-
+
+
-
-
+
+
-
-
-
-
+
+
+
+
-
+
-
+
diff --git a/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Strings/id/Resources.resw b/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Strings/id/Resources.resw
index a5538e2..2bc2f27 100644
--- a/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Strings/id/Resources.resw
+++ b/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Strings/id/Resources.resw
@@ -59,46 +59,46 @@
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
-
-
+
+
-
+
-
-
-
-
+
+
+
+
-
-
+
+
-
-
+
+
-
-
-
-
+
+
+
+
-
+
-
+
diff --git a/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Strings/ja/Resources.resw b/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Strings/ja/Resources.resw
index 8ec90d1..60a9737 100644
--- a/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Strings/ja/Resources.resw
+++ b/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Strings/ja/Resources.resw
@@ -59,46 +59,46 @@
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
-
-
+
+
-
+
-
-
-
-
+
+
+
+
-
-
+
+
-
-
+
+
-
-
-
-
+
+
+
+
-
+
-
+
diff --git a/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Strings/ko/Resources.resw b/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Strings/ko/Resources.resw
index d02aee4..9ccc429 100644
--- a/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Strings/ko/Resources.resw
+++ b/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Strings/ko/Resources.resw
@@ -59,46 +59,46 @@
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
-
-
+
+
-
+
-
-
-
-
+
+
+
+
-
-
+
+
-
-
+
+
-
-
-
-
+
+
+
+
-
+
-
+
diff --git a/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Strings/ms/Resources.resw b/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Strings/ms/Resources.resw
index bb6b927..6289ceb 100644
--- a/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Strings/ms/Resources.resw
+++ b/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Strings/ms/Resources.resw
@@ -59,46 +59,46 @@
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
-
-
+
+
-
+
-
-
-
-
+
+
+
+
-
-
+
+
-
-
+
+
-
-
-
-
+
+
+
+
-
+
-
+
diff --git a/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Strings/pt/Resources.resw b/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Strings/pt/Resources.resw
index 53997c6..ec955c6 100644
--- a/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Strings/pt/Resources.resw
+++ b/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Strings/pt/Resources.resw
@@ -59,46 +59,46 @@
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
-
-
+
+
-
+
-
-
-
-
+
+
+
+
-
-
+
+
-
-
+
+
-
-
-
-
+
+
+
+
-
+
-
+
diff --git a/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Strings/ru/Resources.resw b/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Strings/ru/Resources.resw
index 8f951ed..26cf55c 100644
--- a/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Strings/ru/Resources.resw
+++ b/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Strings/ru/Resources.resw
@@ -59,46 +59,46 @@
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
-
-
+
+
-
+
-
-
-
-
+
+
+
+
-
-
+
+
-
-
+
+
-
-
-
-
+
+
+
+
-
+
-
+
diff --git a/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Strings/th/Resources.resw b/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Strings/th/Resources.resw
index 9570db6..46e4165 100644
--- a/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Strings/th/Resources.resw
+++ b/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Strings/th/Resources.resw
@@ -59,46 +59,46 @@
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
-
-
+
+
-
+
-
-
-
-
+
+
+
+
-
-
+
+
-
-
+
+
-
-
-
-
+
+
+
+
-
+
-
+
diff --git a/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Strings/vi/Resources.resw b/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Strings/vi/Resources.resw
index ddee18f..fed2c08 100644
--- a/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Strings/vi/Resources.resw
+++ b/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Strings/vi/Resources.resw
@@ -59,46 +59,46 @@
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
-
-
+
+
-
+
-
-
-
-
+
+
+
+
-
-
+
+
-
-
+
+
-
-
-
-
+
+
+
+
-
+
-
+
diff --git a/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Strings/zh-Hans/Resources.resw b/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Strings/zh-Hans/Resources.resw
index 92c39ca..a2620cb 100644
--- a/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Strings/zh-Hans/Resources.resw
+++ b/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Strings/zh-Hans/Resources.resw
@@ -59,46 +59,46 @@
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
-
-
+
+
-
+
-
-
-
-
+
+
+
+
-
-
+
+
-
-
+
+
-
-
-
-
+
+
+
+
-
+
-
+
@@ -243,6 +243,9 @@
例如 http://localhost:5000
+
+ 持续时间
+
加载歌词中...
diff --git a/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Strings/zh-Hant/Resources.resw b/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Strings/zh-Hant/Resources.resw
index fb85a5d..06cfd6c 100644
--- a/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Strings/zh-Hant/Resources.resw
+++ b/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Strings/zh-Hant/Resources.resw
@@ -59,46 +59,46 @@
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
-
-
+
+
-
+
-
-
-
-
+
+
+
+
-
-
+
+
-
-
+
+
-
-
-
-
+
+
+
+
-
+
-
+