From 97d662ef2bcb88c0d63c8ad483f25dd477c6c355 Mon Sep 17 00:00:00 2001 From: jitwxs Date: Wed, 4 May 2022 12:01:05 +0800 Subject: [PATCH 1/5] initial version v4.3 --- MusicLyricApp/Bean/Constants.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/MusicLyricApp/Bean/Constants.cs b/MusicLyricApp/Bean/Constants.cs index a9e2cb2..05d4f53 100644 --- a/MusicLyricApp/Bean/Constants.cs +++ b/MusicLyricApp/Bean/Constants.cs @@ -4,7 +4,7 @@ namespace MusicLyricApp.Bean { public static class Constants { - public const string Version = "v4.2"; + public const string Version = "v4.3"; public static readonly string SettingPath = Environment.CurrentDirectory + "\\MusicLyricAppSetting.json"; From 30360da4c8c2d5988289943f29da03d08e4a0199 Mon Sep 17 00:00:00 2001 From: jitwxs Date: Wed, 4 May 2022 12:32:12 +0800 Subject: [PATCH 2/5] fix lyric sort and format bugs --- MusicLyricApp/Api/QQMusicApiV2.cs | 4 ++-- MusicLyricApp/Bean/MusicLyricsVO.cs | 18 ++++++++++++++++++ MusicLyricApp/Bean/QQMusicBean.cs | 10 ++++------ MusicLyricApp/Utils/LyricUtils.cs | 22 ++++++++-------------- 4 files changed, 32 insertions(+), 22 deletions(-) diff --git a/MusicLyricApp/Api/QQMusicApiV2.cs b/MusicLyricApp/Api/QQMusicApiV2.cs index ecad0eb..3c1608f 100644 --- a/MusicLyricApp/Api/QQMusicApiV2.cs +++ b/MusicLyricApp/Api/QQMusicApiV2.cs @@ -72,8 +72,8 @@ protected override LyricVo GetLyricVo0(string songId) var lyricVo = new LyricVo(); - lyricVo.SetLyric(resp.lyric); - lyricVo.SetTranslateLyric(resp.trans); + lyricVo.SetLyric(resp.Lyric); + lyricVo.SetTranslateLyric(resp.Trans); return lyricVo; } diff --git a/MusicLyricApp/Bean/MusicLyricsVO.cs b/MusicLyricApp/Bean/MusicLyricsVO.cs index af42cb5..ae4e084 100644 --- a/MusicLyricApp/Bean/MusicLyricsVO.cs +++ b/MusicLyricApp/Bean/MusicLyricsVO.cs @@ -263,6 +263,24 @@ public int CompareTo(object input) return (int) (TimeOffset - obj.TimeOffset); } + /// + /// 是否是无效的内容 + /// + public bool IsIllegalContent() + { + if (string.IsNullOrWhiteSpace(Content)) + { + return true; + } + + if ("//".Equals(Content)) + { + return true; + } + + return false; + } + public override string ToString() { return Timestamp + Content; diff --git a/MusicLyricApp/Bean/QQMusicBean.cs b/MusicLyricApp/Bean/QQMusicBean.cs index 4db422b..0ab0a34 100644 --- a/MusicLyricApp/Bean/QQMusicBean.cs +++ b/MusicLyricApp/Bean/QQMusicBean.cs @@ -26,17 +26,15 @@ public class LyricResult { public long Code { get; set; } - public string lyric { get; set; } + public string Lyric { get; set; } - public string trans { get; set; } + public string Trans { get; set; } public LyricResult Decode() { - var decode = Encoding.UTF8.GetString(Convert.FromBase64String(lyric)); - lyric = Regex.Replace(decode, "\n", "\r\n"); + Lyric = Encoding.UTF8.GetString(Convert.FromBase64String(Lyric)); - decode = Encoding.UTF8.GetString(Convert.FromBase64String(trans)); - trans = Regex.Replace(decode, "\n", "\r\n"); + Trans = Encoding.UTF8.GetString(Convert.FromBase64String(Trans)); return this; } diff --git a/MusicLyricApp/Utils/LyricUtils.cs b/MusicLyricApp/Utils/LyricUtils.cs index 598e4dd..b22166b 100644 --- a/MusicLyricApp/Utils/LyricUtils.cs +++ b/MusicLyricApp/Utils/LyricUtils.cs @@ -136,12 +136,6 @@ private static List SplitLrc(string lrc, SearchSourceEnum searchSou foreach (var line in temp) { - // 跳过空行 - if (string.IsNullOrWhiteSpace(line)) - { - continue; - } - // QQ 音乐歌词正式开始标识符 if (searchSource == SearchSourceEnum.QQ_MUSIC && "[offset:0]".Equals(line)) { @@ -150,15 +144,15 @@ private static List SplitLrc(string lrc, SearchSourceEnum searchSou } var lyricLineVo = new LyricLineVo(line); - - SetTimeStamp2Dot(lyricLineVo, dotType); - - // 跳过无效行 - if (string.IsNullOrWhiteSpace(lyricLineVo.Content)) + + // 跳过无效内容 + if (lyricLineVo.IsIllegalContent()) { continue; } + SetTimeStamp2Dot(lyricLineVo, dotType); + resultList.Add(lyricLineVo); } @@ -212,9 +206,9 @@ private static List MergeLrc(List originLrcs, List Date: Wed, 4 May 2022 15:49:45 +0800 Subject: [PATCH 3/5] fix lyric timestamp 2 dot bugs --- MusicLyricApp/Bean/MusicLyricsVO.cs | 130 ++++++++++++++---- MusicLyricApp/Utils/GlobalUtils.cs | 46 ------- MusicLyricApp/Utils/LyricUtils.cs | 42 ++++-- MusicLyricApp/Utils/RomajiUtils.cs | 3 +- MusicLyricAppTest/Bean/MusicLyricsVOTest.cs | 52 +++++++ MusicLyricAppTest/MusicLyricAppTest.csproj | 6 +- .../{GlobalUtils.cs => GlobalUtilsTest.cs} | 37 +---- MusicLyricAppTest/Utils/LyricUtilsTest.cs | 50 +++++++ .../Utils/{SrtUtils.cs => SrtUtilsTest.cs} | 2 +- 9 files changed, 236 insertions(+), 132 deletions(-) create mode 100644 MusicLyricAppTest/Bean/MusicLyricsVOTest.cs rename MusicLyricAppTest/Utils/{GlobalUtils.cs => GlobalUtilsTest.cs} (67%) create mode 100644 MusicLyricAppTest/Utils/LyricUtilsTest.cs rename MusicLyricAppTest/Utils/{SrtUtils.cs => SrtUtilsTest.cs} (96%) diff --git a/MusicLyricApp/Bean/MusicLyricsVO.cs b/MusicLyricApp/Bean/MusicLyricsVO.cs index ae4e084..298c4dc 100644 --- a/MusicLyricApp/Bean/MusicLyricsVO.cs +++ b/MusicLyricApp/Bean/MusicLyricsVO.cs @@ -2,6 +2,7 @@ using System.Collections.Generic; using System.ComponentModel; using System.Linq; +using System.Text; using System.Web; using MusicLyricApp.Exception; using MusicLyricApp.Utils; @@ -196,51 +197,62 @@ public bool IsEmpty() return string.IsNullOrEmpty(Lyric) && string.IsNullOrEmpty(TranslateLyric); } } - - /// - /// 当行歌词信息 - /// - public class LyricLineVo : IComparable + + public class LyricTimestamp : IComparable { - /// - /// 时间戳字符串 - /// - public string Timestamp { get; set; } + public int Minute { get; private set; } - /** - * 时间偏移量 - */ - public long TimeOffset { get; set; } + public string MinuteS { get; private set; } - /// - /// 歌词正文 - /// - public string Content { get; set; } + public int Second { get; private set; } - public LyricLineVo(string lyricLine) + public string SecondS { get; private set; } + + public int Millisecond { get; private set; } + + public string MillisecondS { get; private set; } + + public int TimeOffset { get;} + + public LyricTimestamp(string timestamp = "") { - var index = lyricLine.IndexOf("]"); - if (index == -1) + if (string.IsNullOrWhiteSpace(timestamp) || timestamp[0] != '[' || timestamp[timestamp.Length - 1] != ']') { - Timestamp = ""; - TimeOffset = -1; - Content = lyricLine; + // 不支持的格式 } else { - Timestamp = lyricLine.Substring(0, index + 1); - Content = lyricLine.Substring(index + 1); - TimeOffset = GlobalUtils.TimestampStrToLong(Timestamp); + timestamp = timestamp.Substring(1, timestamp.Length - 2); + + var split = timestamp.Split(':'); + + Minute = GlobalUtils.toInt(split[0], 0); + + split = split[1].Split('.'); + + Second = GlobalUtils.toInt(split[0], 0); + + if (split.Length > 1) + { + Millisecond = GlobalUtils.toInt(split[1], 0); + } } - } + + UpdateMinute(Minute); + UpdateSecond(Second); + UpdateMillisecond(Millisecond); - public LyricLineVo() + TimeOffset = (Minute * 60 + Second) * 1000 + Millisecond; + } + + public override string ToString() { + return "[" + MinuteS + ":" + SecondS + "." + MillisecondS + "]"; } public int CompareTo(object input) { - if (!(input is LyricLineVo obj)) + if (!(input is LyricTimestamp obj)) { throw new MusicLyricException(ErrorMsg.SYSTEM_ERROR); } @@ -260,7 +272,65 @@ public int CompareTo(object input) return 1; } - return (int) (TimeOffset - obj.TimeOffset); + return TimeOffset - obj.TimeOffset; + } + + private void UpdateMinute(int value) + { + Minute = value; + MinuteS = value.ToString("00"); + } + + private void UpdateSecond(int value) + { + Second = value; + SecondS = value.ToString("00"); + } + + public void UpdateMillisecond(int value, int scale = 3) + { + var format = new StringBuilder().Insert(0, "0", scale).ToString(); + + Millisecond = value; + MillisecondS = Millisecond.ToString(format); + } + } + + /// + /// 当行歌词信息 + /// + public class LyricLineVo : IComparable + { + public LyricTimestamp Timestamp { get; set; } + + /// + /// 歌词正文 + /// + public string Content { get; set; } + + public LyricLineVo(string lyricLine = "") + { + var index = lyricLine.IndexOf("]"); + if (index == -1) + { + Timestamp = new LyricTimestamp(""); + Content = lyricLine; + } + else + { + Timestamp = new LyricTimestamp(lyricLine.Substring(0, index + 1)); + Content = lyricLine.Substring(index + 1); + } + } + + public int CompareTo(object input) + { + if (!(input is LyricLineVo obj)) + { + throw new MusicLyricException(ErrorMsg.SYSTEM_ERROR); + } + + return Timestamp.CompareTo(obj.Timestamp); } /// diff --git a/MusicLyricApp/Utils/GlobalUtils.cs b/MusicLyricApp/Utils/GlobalUtils.cs index d48fc2d..5a22c99 100644 --- a/MusicLyricApp/Utils/GlobalUtils.cs +++ b/MusicLyricApp/Utils/GlobalUtils.cs @@ -106,52 +106,6 @@ private static bool CheckNum(string s) { return Regex.IsMatch(s, "^\\d+$"); } - - public static long TimestampStrToLong(string timestamp) - { - // 不支持的格式 - if (string.IsNullOrWhiteSpace(timestamp) || timestamp[0] != '[' || timestamp[timestamp.Length - 1] != ']') - { - return -1; - } - - timestamp = timestamp.Substring(1, timestamp.Length - 2); - - var split = timestamp.Split(':'); - - var min = toInt(split[0], 0); - - split = split[1].Split('.'); - - var second = toInt(split[0], 0); - - var ms = 0; - - if (split.Length > 1) - { - ms = toInt(split[1], 0); - } - - return (min * 60 + second) * 1000 + ms; - } - - public static string TimestampLongToStr(long timestamp, string msScale) - { - if (timestamp < 0) - { - throw new MusicLyricException(ErrorMsg.SYSTEM_ERROR); - } - - var ms = timestamp % 1000; - - timestamp /= 1000; - - var seconds = timestamp % 60; - - var min = timestamp / 60; - - return "[" + min.ToString("00") + ":" + seconds.ToString("00") + "." + ms.ToString(msScale) + "]"; - } /** * 获取输出文件名 diff --git a/MusicLyricApp/Utils/LyricUtils.cs b/MusicLyricApp/Utils/LyricUtils.cs index b22166b..585fe14 100644 --- a/MusicLyricApp/Utils/LyricUtils.cs +++ b/MusicLyricApp/Utils/LyricUtils.cs @@ -151,7 +151,7 @@ private static List SplitLrc(string lrc, SearchSourceEnum searchSou continue; } - SetTimeStamp2Dot(lyricLineVo, dotType); + SetMillisecondScale(lyricLineVo, dotType, 2); resultList.Add(lyricLineVo); } @@ -208,16 +208,16 @@ private static List MergeLrc(List originLrcs, List 0 && dotTypeEnum == DotTypeEnum.HALF_UP) + + var timestamp = vo.Timestamp; + + if (timestamp.MillisecondS.Length <= scale) { - round = round >= 5 ? 1 : 0; + return; } - if (round == 1) + var millisecond = timestamp.Millisecond; + + if (millisecond > 100) { - vo.TimeOffset = (vo.TimeOffset / 10 + round) * 10; + var round = 0; + if (dotTypeEnum == DotTypeEnum.HALF_UP) + { + if (millisecond % 10 >= 5) + { + round = 1; + } + } + + millisecond = millisecond / 10 + round; } - vo.Timestamp = GlobalUtils.TimestampLongToStr(vo.TimeOffset, "00"); + timestamp.UpdateMillisecond(millisecond, scale); } } } \ No newline at end of file diff --git a/MusicLyricApp/Utils/RomajiUtils.cs b/MusicLyricApp/Utils/RomajiUtils.cs index 3de9038..d45a65a 100644 --- a/MusicLyricApp/Utils/RomajiUtils.cs +++ b/MusicLyricApp/Utils/RomajiUtils.cs @@ -26,8 +26,7 @@ public static async Task> ToRomaji(List inputList resultList.Add(new LyricLineVo { Content = content, - Timestamp = vo.Timestamp, - TimeOffset = vo.TimeOffset + Timestamp = vo.Timestamp }); } diff --git a/MusicLyricAppTest/Bean/MusicLyricsVOTest.cs b/MusicLyricAppTest/Bean/MusicLyricsVOTest.cs new file mode 100644 index 0000000..8285c65 --- /dev/null +++ b/MusicLyricAppTest/Bean/MusicLyricsVOTest.cs @@ -0,0 +1,52 @@ +using MusicLyricApp.Bean; +using NUnit.Framework; + +namespace MusicLyricAppTest.Bean +{ + [TestFixture] + public class MusicLyricsVoTest + { + [Test] + public void TestLyricTimestamp() + { + // 空数据 && 不合法 + foreach (var scenario in new[] + { + new LyricTimestamp(), + new LyricTimestamp("[12131"), + new LyricTimestamp("-1]") + }) + { + Assert.AreEqual(0, scenario.Minute); + Assert.AreEqual(0, scenario.Second); + Assert.AreEqual(0, scenario.Millisecond); + + Assert.AreEqual("[00:00.000]", scenario.ToString()); + } + + // scenario1 [1:2.3] + var scenario1 = new LyricTimestamp("[1:2.3]"); + Assert.AreEqual(1, scenario1.Minute); + Assert.AreEqual(2, scenario1.Second); + Assert.AreEqual(3, scenario1.Millisecond); + + Assert.AreEqual("[01:02.003]", scenario1.ToString()); + + // scenario2 [00:39.17] + var scenario2 = new LyricTimestamp("[[00:39.17]"); + Assert.AreEqual(0, scenario2.Minute); + Assert.AreEqual(39, scenario2.Second); + Assert.AreEqual(17, scenario2.Millisecond); + + Assert.AreEqual("[00:39.017]", scenario2.ToString()); + + // scenario3 [00:39.17] + var scenario3 = new LyricTimestamp("[00:2]"); + Assert.AreEqual(0, scenario3.Minute); + Assert.AreEqual(2, scenario3.Second); + Assert.AreEqual(0, scenario3.Millisecond); + + Assert.AreEqual("[00:02.000]", scenario3.ToString()); + } + } +} \ No newline at end of file diff --git a/MusicLyricAppTest/MusicLyricAppTest.csproj b/MusicLyricAppTest/MusicLyricAppTest.csproj index 7d58b23..e5c76b4 100644 --- a/MusicLyricAppTest/MusicLyricAppTest.csproj +++ b/MusicLyricAppTest/MusicLyricAppTest.csproj @@ -41,8 +41,10 @@ - - + + + + diff --git a/MusicLyricAppTest/Utils/GlobalUtils.cs b/MusicLyricAppTest/Utils/GlobalUtilsTest.cs similarity index 67% rename from MusicLyricAppTest/Utils/GlobalUtils.cs rename to MusicLyricAppTest/Utils/GlobalUtilsTest.cs index 035ec48..04c2a01 100644 --- a/MusicLyricAppTest/Utils/GlobalUtils.cs +++ b/MusicLyricAppTest/Utils/GlobalUtilsTest.cs @@ -6,7 +6,7 @@ namespace MusicLyricAppTest.Utils { [TestFixture] - public class GlobalUtils + public class GlobalUtilsTest { [Test] public void TestCheckInputIdWithNumber() @@ -66,40 +66,5 @@ public void GetOutputNameTest() Assert.AreEqual("singer - name", GetOutputName(songVo, OutputFilenameTypeEnum.SINGER_NAME)); Assert.AreEqual("name", GetOutputName(songVo, OutputFilenameTypeEnum.NAME)); } - - [Test] - public void TestTimestampToLong() - { - // 不合法 - Assert.AreEqual(-1, TimestampStrToLong("")); - Assert.AreEqual(-1, TimestampStrToLong("[12131")); - Assert.AreEqual(-1, TimestampStrToLong("-1]")); - - // 合法 - Assert.AreEqual(62 * 1000 + 3, TimestampStrToLong("[1:2.3]")); - Assert.AreEqual((12 * 60 + 59) * 1000 + 311, TimestampStrToLong("[12:59.311]")); - - // [00:39.17] - Assert.AreEqual(39 * 1000 + 17, TimestampStrToLong("[00:39.17]")); - } - - [Test] - public void TestTimestampLongToStr() - { - // 非法 - Assert.Throws(() => TimestampLongToStr(-1, "00")); - - Assert.AreEqual("[00:00.000]", TimestampLongToStr(0, "000")); - - Assert.AreEqual("[00:00.00]", TimestampLongToStr(0, "00")); - - Assert.AreEqual("[01:02.003]", TimestampLongToStr(62 * 1000 + 3, "000")); - - Assert.AreEqual("[01:02.03]", TimestampLongToStr(62 * 1000 + 3, "00")); - - Assert.AreEqual("[12:59.311]", TimestampLongToStr((12 * 60 + 59) * 1000 + 311, "000")); - - Assert.AreEqual("[12:59.0311]", TimestampLongToStr((12 * 60 + 59) * 1000 + 311, "0000")); - } } } \ No newline at end of file diff --git a/MusicLyricAppTest/Utils/LyricUtilsTest.cs b/MusicLyricAppTest/Utils/LyricUtilsTest.cs new file mode 100644 index 0000000..b37ad8f --- /dev/null +++ b/MusicLyricAppTest/Utils/LyricUtilsTest.cs @@ -0,0 +1,50 @@ +using MusicLyricApp.Bean; +using MusicLyricApp.Utils; +using NUnit.Framework; + +namespace MusicLyricAppTest.Utils +{ + [TestFixture] + public class LyricUtilsTest + { + [Test] + public void TestSetTimeStamp2Dot() + { + var scenario1 = new LyricLineVo("[00:12.526]綺麗な嘘ごと自分を騙し続けて"); + + LyricUtils.SetMillisecondScale(scenario1, DotTypeEnum.HALF_UP, 2); + + Assert.AreEqual("[00:12.53]", scenario1.Timestamp.ToString()); + + var scenario2 = new LyricLineVo("[00:12.526]綺麗な嘘ごと自分を騙し続けて"); + + LyricUtils.SetMillisecondScale(scenario2, DotTypeEnum.DOWN, 2); + + Assert.AreEqual("[00:12.52]", scenario2.Timestamp.ToString()); + + var scenario3 = new LyricLineVo("[00:12.526]綺麗な嘘ごと自分を騙し続けて"); + + LyricUtils.SetMillisecondScale(scenario3, DotTypeEnum.DISABLE, 2); + + Assert.AreEqual("[00:12.526]", scenario3.Timestamp.ToString()); + + var scenario4 = new LyricLineVo("[00:12.523]綺麗な嘘ごと自分を騙し続けて"); + + LyricUtils.SetMillisecondScale(scenario4, DotTypeEnum.HALF_UP, 2); + + Assert.AreEqual("[00:12.52]", scenario4.Timestamp.ToString()); + + var scenario5 = new LyricLineVo("[00:00.000] 作词 : Kirara Magic"); + + LyricUtils.SetMillisecondScale(scenario5, DotTypeEnum.HALF_UP, 2); + + Assert.AreEqual("[00:00.00]", scenario5.Timestamp.ToString()); + + var scenario6 = new LyricLineVo("[01:10.050] 作词 : Kirara Magic"); + + LyricUtils.SetMillisecondScale(scenario6, DotTypeEnum.HALF_UP, 2); + + Assert.AreEqual("[01:10.50]", scenario6.Timestamp.ToString()); + } + } +} \ No newline at end of file diff --git a/MusicLyricAppTest/Utils/SrtUtils.cs b/MusicLyricAppTest/Utils/SrtUtilsTest.cs similarity index 96% rename from MusicLyricAppTest/Utils/SrtUtils.cs rename to MusicLyricAppTest/Utils/SrtUtilsTest.cs index ff22d23..b5b8d2d 100644 --- a/MusicLyricAppTest/Utils/SrtUtils.cs +++ b/MusicLyricAppTest/Utils/SrtUtilsTest.cs @@ -7,7 +7,7 @@ namespace MusicLyricAppTest.Utils { [TestFixture] - public class SrtUtils + public class SrtUtilsTest { [Test] public void TestJapaneseLanguageJudge() From 4a12aa6e0a32494d5ec29c24318e0342b3f1111c Mon Sep 17 00:00:00 2001 From: jitwxs Date: Wed, 4 May 2022 20:57:19 +0800 Subject: [PATCH 4/5] fix srt format bugs --- MusicLyricApp/Bean/MusicLyricsVO.cs | 57 ++++++++++---- MusicLyricApp/Utils/LyricUtils.cs | 30 ++----- MusicLyricApp/Utils/SrtUtils.cs | 116 +++++++++++++++------------- 3 files changed, 113 insertions(+), 90 deletions(-) diff --git a/MusicLyricApp/Bean/MusicLyricsVO.cs b/MusicLyricApp/Bean/MusicLyricsVO.cs index 298c4dc..bbf8f09 100644 --- a/MusicLyricApp/Bean/MusicLyricsVO.cs +++ b/MusicLyricApp/Bean/MusicLyricsVO.cs @@ -200,21 +200,38 @@ public bool IsEmpty() public class LyricTimestamp : IComparable { - public int Minute { get; private set; } + public long Minute { get; private set; } public string MinuteS { get; private set; } - public int Second { get; private set; } + public long Second { get; private set; } public string SecondS { get; private set; } - public int Millisecond { get; private set; } + public long Millisecond { get; private set; } public string MillisecondS { get; private set; } - public int TimeOffset { get;} + public long TimeOffset { get;} + + public LyricTimestamp(long millisecond) + { + TimeOffset = millisecond; + + Millisecond = millisecond % 1000; + + millisecond /= 1000; + + Second = millisecond % 60; + + Minute = millisecond / 60; + + UpdateMinute(Minute); + UpdateSecond(Second); + UpdateMillisecond(Millisecond); + } - public LyricTimestamp(string timestamp = "") + public LyricTimestamp(string timestamp) { if (string.IsNullOrWhiteSpace(timestamp) || timestamp[0] != '[' || timestamp[timestamp.Length - 1] != ']') { @@ -245,9 +262,16 @@ public LyricTimestamp(string timestamp = "") TimeOffset = (Minute * 60 + Second) * 1000 + Millisecond; } - public override string ToString() + public string ToString(OutputFormatEnum outputFormat) { - return "[" + MinuteS + ":" + SecondS + "." + MillisecondS + "]"; + if (outputFormat == OutputFormatEnum.LRC) + { + return "[" + MinuteS + ":" + SecondS + "." + MillisecondS + "]"; + } + else + { + return "00:" + MinuteS + ":" + SecondS + "," + MillisecondS; + } } public int CompareTo(object input) @@ -257,7 +281,7 @@ public int CompareTo(object input) throw new MusicLyricException(ErrorMsg.SYSTEM_ERROR); } - if (TimeOffset == -1 && obj.TimeOffset == -1) + if (TimeOffset == obj.TimeOffset) { return 0; } @@ -272,22 +296,29 @@ public int CompareTo(object input) return 1; } - return TimeOffset - obj.TimeOffset; + if (TimeOffset > obj.TimeOffset) + { + return 1; + } + else + { + return -1; + } } - private void UpdateMinute(int value) + private void UpdateMinute(long value) { Minute = value; MinuteS = value.ToString("00"); } - private void UpdateSecond(int value) + private void UpdateSecond(long value) { Second = value; SecondS = value.ToString("00"); } - public void UpdateMillisecond(int value, int scale = 3) + public void UpdateMillisecond(long value, int scale = 3) { var format = new StringBuilder().Insert(0, "0", scale).ToString(); @@ -353,7 +384,7 @@ public bool IsIllegalContent() public override string ToString() { - return Timestamp + Content; + return Timestamp.ToString(OutputFormatEnum.LRC) + Content; } } diff --git a/MusicLyricApp/Utils/LyricUtils.cs b/MusicLyricApp/Utils/LyricUtils.cs index 585fe14..dbedf92 100644 --- a/MusicLyricApp/Utils/LyricUtils.cs +++ b/MusicLyricApp/Utils/LyricUtils.cs @@ -1,6 +1,6 @@ using System; using System.Collections.Generic; -using System.Text; +using System.Linq; using System.Threading.Tasks; using MusicLyricApp.Bean; @@ -19,34 +19,16 @@ public abstract class LyricUtils /// public static async Task GetOutputContent(LyricVo lyricVo, SearchInfo searchInfo) { - var output = await GenerateOutput(lyricVo.Lyric, lyricVo.TranslateLyric, searchInfo); + var voList = await FormatLyric(lyricVo.Lyric, lyricVo.TranslateLyric, searchInfo); if (searchInfo.SettingBean.Param.OutputFileFormat == OutputFormatEnum.SRT) { - output = SrtUtils.LrcToSrt(output, lyricVo.Duration); + return SrtUtils.LrcToSrt(voList, lyricVo.Duration); } - - return output; - } - - /// - /// 生成输出结果 - /// - /// 原始的歌词内容 - /// 原始的译文内容 - /// 处理参数 - /// - private static async Task GenerateOutput(string originLyric, string originTLyric, SearchInfo searchInfo) - { - var formatLyrics = await FormatLyric(originLyric, originTLyric, searchInfo); - - var result = new StringBuilder(); - foreach (var i in formatLyrics) + else { - result.Append(i).Append(Environment.NewLine); + return string.Join(Environment.NewLine, from o in voList select o.ToString()); } - - return result.ToString(); } /// @@ -232,7 +214,7 @@ private static int Compare(LyricLineVo originLrc, LyricLineVo translateLrc, bool if (compareTo == 0) { - return hasOriginLrcPrior ? 1 : -1; + return hasOriginLrcPrior ? -1 : 1; } return compareTo; diff --git a/MusicLyricApp/Utils/SrtUtils.cs b/MusicLyricApp/Utils/SrtUtils.cs index c8ceba4..67f7153 100644 --- a/MusicLyricApp/Utils/SrtUtils.cs +++ b/MusicLyricApp/Utils/SrtUtils.cs @@ -1,6 +1,7 @@ using System; +using System.Collections.Generic; using System.Text; -using System.Text.RegularExpressions; +using MusicLyricApp.Bean; namespace MusicLyricApp.Utils { @@ -9,85 +10,94 @@ public static class SrtUtils /// /// 将 Lrc 格式,转换为 Srt 格式 /// - /// lrc 格式内容 + /// 歌词行数据 /// 时长 ms /// - public static string LrcToSrt(string input, long duration) + public static string LrcToSrt(List inputList, long duration) { - var output = new StringBuilder(); - - var startTime = new TimeSpan(); - var baseTime = startTime.Add(new TimeSpan(0, 0, 0, 0, 0)); - var preTime = baseTime; - var isFirstLine = true; - var preStr = string.Empty; - var timeReg = new Regex(@"(?<=^\[)(\d|\:|\.)+(?=])"); - var strReg = new Regex(@"(?<=]).+", RegexOptions.RightToLeft); - - var lines = input.Split(Environment.NewLine.ToCharArray()); - - var index = 1; + if (inputList.Count == 0) + { + return ""; + } - void AddSrtLine(TimeSpan curTime) + var index = 1; + var sb = new StringBuilder(); + + void AddLine(LyricTimestamp start, LyricTimestamp end, string content) { - output + sb .Append(index++) .Append(Environment.NewLine) - .Append($"{preTime.Hours:d2}:{preTime.Minutes:d2}:{preTime.Seconds:d2},{preTime.Milliseconds:d3}") - .Append(" --> ") - .Append($"{curTime.Hours:d2}:{curTime.Minutes:d2}:{curTime.Seconds:d2},{curTime.Milliseconds:d3}") + .Append(start.ToString(OutputFormatEnum.SRT)).Append(" --> ").Append(end.ToString(OutputFormatEnum.SRT)) .Append(Environment.NewLine) - .Append(preStr) + .Append(content) .Append(Environment.NewLine) .Append(Environment.NewLine); } - foreach (var line in lines) - { - if (string.IsNullOrWhiteSpace(line)) - continue; + var durationTimestamp = new LyricTimestamp(duration); - var match = timeReg.Match(line); - if (match.Success) + if (inputList.Count == 1) + { + AddLine(inputList[0].Timestamp, durationTimestamp, inputList[0].Content); + } + else + { + var i = 0; + for (; i < inputList.Count - 1; i++) { - if (isFirstLine) + LyricLineVo startVo = inputList[i], endVo = inputList[i + 1]; + + var compareTo = startVo.Timestamp.CompareTo(endVo.Timestamp); + + if (compareTo == 1) { - preTime = baseTime.Add(TimeSpan.Parse("00:" + match.Value)); - isFirstLine = false; + // start > end + AddLine(startVo.Timestamp, durationTimestamp, startVo.Content); } - else + else if (compareTo == 0) { - if (preStr != string.Empty) + // start == end + var endTimestamp = durationTimestamp; + + var j = i + 1; + while (++j < inputList.Count) { - var curTime = baseTime.Add(TimeSpan.Parse("00:" + match.Value)); - - AddSrtLine(curTime); + if (inputList[j].Timestamp.CompareTo(startVo.Timestamp) == 0) + { + continue; + } - preTime = curTime; + if (inputList[j].Timestamp.CompareTo(startVo.Timestamp) > 0) + { + endTimestamp = inputList[j].Timestamp; + } + + break; } - } - var strMatch = strReg.Match(line); - preStr = strMatch.Success ? strMatch.Value.Trim() : string.Empty; - } - else - { - var offsetReg = new Regex(@"(?<=^\[offset:)\d+(?=])"); - match = offsetReg.Match(line); - if (match.Success) + do + { + AddLine(inputList[i].Timestamp, endTimestamp, inputList[i].Content); + } while (++i < j); + + i--; + } + else { - var offset = Convert.ToInt32(match.Value); - baseTime = baseTime.Add(new TimeSpan(0, 0, 0, 0, offset)); + // start < end + AddLine(startVo.Timestamp, endVo.Timestamp, startVo.Content); } } - } - if (preStr != string.Empty) - { - AddSrtLine(TimeSpan.FromMilliseconds(duration)); + if (i < inputList.Count - 1) + { + var lastVo = inputList[inputList.Count - 1]; + AddLine(lastVo.Timestamp, durationTimestamp, lastVo.Content); + } } - return output.ToString(); + return sb.ToString(); } } } \ No newline at end of file From 244ee92165c92beb2d908f7ee57b8308b4d43dd0 Mon Sep 17 00:00:00 2001 From: jitwxs Date: Sun, 15 May 2022 11:36:03 +0800 Subject: [PATCH 5/5] update MusicLyricsVOTest.cs --- MusicLyricAppTest/Bean/MusicLyricsVOTest.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/MusicLyricAppTest/Bean/MusicLyricsVOTest.cs b/MusicLyricAppTest/Bean/MusicLyricsVOTest.cs index 8285c65..d9ce286 100644 --- a/MusicLyricAppTest/Bean/MusicLyricsVOTest.cs +++ b/MusicLyricAppTest/Bean/MusicLyricsVOTest.cs @@ -12,7 +12,7 @@ public void TestLyricTimestamp() // 空数据 && 不合法 foreach (var scenario in new[] { - new LyricTimestamp(), + new LyricTimestamp(""), new LyricTimestamp("[12131"), new LyricTimestamp("-1]") })