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/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"; diff --git a/MusicLyricApp/Bean/MusicLyricsVO.cs b/MusicLyricApp/Bean/MusicLyricsVO.cs index af42cb5..bbf8f09 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,76 +197,194 @@ public bool IsEmpty() return string.IsNullOrEmpty(Lyric) && string.IsNullOrEmpty(TranslateLyric); } } + + public class LyricTimestamp : IComparable + { + public long Minute { get; private set; } + + public string MinuteS { get; private set; } + + public long Second { get; private set; } + + public string SecondS { get; private set; } + + public long Millisecond { get; private set; } + + public string MillisecondS { get; private set; } + + 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) + { + if (string.IsNullOrWhiteSpace(timestamp) || timestamp[0] != '[' || timestamp[timestamp.Length - 1] != ']') + { + // 不支持的格式 + } + else + { + 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); + + TimeOffset = (Minute * 60 + Second) * 1000 + Millisecond; + } + + public string ToString(OutputFormatEnum outputFormat) + { + if (outputFormat == OutputFormatEnum.LRC) + { + return "[" + MinuteS + ":" + SecondS + "." + MillisecondS + "]"; + } + else + { + return "00:" + MinuteS + ":" + SecondS + "," + MillisecondS; + } + } + + public int CompareTo(object input) + { + if (!(input is LyricTimestamp obj)) + { + throw new MusicLyricException(ErrorMsg.SYSTEM_ERROR); + } + + if (TimeOffset == obj.TimeOffset) + { + return 0; + } + + if (TimeOffset == -1) + { + return -1; + } + + if (obj.TimeOffset == -1) + { + return 1; + } + + if (TimeOffset > obj.TimeOffset) + { + return 1; + } + else + { + return -1; + } + } + + private void UpdateMinute(long value) + { + Minute = value; + MinuteS = value.ToString("00"); + } + + private void UpdateSecond(long value) + { + Second = value; + SecondS = value.ToString("00"); + } + + public void UpdateMillisecond(long value, int scale = 3) + { + var format = new StringBuilder().Insert(0, "0", scale).ToString(); + + Millisecond = value; + MillisecondS = Millisecond.ToString(format); + } + } /// /// 当行歌词信息 /// public class LyricLineVo : IComparable { - /// - /// 时间戳字符串 - /// - public string Timestamp { get; set; } - - /** - * 时间偏移量 - */ - public long TimeOffset { get; set; } + public LyricTimestamp Timestamp { get; set; } /// /// 歌词正文 /// public string Content { get; set; } - public LyricLineVo(string lyricLine) + public LyricLineVo(string lyricLine = "") { var index = lyricLine.IndexOf("]"); if (index == -1) { - Timestamp = ""; - TimeOffset = -1; + Timestamp = new LyricTimestamp(""); Content = lyricLine; } else { - Timestamp = lyricLine.Substring(0, index + 1); + Timestamp = new LyricTimestamp(lyricLine.Substring(0, index + 1)); Content = lyricLine.Substring(index + 1); - TimeOffset = GlobalUtils.TimestampStrToLong(Timestamp); } } - public LyricLineVo() - { - } - public int CompareTo(object input) { if (!(input is LyricLineVo obj)) { throw new MusicLyricException(ErrorMsg.SYSTEM_ERROR); } - - if (TimeOffset == -1 && obj.TimeOffset == -1) - { - return 0; - } - - if (TimeOffset == -1) + + return Timestamp.CompareTo(obj.Timestamp); + } + + /// + /// 是否是无效的内容 + /// + public bool IsIllegalContent() + { + if (string.IsNullOrWhiteSpace(Content)) { - return -1; + return true; } - if (obj.TimeOffset == -1) + if ("//".Equals(Content)) { - return 1; + return true; } - return (int) (TimeOffset - obj.TimeOffset); + return false; } - + public override string ToString() { - return Timestamp + Content; + return Timestamp.ToString(OutputFormatEnum.LRC) + 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/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 598e4dd..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(); } /// @@ -136,12 +118,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 +126,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; } + SetMillisecondScale(lyricLineVo, dotType, 2); + resultList.Add(lyricLineVo); } @@ -212,18 +188,18 @@ 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/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 diff --git a/MusicLyricAppTest/Bean/MusicLyricsVOTest.cs b/MusicLyricAppTest/Bean/MusicLyricsVOTest.cs new file mode 100644 index 0000000..d9ce286 --- /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()