Files
WindowsMusicPlayer-TheUntam…/The Untamed Music Player/Models/LyricSlice.cs
2024-08-27 15:07:06 +08:00

127 lines
4.5 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Text.RegularExpressions;
namespace The_Untamed_Music_Player.Models;
public partial class LyricSlice : INotifyPropertyChanged
{
public event PropertyChangedEventHandler? PropertyChanged;
protected void OnPropertyChanged(string propertyName)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
private string _content = "";
public string Content
{
get => _content;
set
{
_content = value;
OnPropertyChanged(nameof(Content));
}
}
private double _time;
public double Time
{
get => _time;
set
{
_time = value;
OnPropertyChanged(nameof(Time));
}
}
public LyricSlice(double time, string content)
{
Time = time;
Content = content;
}
[GeneratedRegex(@".*\](.*)")]
private static partial Regex RegexWord();
[GeneratedRegex(@"\[([0-9.:]*)\]", RegexOptions.Compiled)]
private static partial Regex RegexTime();
public static ObservableCollection<LyricSlice> GetLyricSlices(string lyric)
{
var lyricSlices = new List<LyricSlice>();
if (string.IsNullOrEmpty(lyric))
{
return [];
}
var lines = lyric.Split('\n');
double? lastTime = null;//上一行有歌词的行的时间
double emptyStartTime = 0;//空白行开始时间
var inEmptyBlock = false;
var emptyLines = new List<LyricSlice>();
foreach (var line in lines)
{
if (line != null)
{
if (line.StartsWith("[ti:") || line.StartsWith("[ar:") || line.StartsWith("[al:") || line.StartsWith("[by:") || line.StartsWith("[offset:"))//歌曲名、艺人名、专辑名、歌词制作人、歌词时间补偿值
{
continue;
}
try
{
var regexword = RegexWord();//获取歌词文本的正则表达式
var regextime = RegexTime();//获取时间戳的正则表达式
var WORD = regexword.Match(line).Groups[1].Value;//获取歌词文本
var TIME = regextime.Matches(line);//获取时间戳
if (string.IsNullOrWhiteSpace(WORD))//歌词文本为空
{
if (!inEmptyBlock)
{
emptyStartTime = TIME.Count > 0 ? TimeSpan.Parse("00:" + TIME[0].Groups[1].Value).TotalMilliseconds : lastTime ?? 0;//将时间戳转换为毫秒(只保留第一组, 防止一行歌词里面有多个时间)
if (emptyStartTime == lastTime)
{
emptyStartTime += 1; // 如果空白行和上一行有歌词的行时间相同空白行的时间加1毫秒
}
inEmptyBlock = true;
}
}
else
{
if (inEmptyBlock)
{
var emptyEndTime = TIME.Count > 0 ? TimeSpan.Parse("00:" + TIME[0].Groups[1].Value).TotalMilliseconds : lastTime ?? 0;
if (emptyEndTime - emptyStartTime > 5000)
{
lyricSlices.Add(new LyricSlice(emptyStartTime, "•••"));
}
inEmptyBlock = false;
}
foreach (Match item in TIME)
{
var time = TimeSpan.Parse("00:" + item.Groups[1].Value).TotalMilliseconds;
lyricSlices.Add(new LyricSlice(time, WORD));
lastTime = time;
}
}
}
catch
{
continue;
}
}
}
if (inEmptyBlock && emptyLines.Count > 0)
{
var emptyEndTime = emptyLines.Last().Time;
if (emptyEndTime - emptyStartTime > 5000)
{
lyricSlices.Add(new LyricSlice(emptyStartTime, "•••"));
}
}
return new ObservableCollection<LyricSlice>(lyricSlices.OrderBy(t => t.Time));//将 lyricSlices 列表按时间戳排序。
}
}