diff --git a/MusicLyricApp/Bean/Constants.cs b/MusicLyricApp/Bean/Constants.cs index 85b5b61..ed0ed2a 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.4"; + public const string Version = "v4.5"; public static readonly string SettingPath = Environment.CurrentDirectory + "\\MusicLyricAppSetting.json"; diff --git a/MusicLyricApp/Bean/MusicLyricsVO.cs b/MusicLyricApp/Bean/MusicLyricsVO.cs index bbf8f09..07c146f 100644 --- a/MusicLyricApp/Bean/MusicLyricsVO.cs +++ b/MusicLyricApp/Bean/MusicLyricsVO.cs @@ -47,9 +47,8 @@ public enum SearchTypeEnum // 强制两位类型 public enum DotTypeEnum { - [Description("不启用")] DISABLE = 0, - [Description("截位")] DOWN = 1, - [Description("四舍五入")] HALF_UP = 2 + [Description("截位")] DOWN = 0, + [Description("四舍五入")] HALF_UP = 1 } // 输出文件格式 @@ -200,18 +199,12 @@ public bool IsEmpty() public class LyricTimestamp : IComparable { - public long Minute { get; private set; } + public long Minute { get; } - public string MinuteS { get; private set; } - - public long Second { get; private set; } + public long Second { get; } - public string SecondS { get; private set; } - - public long Millisecond { get; private set; } + public long Millisecond { get; } - public string MillisecondS { get; private set; } - public long TimeOffset { get;} public LyricTimestamp(long millisecond) @@ -225,10 +218,6 @@ public LyricTimestamp(long millisecond) Second = millisecond % 60; Minute = millisecond / 60; - - UpdateMinute(Minute); - UpdateSecond(Second); - UpdateMillisecond(Millisecond); } public LyricTimestamp(string timestamp) @@ -255,24 +244,8 @@ public LyricTimestamp(string timestamp) } } - 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) { @@ -306,24 +279,83 @@ public int CompareTo(object input) } } - private void UpdateMinute(long value) - { - Minute = value; - MinuteS = value.ToString("00"); - } - - private void UpdateSecond(long value) + public string PrintTimestamp(string timestampFormat, DotTypeEnum dotTypeEnum) { - Second = value; - SecondS = value.ToString("00"); + var output = timestampFormat; + + long actualMinute; + if (output.Contains("HH")) + { + var hour = Minute / 60; + actualMinute = Minute % 60; + output = output.Replace("HH", hour.ToString("00")); + } + else + { + actualMinute = Minute; + } + + if (output.Contains("mm")) + { + output = output.Replace("mm", actualMinute.ToString("00")); + } + + if (output.Contains("ss")) + { + output = output.Replace("ss", Second.ToString("00")); + } + + if (output.Contains("SSS")) + { + output = output.Replace("SSS", Millisecond.ToString("000")); + } + + if (output.Contains("SS")) + { + var actualMillisecond = AdjustMillisecondScale(2, dotTypeEnum); + output = output.Replace("SS", actualMillisecond.ToString("00")); + } + + if (output.Contains("S")) + { + var actualMillisecond = AdjustMillisecondScale(1, dotTypeEnum); + output = output.Replace("S", actualMillisecond.ToString("0")); + } + + return output; } - public void UpdateMillisecond(long value, int scale = 3) + /// + /// 调整毫秒位数 + /// + /// 位数,取值为 1 ~ 3 + /// 截位规则 + /// + private long AdjustMillisecondScale(int scale, DotTypeEnum dotTypeEnum) { - var format = new StringBuilder().Insert(0, "0", scale).ToString(); - - Millisecond = value; - MillisecondS = Millisecond.ToString(format); + var limit = 1; + for (var i = 0; i < scale; i++) + { + limit *= 10; + } + + var actualMillisecond = Millisecond; + + while (actualMillisecond >= limit) + { + var round = 0; + if (dotTypeEnum == DotTypeEnum.HALF_UP) + { + if (actualMillisecond % 10 >= 5) + { + round = 1; + } + } + + actualMillisecond = actualMillisecond / 10 + round; + } + + return actualMillisecond; } } @@ -339,7 +371,13 @@ public class LyricLineVo : IComparable /// public string Content { get; set; } - public LyricLineVo(string lyricLine = "") + public LyricLineVo(string content, LyricTimestamp timestamp) + { + Timestamp = timestamp; + Content = content; + } + + public LyricLineVo(string lyricLine) { var index = lyricLine.IndexOf("]"); if (index == -1) @@ -381,10 +419,10 @@ public bool IsIllegalContent() return false; } - - public override string ToString() + + public string Print(string timestampFormat, DotTypeEnum dotType) { - return Timestamp.ToString(OutputFormatEnum.LRC) + Content; + return Timestamp.PrintTimestamp(timestampFormat, dotType) + Content.Trim(); } } diff --git a/MusicLyricApp/Bean/SettingBase.cs b/MusicLyricApp/Bean/SettingBase.cs index 2cddb33..55d8c42 100644 --- a/MusicLyricApp/Bean/SettingBase.cs +++ b/MusicLyricApp/Bean/SettingBase.cs @@ -71,11 +71,21 @@ public class PersistParamBean /// 指定歌词合并的分隔符 /// public string LrcMergeSeparator = String.Empty; + + /// + /// LRC 歌词时间戳格式 + /// + public string LrcTimestampFormat = "[mm:ss.SSS]"; + + /// + /// SRT 歌词时间戳格式 + /// + public string SrtTimestampFormat = "HH:mm:ss,SSS"; /// /// 小数位处理策略 /// - public DotTypeEnum DotType = DotTypeEnum.DISABLE; + public DotTypeEnum DotType = DotTypeEnum.DOWN; /// /// 输出文件名类型 diff --git a/MusicLyricApp/MainForm.Designer.cs b/MusicLyricApp/MainForm.Designer.cs index 1d49811..c14009e 100644 --- a/MusicLyricApp/MainForm.Designer.cs +++ b/MusicLyricApp/MainForm.Designer.cs @@ -23,6 +23,16 @@ protected override void Dispose(bool disposing) base.Dispose(disposing); } + private void AfterInitializeComponent() + { + this.OutputName_ComboBox.Items.AddRange(GlobalUtils.GetEnumDescArray()); + this.LrcType_ComboBox.Items.AddRange(GlobalUtils.GetEnumDescArray()); + this.OutputEncoding_ComboBox.Items.AddRange(GlobalUtils.GetEnumDescArray()); + this.SearchType_ComboBox.Items.AddRange(GlobalUtils.GetEnumDescArray()); + this.OutputFormat_CombBox.Items.AddRange(new object[] { "LRC", "SRT" }); + this.SearchSource_ComboBox.Items.AddRange(GlobalUtils.GetEnumDescArray()); + } + #region Windows 窗体设计器生成的代码 /// @@ -57,8 +67,6 @@ private void InitializeComponent() this.Issue_MItem = new System.Windows.Forms.ToolStripMenuItem(); this.CheckVersion_MItem = new System.Windows.Forms.ToolStripMenuItem(); this.Setting_MItem = new System.Windows.Forms.ToolStripMenuItem(); - this.Dot_TextBox = new System.Windows.Forms.ComboBox(); - this.Dot_Label = new System.Windows.Forms.Label(); this.OutputFormat_Label = new System.Windows.Forms.Label(); this.OutputFormat_CombBox = new System.Windows.Forms.ComboBox(); this.SearchSource_ComboBox = new System.Windows.Forms.ComboBox(); @@ -106,7 +114,7 @@ private void InitializeComponent() // this.Search_Btn.Location = new System.Drawing.Point(387, 28); this.Search_Btn.Name = "Search_Btn"; - this.Search_Btn.Size = new System.Drawing.Size(93, 46); + this.Search_Btn.Size = new System.Drawing.Size(93, 73); this.Search_Btn.TabIndex = 2; this.Search_Btn.Text = "搜索 Enter"; this.Search_Btn.UseVisualStyleBackColor = true; @@ -126,7 +134,6 @@ private void InitializeComponent() // this.OutputName_ComboBox.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList; this.OutputName_ComboBox.FormattingEnabled = true; - this.OutputName_ComboBox.Items.AddRange(GlobalUtils.GetEnumDescArray()); this.OutputName_ComboBox.Location = new System.Drawing.Point(101, 374); this.OutputName_ComboBox.Name = "OutputName_ComboBox"; this.OutputName_ComboBox.Size = new System.Drawing.Size(101, 20); @@ -137,7 +144,6 @@ private void InitializeComponent() // this.LrcType_ComboBox.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList; this.LrcType_ComboBox.FormattingEnabled = true; - this.LrcType_ComboBox.Items.AddRange(GlobalUtils.GetEnumDescArray()); this.LrcType_ComboBox.Location = new System.Drawing.Point(89, 42); this.LrcType_ComboBox.Name = "LrcType_ComboBox"; this.LrcType_ComboBox.Size = new System.Drawing.Size(120, 20); @@ -148,7 +154,7 @@ private void InitializeComponent() // this.Search_Text.Location = new System.Drawing.Point(89, 80); this.Search_Text.Name = "Search_Text"; - this.Search_Text.Size = new System.Drawing.Size(120, 21); + this.Search_Text.Size = new System.Drawing.Size(204, 21); this.Search_Text.TabIndex = 1; // // OutputName_Label @@ -200,7 +206,6 @@ private void InitializeComponent() // this.OutputEncoding_ComboBox.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList; this.OutputEncoding_ComboBox.FormattingEnabled = true; - this.OutputEncoding_ComboBox.Items.AddRange(GlobalUtils.GetEnumDescArray()); this.OutputEncoding_ComboBox.Location = new System.Drawing.Point(100, 440); this.OutputEncoding_ComboBox.Name = "OutputEncoding_ComboBox"; this.OutputEncoding_ComboBox.Size = new System.Drawing.Size(102, 20); @@ -226,9 +231,9 @@ private void InitializeComponent() // // SongLink_Btn // - this.SongLink_Btn.Location = new System.Drawing.Point(387, 79); + this.SongLink_Btn.Location = new System.Drawing.Point(299, 80); this.SongLink_Btn.Name = "SongLink_Btn"; - this.SongLink_Btn.Size = new System.Drawing.Size(93, 22); + this.SongLink_Btn.Size = new System.Drawing.Size(70, 22); this.SongLink_Btn.TabIndex = 21; this.SongLink_Btn.Text = "歌曲链接"; this.SongLink_Btn.UseVisualStyleBackColor = true; @@ -238,7 +243,6 @@ private void InitializeComponent() // this.SearchType_ComboBox.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList; this.SearchType_ComboBox.FormattingEnabled = true; - this.SearchType_ComboBox.Items.AddRange(GlobalUtils.GetEnumDescArray()); this.SearchType_ComboBox.Location = new System.Drawing.Point(11, 81); this.SearchType_ComboBox.Name = "SearchType_ComboBox"; this.SearchType_ComboBox.Size = new System.Drawing.Size(62, 20); @@ -247,7 +251,12 @@ private void InitializeComponent() // // Top_MenuStrip // - this.Top_MenuStrip.Items.AddRange(new System.Windows.Forms.ToolStripItem[] { this.Home_MItem, this.Wiki_MItem, this.Issue_MItem, this.CheckVersion_MItem, this.Setting_MItem }); + this.Top_MenuStrip.Items.AddRange(new System.Windows.Forms.ToolStripItem[] { + this.Home_MItem, + this.Wiki_MItem, + this.Issue_MItem, + this.CheckVersion_MItem, + this.Setting_MItem}); this.Top_MenuStrip.Location = new System.Drawing.Point(0, 0); this.Top_MenuStrip.Name = "Top_MenuStrip"; this.Top_MenuStrip.Size = new System.Drawing.Size(492, 25); @@ -289,26 +298,6 @@ private void InitializeComponent() this.Setting_MItem.Text = "更多设置"; this.Setting_MItem.Click += new System.EventHandler(this.Top_MItem_Click); // - // Dot_TextBox - // - this.Dot_TextBox.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList; - this.Dot_TextBox.FormattingEnabled = true; - this.Dot_TextBox.Items.AddRange(GlobalUtils.GetEnumDescArray()); - this.Dot_TextBox.Location = new System.Drawing.Point(298, 80); - this.Dot_TextBox.Name = "Dot_TextBox"; - this.Dot_TextBox.Size = new System.Drawing.Size(71, 20); - this.Dot_TextBox.TabIndex = 26; - this.Dot_TextBox.SelectedIndexChanged += new System.EventHandler(this.Dot_TextBox_SelectedIndexChanged); - // - // Dot_Label - // - this.Dot_Label.AutoSize = true; - this.Dot_Label.Location = new System.Drawing.Point(222, 85); - this.Dot_Label.Name = "Dot_Label"; - this.Dot_Label.Size = new System.Drawing.Size(65, 12); - this.Dot_Label.TabIndex = 27; - this.Dot_Label.Text = "强制两位:"; - // // OutputFormat_Label // this.OutputFormat_Label.AutoSize = true; @@ -322,7 +311,6 @@ private void InitializeComponent() // this.OutputFormat_CombBox.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList; this.OutputFormat_CombBox.FormattingEnabled = true; - this.OutputFormat_CombBox.Items.AddRange(new object[] { "LRC", "SRT" }); this.OutputFormat_CombBox.Location = new System.Drawing.Point(100, 409); this.OutputFormat_CombBox.Name = "OutputFormat_CombBox"; this.OutputFormat_CombBox.Size = new System.Drawing.Size(102, 20); @@ -333,7 +321,6 @@ private void InitializeComponent() // this.SearchSource_ComboBox.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList; this.SearchSource_ComboBox.FormattingEnabled = true; - this.SearchSource_ComboBox.Items.AddRange(GlobalUtils.GetEnumDescArray()); this.SearchSource_ComboBox.Location = new System.Drawing.Point(11, 42); this.SearchSource_ComboBox.Name = "SearchSource_ComboBox"; this.SearchSource_ComboBox.Size = new System.Drawing.Size(62, 20); @@ -349,8 +336,6 @@ private void InitializeComponent() this.Controls.Add(this.SearchSource_ComboBox); this.Controls.Add(this.OutputFormat_CombBox); this.Controls.Add(this.OutputFormat_Label); - this.Controls.Add(this.Dot_Label); - this.Controls.Add(this.Dot_TextBox); this.Controls.Add(this.SearchType_ComboBox); this.Controls.Add(this.SongLink_Btn); this.Controls.Add(this.Album_TextBox); @@ -416,8 +401,6 @@ private void InitializeComponent() private System.Windows.Forms.ToolStripMenuItem CheckVersion_MItem; private System.Windows.Forms.ToolStripMenuItem Issue_MItem; private System.Windows.Forms.ToolStripMenuItem Wiki_MItem; - private System.Windows.Forms.ComboBox Dot_TextBox; - private System.Windows.Forms.Label Dot_Label; } } diff --git a/MusicLyricApp/MainForm.cs b/MusicLyricApp/MainForm.cs index cf86c3b..20cefa8 100644 --- a/MusicLyricApp/MainForm.cs +++ b/MusicLyricApp/MainForm.cs @@ -43,6 +43,8 @@ public MainForm() } InitializeComponent(); + AfterInitializeComponent(); + InitialConfig(); TrySetHighDPIFont("Segoe UI"); @@ -73,7 +75,6 @@ private void InitialConfig() LrcType_ComboBox.SelectedIndex = (int) paramConfig.ShowLrcType; SearchSource_ComboBox.SelectedIndex = (int) paramConfig.SearchSource; SearchType_ComboBox.SelectedIndex = (int) paramConfig.SearchType; - Dot_TextBox.SelectedIndex = (int) paramConfig.DotType; OutputFormat_CombBox.SelectedIndex = (int) paramConfig.OutputFileFormat; LrcMergeSeparator_TextBox.Text = paramConfig.LrcMergeSeparator; @@ -693,16 +694,6 @@ private void LrcMergeSeparator_TextBox_TextChanged(object sender, EventArgs e) UpdateLrcTextBox(string.Empty); } - /// - /// 小数位配置,变更事件 - /// - private void Dot_TextBox_SelectedIndexChanged(object sender, EventArgs e) - { - _globalSearchInfo.SettingBean.Param.DotType = (DotTypeEnum)Dot_TextBox.SelectedIndex; - ReloadConfig(); - UpdateLrcTextBox(string.Empty); - } - /// /// 控制台,键盘事件 /// @@ -781,9 +772,11 @@ private async void Top_MItem_Click(object sender, EventArgs e) { if (_settingForm == null || _settingForm.IsDisposed) { - _settingForm = new SettingForm(_globalSearchInfo.SettingBean.Config); - _settingForm.Location = new Point(Left + Constants.SettingFormOffset, Top + Constants.SettingFormOffset); - _settingForm.StartPosition = FormStartPosition.Manual; + _settingForm = new SettingForm(_globalSearchInfo.SettingBean) + { + Location = new Point(Left + Constants.SettingFormOffset, Top + Constants.SettingFormOffset), + StartPosition = FormStartPosition.Manual + }; _settingForm.Show(); } else diff --git a/MusicLyricApp/SettingForm.Designer.cs b/MusicLyricApp/SettingForm.Designer.cs index 4364c4b..4cbdeb2 100644 --- a/MusicLyricApp/SettingForm.Designer.cs +++ b/MusicLyricApp/SettingForm.Designer.cs @@ -25,6 +25,25 @@ protected override void Dispose(bool disposing) base.Dispose(disposing); } + private void AfterInitializeComponent() + { + this.RomajiMode_ComboBox.Items.AddRange(GlobalUtils.GetEnumDescArray()); + this.RomajiSystem_ComboBox.Items.AddRange(GlobalUtils.GetEnumDescArray()); + this.Dot_ComboBox.Items.AddRange(GlobalUtils.GetEnumDescArray()); + + RememberParam_CheckBox.Checked = _settingBean.Config.RememberParam; + AutoReadClipboard_CheckBox.Checked = _settingBean.Config.AutoReadClipboard; + AutoCheckUpdate_CheckBox.Checked = _settingBean.Config.AutoCheckUpdate; + + LrcTimestampFormat_TextBox.Text = _settingBean.Param.LrcTimestampFormat; + SrtTimestampFormat_TextBox.Text = _settingBean.Param.SrtTimestampFormat; + Dot_ComboBox.SelectedIndex = (int)_settingBean.Param.DotType; + + ShowRomaji_CheckBox.Checked = _settingBean.Config.RomajiConfig.Enable; + RomajiMode_ComboBox.SelectedIndex = (int)_settingBean.Config.RomajiConfig.ModeEnum; + RomajiSystem_ComboBox.SelectedIndex = (int)_settingBean.Config.RomajiConfig.SystemEnum; + } + #region Windows Form Designer generated code /// @@ -38,20 +57,26 @@ private void InitializeComponent() this.RememberParam_CheckBox = new System.Windows.Forms.CheckBox(); this.AutoReadClipboard_CheckBox = new System.Windows.Forms.CheckBox(); this.AutoCheckUpdate_CheckBox = new System.Windows.Forms.CheckBox(); - this.label1 = new System.Windows.Forms.Label(); this.ShowRomaji_CheckBox = new System.Windows.Forms.CheckBox(); this.RomajiMode_ComboBox = new System.Windows.Forms.ComboBox(); this.label3 = new System.Windows.Forms.Label(); this.label4 = new System.Windows.Forms.Label(); this.RomajiSystem_ComboBox = new System.Windows.Forms.ComboBox(); this.label2 = new System.Windows.Forms.Label(); + this.label5 = new System.Windows.Forms.Label(); + this.label6 = new System.Windows.Forms.Label(); + this.label7 = new System.Windows.Forms.Label(); + this.LrcTimestampFormat_TextBox = new System.Windows.Forms.TextBox(); + this.SrtTimestampFormat_TextBox = new System.Windows.Forms.TextBox(); + this.label8 = new System.Windows.Forms.Label(); + this.Dot_ComboBox = new System.Windows.Forms.ComboBox(); this.SuspendLayout(); // // Save_Btn // - this.Save_Btn.Location = new System.Drawing.Point(148, 161); + this.Save_Btn.Location = new System.Drawing.Point(294, 252); this.Save_Btn.Name = "Save_Btn"; - this.Save_Btn.Size = new System.Drawing.Size(166, 44); + this.Save_Btn.Size = new System.Drawing.Size(114, 44); this.Save_Btn.TabIndex = 0; this.Save_Btn.Text = "保存"; this.Save_Btn.UseVisualStyleBackColor = true; @@ -59,7 +84,7 @@ private void InitializeComponent() // // RememberParam_CheckBox // - this.RememberParam_CheckBox.Location = new System.Drawing.Point(12, 17); + this.RememberParam_CheckBox.Location = new System.Drawing.Point(15, 206); this.RememberParam_CheckBox.Name = "RememberParam_CheckBox"; this.RememberParam_CheckBox.Size = new System.Drawing.Size(78, 24); this.RememberParam_CheckBox.TabIndex = 1; @@ -68,7 +93,7 @@ private void InitializeComponent() // // AutoReadClipboard_CheckBox // - this.AutoReadClipboard_CheckBox.Location = new System.Drawing.Point(148, 15); + this.AutoReadClipboard_CheckBox.Location = new System.Drawing.Point(144, 206); this.AutoReadClipboard_CheckBox.Name = "AutoReadClipboard_CheckBox"; this.AutoReadClipboard_CheckBox.Size = new System.Drawing.Size(112, 26); this.AutoReadClipboard_CheckBox.TabIndex = 2; @@ -77,25 +102,16 @@ private void InitializeComponent() // // AutoCheckUpdate_CheckBox // - this.AutoCheckUpdate_CheckBox.Location = new System.Drawing.Point(12, 168); + this.AutoCheckUpdate_CheckBox.Location = new System.Drawing.Point(15, 259); this.AutoCheckUpdate_CheckBox.Name = "AutoCheckUpdate_CheckBox"; this.AutoCheckUpdate_CheckBox.Size = new System.Drawing.Size(97, 32); this.AutoCheckUpdate_CheckBox.TabIndex = 3; this.AutoCheckUpdate_CheckBox.Text = "自动检查更新"; this.AutoCheckUpdate_CheckBox.UseVisualStyleBackColor = true; // - // label1 - // - this.label1.BorderStyle = System.Windows.Forms.BorderStyle.Fixed3D; - this.label1.Location = new System.Drawing.Point(8, 49); - this.label1.Name = "label1"; - this.label1.Size = new System.Drawing.Size(315, 2); - this.label1.TabIndex = 4; - this.label1.Text = "label1"; - // // ShowRomaji_CheckBox // - this.ShowRomaji_CheckBox.Location = new System.Drawing.Point(12, 61); + this.ShowRomaji_CheckBox.Location = new System.Drawing.Point(15, 104); this.ShowRomaji_CheckBox.Name = "ShowRomaji_CheckBox"; this.ShowRomaji_CheckBox.Size = new System.Drawing.Size(120, 30); this.ShowRomaji_CheckBox.TabIndex = 5; @@ -107,15 +123,14 @@ private void InitializeComponent() // this.RomajiMode_ComboBox.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList; this.RomajiMode_ComboBox.FormattingEnabled = true; - this.RomajiMode_ComboBox.Items.AddRange(GlobalUtils.GetEnumDescArray()); - this.RomajiMode_ComboBox.Location = new System.Drawing.Point(232, 61); + this.RomajiMode_ComboBox.Location = new System.Drawing.Point(87, 148); this.RomajiMode_ComboBox.Name = "RomajiMode_ComboBox"; - this.RomajiMode_ComboBox.Size = new System.Drawing.Size(82, 20); + this.RomajiMode_ComboBox.Size = new System.Drawing.Size(100, 20); this.RomajiMode_ComboBox.TabIndex = 7; // // label3 // - this.label3.Location = new System.Drawing.Point(148, 66); + this.label3.Location = new System.Drawing.Point(13, 154); this.label3.Name = "label3"; this.label3.Size = new System.Drawing.Size(68, 18); this.label3.TabIndex = 8; @@ -123,7 +138,7 @@ private void InitializeComponent() // // label4 // - this.label4.Location = new System.Drawing.Point(148, 107); + this.label4.Location = new System.Drawing.Point(221, 151); this.label4.Name = "label4"; this.label4.Size = new System.Drawing.Size(68, 18); this.label4.TabIndex = 9; @@ -133,33 +148,97 @@ private void InitializeComponent() // this.RomajiSystem_ComboBox.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList; this.RomajiSystem_ComboBox.FormattingEnabled = true; - this.RomajiSystem_ComboBox.Items.AddRange(GlobalUtils.GetEnumDescArray()); - this.RomajiSystem_ComboBox.Location = new System.Drawing.Point(232, 107); + this.RomajiSystem_ComboBox.Location = new System.Drawing.Point(308, 148); this.RomajiSystem_ComboBox.Name = "RomajiSystem_ComboBox"; - this.RomajiSystem_ComboBox.Size = new System.Drawing.Size(82, 20); + this.RomajiSystem_ComboBox.Size = new System.Drawing.Size(100, 20); this.RomajiSystem_ComboBox.TabIndex = 10; // // label2 // this.label2.BorderStyle = System.Windows.Forms.BorderStyle.Fixed3D; - this.label2.Location = new System.Drawing.Point(12, 144); + this.label2.Location = new System.Drawing.Point(15, 87); this.label2.Name = "label2"; - this.label2.Size = new System.Drawing.Size(315, 2); + this.label2.Size = new System.Drawing.Size(410, 2); this.label2.TabIndex = 11; - this.label2.Text = "label2"; + this.label2.Text = "分割线"; + // + // label5 + // + this.label5.BorderStyle = System.Windows.Forms.BorderStyle.Fixed3D; + this.label5.Location = new System.Drawing.Point(15, 184); + this.label5.Name = "label5"; + this.label5.Size = new System.Drawing.Size(410, 2); + this.label5.TabIndex = 12; + this.label5.Text = "分割线"; + // + // label6 + // + this.label6.AutoSize = true; + this.label6.Location = new System.Drawing.Point(13, 15); + this.label6.Name = "label6"; + this.label6.Size = new System.Drawing.Size(65, 12); + this.label6.TabIndex = 13; + this.label6.Text = "LRC 时间戳"; + // + // label7 + // + this.label7.AutoSize = true; + this.label7.Location = new System.Drawing.Point(228, 15); + this.label7.Name = "label7"; + this.label7.Size = new System.Drawing.Size(65, 12); + this.label7.TabIndex = 14; + this.label7.Text = "SRT 时间戳"; + // + // LrcTimestampFormat_TextBox + // + this.LrcTimestampFormat_TextBox.Location = new System.Drawing.Point(108, 12); + this.LrcTimestampFormat_TextBox.Name = "LrcTimestampFormat_TextBox"; + this.LrcTimestampFormat_TextBox.Size = new System.Drawing.Size(100, 21); + this.LrcTimestampFormat_TextBox.TabIndex = 15; + // + // SrtTimestampFormat_TextBox + // + this.SrtTimestampFormat_TextBox.Location = new System.Drawing.Point(321, 12); + this.SrtTimestampFormat_TextBox.Name = "SrtTimestampFormat_TextBox"; + this.SrtTimestampFormat_TextBox.Size = new System.Drawing.Size(100, 21); + this.SrtTimestampFormat_TextBox.TabIndex = 16; + // + // label8 + // + this.label8.AutoSize = true; + this.label8.Location = new System.Drawing.Point(13, 54); + this.label8.Name = "label8"; + this.label8.Size = new System.Drawing.Size(77, 12); + this.label8.TabIndex = 17; + this.label8.Text = "毫秒截位规则"; + // + // Dot_ComboBox + // + this.Dot_ComboBox.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList; + this.Dot_ComboBox.FormattingEnabled = true; + this.Dot_ComboBox.Location = new System.Drawing.Point(108, 51); + this.Dot_ComboBox.Name = "Dot_ComboBox"; + this.Dot_ComboBox.Size = new System.Drawing.Size(100, 20); + this.Dot_ComboBox.TabIndex = 18; // // SettingForm // this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 12F); this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; - this.ClientSize = new System.Drawing.Size(328, 217); + this.ClientSize = new System.Drawing.Size(433, 321); + this.Controls.Add(this.Dot_ComboBox); + this.Controls.Add(this.label8); + this.Controls.Add(this.SrtTimestampFormat_TextBox); + this.Controls.Add(this.LrcTimestampFormat_TextBox); + this.Controls.Add(this.label7); + this.Controls.Add(this.label6); + this.Controls.Add(this.label5); this.Controls.Add(this.label2); this.Controls.Add(this.RomajiSystem_ComboBox); this.Controls.Add(this.label4); this.Controls.Add(this.label3); this.Controls.Add(this.RomajiMode_ComboBox); this.Controls.Add(this.ShowRomaji_CheckBox); - this.Controls.Add(this.label1); this.Controls.Add(this.AutoCheckUpdate_CheckBox); this.Controls.Add(this.AutoReadClipboard_CheckBox); this.Controls.Add(this.RememberParam_CheckBox); @@ -170,6 +249,7 @@ private void InitializeComponent() this.Name = "SettingForm"; this.Text = "设置"; this.ResumeLayout(false); + this.PerformLayout(); } private System.Windows.Forms.ComboBox RomajiSystem_ComboBox; @@ -182,8 +262,6 @@ private void InitializeComponent() private System.Windows.Forms.CheckBox ShowRomaji_CheckBox; - private System.Windows.Forms.Label label1; - private System.Windows.Forms.CheckBox AutoCheckUpdate_CheckBox; private System.Windows.Forms.CheckBox AutoReadClipboard_CheckBox; @@ -193,5 +271,13 @@ private void InitializeComponent() private System.Windows.Forms.Button Save_Btn; #endregion + + private System.Windows.Forms.Label label5; + private System.Windows.Forms.Label label6; + private System.Windows.Forms.Label label7; + private System.Windows.Forms.TextBox LrcTimestampFormat_TextBox; + private System.Windows.Forms.TextBox SrtTimestampFormat_TextBox; + private System.Windows.Forms.Label label8; + private System.Windows.Forms.ComboBox Dot_ComboBox; } } \ No newline at end of file diff --git a/MusicLyricApp/SettingForm.cs b/MusicLyricApp/SettingForm.cs index b089f91..8648906 100644 --- a/MusicLyricApp/SettingForm.cs +++ b/MusicLyricApp/SettingForm.cs @@ -8,35 +8,32 @@ namespace MusicLyricApp { public partial class SettingForm : Form { - private readonly ConfigBean _configBean; + private readonly SettingBean _settingBean; - public SettingForm(ConfigBean configBean) + public SettingForm(SettingBean settingBean) { - InitializeComponent(); - - _configBean = configBean; + _settingBean = settingBean; - RememberParam_CheckBox.Checked = _configBean.RememberParam; - AutoReadClipboard_CheckBox.Checked = _configBean.AutoReadClipboard; - AutoCheckUpdate_CheckBox.Checked = _configBean.AutoCheckUpdate; + InitializeComponent(); - var romajiConfig = _configBean.RomajiConfig; - ShowRomaji_CheckBox.Checked = romajiConfig.Enable; - RomajiMode_ComboBox.SelectedIndex = (int)romajiConfig.ModeEnum; - RomajiSystem_ComboBox.SelectedIndex = (int)romajiConfig.SystemEnum; + AfterInitializeComponent(); + ShowRomajiChangeListener(ShowRomaji_CheckBox.Checked); } private void Save_Btn_Click(object sender, EventArgs e) { - _configBean.RememberParam = RememberParam_CheckBox.Checked; - _configBean.AutoReadClipboard = AutoReadClipboard_CheckBox.Checked; - _configBean.AutoCheckUpdate = AutoCheckUpdate_CheckBox.Checked; + _settingBean.Config.RememberParam = RememberParam_CheckBox.Checked; + _settingBean.Config.AutoReadClipboard = AutoReadClipboard_CheckBox.Checked; + _settingBean.Config.AutoCheckUpdate = AutoCheckUpdate_CheckBox.Checked; + + _settingBean.Param.DotType = (DotTypeEnum)Dot_ComboBox.SelectedIndex; + _settingBean.Param.LrcTimestampFormat = LrcTimestampFormat_TextBox.Text; + _settingBean.Param.SrtTimestampFormat = SrtTimestampFormat_TextBox.Text; - var romajiConfig = _configBean.RomajiConfig; - romajiConfig.Enable = ShowRomaji_CheckBox.Checked; - romajiConfig.ModeEnum = (RomajiModeEnum)RomajiMode_ComboBox.SelectedIndex; - romajiConfig.SystemEnum = (RomajiSystemEnum)RomajiSystem_ComboBox.SelectedIndex; + _settingBean.Config.RomajiConfig.Enable = ShowRomaji_CheckBox.Checked; + _settingBean.Config.RomajiConfig.ModeEnum = (RomajiModeEnum)RomajiMode_ComboBox.SelectedIndex; + _settingBean.Config.RomajiConfig.SystemEnum = (RomajiSystemEnum)RomajiSystem_ComboBox.SelectedIndex; Close(); } diff --git a/MusicLyricApp/Utils/LyricUtils.cs b/MusicLyricApp/Utils/LyricUtils.cs index dbedf92..9c2d8ed 100644 --- a/MusicLyricApp/Utils/LyricUtils.cs +++ b/MusicLyricApp/Utils/LyricUtils.cs @@ -19,15 +19,19 @@ public abstract class LyricUtils /// public static async Task GetOutputContent(LyricVo lyricVo, SearchInfo searchInfo) { + var dotType = searchInfo.SettingBean.Param.DotType; + var voList = await FormatLyric(lyricVo.Lyric, lyricVo.TranslateLyric, searchInfo); if (searchInfo.SettingBean.Param.OutputFileFormat == OutputFormatEnum.SRT) { - return SrtUtils.LrcToSrt(voList, lyricVo.Duration); + var timestampFormat = searchInfo.SettingBean.Param.SrtTimestampFormat; + return SrtUtils.LrcToSrt(voList, timestampFormat, dotType, lyricVo.Duration); } else { - return string.Join(Environment.NewLine, from o in voList select o.ToString()); + var timestampFormat = searchInfo.SettingBean.Param.LrcTimestampFormat; + return string.Join(Environment.NewLine, from o in voList select o.Print(timestampFormat, dotType)); } } @@ -42,9 +46,8 @@ private static async Task> FormatLyric(string originLrc, strin { var showLrcType = searchInfo.SettingBean.Param.ShowLrcType; var searchSource = searchInfo.SettingBean.Param.SearchSource; - var dotType = searchInfo.SettingBean.Param.DotType; - var originLyrics = SplitLrc(originLrc, searchSource, dotType); + var originLyrics = SplitLrc(originLrc, searchSource); /* * 1、原文歌词不存在 @@ -60,7 +63,7 @@ private static async Task> FormatLyric(string originLrc, strin // 译文处理,启用罗马音进行转换,否则使用原始的译文 var romajiConfig = searchInfo.SettingBean.Config.RomajiConfig; - var translateLyrics = SplitLrc(translateLrc, searchSource, dotType); + var translateLyrics = SplitLrc(translateLrc, searchSource); if (romajiConfig.Enable) { @@ -106,7 +109,7 @@ private static async Task> FormatLyric(string originLrc, strin /** * 切割歌词 */ - private static List SplitLrc(string lrc, SearchSourceEnum searchSource, DotTypeEnum dotType) + private static List SplitLrc(string lrc, SearchSourceEnum searchSource) { // 换行符统一 var temp = lrc @@ -133,8 +136,6 @@ private static List SplitLrc(string lrc, SearchSourceEnum searchSou continue; } - SetMillisecondScale(lyricLineVo, dotType, 2); - resultList.Add(lyricLineVo); } @@ -219,41 +220,5 @@ private static int Compare(LyricLineVo originLrc, LyricLineVo translateLrc, bool return compareTo; } - - /** - * 设置毫秒位数 - */ - public static void SetMillisecondScale(LyricLineVo vo, DotTypeEnum dotTypeEnum, int scale) - { - if (dotTypeEnum == DotTypeEnum.DISABLE) - { - return; - } - - var timestamp = vo.Timestamp; - - if (timestamp.MillisecondS.Length <= scale) - { - return; - } - - var millisecond = timestamp.Millisecond; - - if (millisecond > 100) - { - var round = 0; - if (dotTypeEnum == DotTypeEnum.HALF_UP) - { - if (millisecond % 10 >= 5) - { - round = 1; - } - } - - millisecond = millisecond / 10 + round; - } - - timestamp.UpdateMillisecond(millisecond, scale); - } } } \ No newline at end of file diff --git a/MusicLyricApp/Utils/RomajiUtils.cs b/MusicLyricApp/Utils/RomajiUtils.cs index d45a65a..4df4856 100644 --- a/MusicLyricApp/Utils/RomajiUtils.cs +++ b/MusicLyricApp/Utils/RomajiUtils.cs @@ -23,11 +23,7 @@ public static async Task> ToRomaji(List inputList foreach (var vo in inputList) { var content = await converter.Convert(vo.Content, To.Romaji, mode, system, "(", ")"); - resultList.Add(new LyricLineVo - { - Content = content, - Timestamp = vo.Timestamp - }); + resultList.Add(new LyricLineVo(content, vo.Timestamp)); } return resultList; diff --git a/MusicLyricApp/Utils/SrtUtils.cs b/MusicLyricApp/Utils/SrtUtils.cs index 936f568..4bfc982 100644 --- a/MusicLyricApp/Utils/SrtUtils.cs +++ b/MusicLyricApp/Utils/SrtUtils.cs @@ -11,9 +11,11 @@ public static class SrtUtils /// 将 Lrc 格式,转换为 Srt 格式 /// /// 歌词行数据 + /// 时间戳格式 + /// 时间戳截位规则 /// 时长 ms /// - public static string LrcToSrt(List inputList, long duration) + public static string LrcToSrt(List inputList, string timestampFormat, DotTypeEnum dotType, long duration) { if (inputList.Count == 0) { @@ -28,7 +30,7 @@ void AddLine(LyricTimestamp start, LyricTimestamp end, string content) sb .Append(index++) .Append(Environment.NewLine) - .Append(start.ToString(OutputFormatEnum.SRT)).Append(" --> ").Append(end.ToString(OutputFormatEnum.SRT)) + .Append(start.PrintTimestamp(timestampFormat, dotType)).Append(" --> ").Append(end.PrintTimestamp(timestampFormat, dotType)) .Append(Environment.NewLine) .Append(content) .Append(Environment.NewLine) diff --git a/MusicLyricAppTest/Bean/LyricTimestampTest.cs b/MusicLyricAppTest/Bean/LyricTimestampTest.cs new file mode 100644 index 0000000..0cf490c --- /dev/null +++ b/MusicLyricAppTest/Bean/LyricTimestampTest.cs @@ -0,0 +1,78 @@ +using MusicLyricApp.Bean; +using NUnit.Framework; +using static NUnit.Framework.Assert; + +namespace MusicLyricAppTest.Bean +{ + [TestFixture] + public class LyricTimestampTest + { + [Test] + public void TestIllegalScenario() + { + // 空数据 && 不合法 + foreach (var scenario in new[] + { + new LyricTimestamp(""), + new LyricTimestamp("[12131"), + new LyricTimestamp("-1]") + }) + { + AreEqual(0, scenario.Minute); + AreEqual(0, scenario.Second); + AreEqual(0, scenario.Millisecond); + + AreEqual("[00:00.000]", scenario.PrintTimestamp("[mm:ss.SSS]", DotTypeEnum.DOWN)); + } + } + + [Test] + public void TestCreateByTimestamp() + { + // 05:16:02.305 + var bean = new LyricTimestamp(18962305L); + + AreEqual(18962305L, bean.TimeOffset); + AreEqual(316, bean.Minute); + AreEqual(2, bean.Second); + AreEqual(305, bean.Millisecond); + + AreEqual("[05:16:02+305]", bean.PrintTimestamp("[HH:mm:ss+SSS]", DotTypeEnum.HALF_UP)); + AreEqual("[316:02+305]", bean.PrintTimestamp("[mm:ss+SSS]", DotTypeEnum.DOWN)); + + AreEqual("[05:16:02:31]", bean.PrintTimestamp("[HH:mm:ss:SS]", DotTypeEnum.HALF_UP)); + AreEqual("[316:02:30]", bean.PrintTimestamp("[mm:ss:SS]", DotTypeEnum.DOWN)); + + AreEqual("[05H:16m:02s:3]", bean.PrintTimestamp("[HHH:mmm:sss:S]", DotTypeEnum.HALF_UP)); + AreEqual("[316@02@3]", bean.PrintTimestamp("[mm@ss@S]", DotTypeEnum.DOWN)); + } + + [Test] + public void TestCreateByTimestampStr() + { + // scenario1 [1:2.3] + var scenario1 = new LyricTimestamp("[1:2.3]"); + AreEqual(1, scenario1.Minute); + AreEqual(2, scenario1.Second); + AreEqual(3, scenario1.Millisecond); + + AreEqual("[01:02.003]", scenario1.PrintTimestamp("[mm:ss.SSS]", DotTypeEnum.DOWN)); + + // scenario2 [00:39.17] + var scenario2 = new LyricTimestamp("[[00:39.17]"); + AreEqual(0, scenario2.Minute); + AreEqual(39, scenario2.Second); + AreEqual(17, scenario2.Millisecond); + + AreEqual("[00:39.017]", scenario2.PrintTimestamp("[mm:ss.SSS]", DotTypeEnum.DOWN)); + + // scenario3 [00:39.17] + var scenario3 = new LyricTimestamp("[00:2]"); + AreEqual(0, scenario3.Minute); + AreEqual(2, scenario3.Second); + AreEqual(0, scenario3.Millisecond); + + AreEqual("[00:02.000]", scenario3.PrintTimestamp("[mm:ss.SSS]", DotTypeEnum.DOWN)); + } + } +} \ No newline at end of file diff --git a/MusicLyricAppTest/Bean/MusicLyricsVOTest.cs b/MusicLyricAppTest/Bean/MusicLyricsVOTest.cs index d9ce286..08e08a7 100644 --- a/MusicLyricAppTest/Bean/MusicLyricsVOTest.cs +++ b/MusicLyricAppTest/Bean/MusicLyricsVOTest.cs @@ -7,46 +7,31 @@ namespace MusicLyricAppTest.Bean public class MusicLyricsVoTest { [Test] - public void TestLyricTimestamp() + public void TestLyricLineVo() { - // 空数据 && 不合法 - 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); + var scenario1 = new LyricLineVo("[00:12.526]綺麗な嘘ごと自分を騙し続けて"); - Assert.AreEqual("[00:00.000]", scenario.ToString()); - } + Assert.AreEqual("[00:12.53]", scenario1.Timestamp.PrintTimestamp("[mm:ss.SS]", DotTypeEnum.HALF_UP)); - // 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); + var scenario2 = new LyricLineVo("[00:12.526]綺麗な嘘ごと自分を騙し続けて"); - Assert.AreEqual("[01:02.003]", scenario1.ToString()); + Assert.AreEqual("[00:12.52]", scenario2.Timestamp.PrintTimestamp("[mm:ss.SS]", DotTypeEnum.DOWN)); - // 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); + var scenario3 = new LyricLineVo("[00:12.526]綺麗な嘘ごと自分を騙し続けて"); + + Assert.AreEqual("[00:12.526]", scenario3.Timestamp.PrintTimestamp("[mm:ss.SSS]", DotTypeEnum.DOWN)); - Assert.AreEqual("[00:39.017]", scenario2.ToString()); + var scenario4 = new LyricLineVo("[00:12.523]綺麗な嘘ごと自分を騙し続けて"); + + Assert.AreEqual("[00:12.52]", scenario4.Timestamp.PrintTimestamp("[mm:ss.SS]", DotTypeEnum.HALF_UP)); - // 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); + var scenario5 = new LyricLineVo("[00:00.000] 作词 : Kirara Magic"); + + Assert.AreEqual("[00:00.00]", scenario5.Timestamp.PrintTimestamp("[mm:ss.SS]", DotTypeEnum.HALF_UP)); - Assert.AreEqual("[00:02.000]", scenario3.ToString()); + var scenario6 = new LyricLineVo("[01:10.050] 作词 : Kirara Magic"); + + Assert.AreEqual("[01:10.50]", scenario6.Timestamp.PrintTimestamp("[mm:ss.SS]", DotTypeEnum.HALF_UP)); } } } \ No newline at end of file diff --git a/MusicLyricAppTest/MusicLyricAppTest.csproj b/MusicLyricAppTest/MusicLyricAppTest.csproj index e5c76b4..e63ca54 100644 --- a/MusicLyricAppTest/MusicLyricAppTest.csproj +++ b/MusicLyricAppTest/MusicLyricAppTest.csproj @@ -41,9 +41,9 @@ + - diff --git a/MusicLyricAppTest/Utils/LyricUtilsTest.cs b/MusicLyricAppTest/Utils/LyricUtilsTest.cs deleted file mode 100644 index f505ecc..0000000 --- a/MusicLyricAppTest/Utils/LyricUtilsTest.cs +++ /dev/null @@ -1,50 +0,0 @@ -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(OutputFormatEnum.LRC)); - - var scenario2 = new LyricLineVo("[00:12.526]綺麗な嘘ごと自分を騙し続けて"); - - LyricUtils.SetMillisecondScale(scenario2, DotTypeEnum.DOWN, 2); - - Assert.AreEqual("[00:12.52]", scenario2.Timestamp.ToString(OutputFormatEnum.LRC)); - - var scenario3 = new LyricLineVo("[00:12.526]綺麗な嘘ごと自分を騙し続けて"); - - LyricUtils.SetMillisecondScale(scenario3, DotTypeEnum.DISABLE, 2); - - Assert.AreEqual("[00:12.526]", scenario3.Timestamp.ToString(OutputFormatEnum.LRC)); - - var scenario4 = new LyricLineVo("[00:12.523]綺麗な嘘ごと自分を騙し続けて"); - - LyricUtils.SetMillisecondScale(scenario4, DotTypeEnum.HALF_UP, 2); - - Assert.AreEqual("[00:12.52]", scenario4.Timestamp.ToString(OutputFormatEnum.LRC)); - - var scenario5 = new LyricLineVo("[00:00.000] 作词 : Kirara Magic"); - - LyricUtils.SetMillisecondScale(scenario5, DotTypeEnum.HALF_UP, 2); - - Assert.AreEqual("[00:00.00]", scenario5.Timestamp.ToString(OutputFormatEnum.LRC)); - - var scenario6 = new LyricLineVo("[01:10.050] 作词 : Kirara Magic"); - - LyricUtils.SetMillisecondScale(scenario6, DotTypeEnum.HALF_UP, 2); - - Assert.AreEqual("[01:10.50]", scenario6.Timestamp.ToString(OutputFormatEnum.LRC)); - } - } -} \ No newline at end of file