Skip to content

Commit 734787d

Browse files
authored
Merge pull request #111 from jitwxs/dev
Release v4.7
2 parents a860cc5 + cfea5a6 commit 734787d

File tree

5 files changed

+112
-121
lines changed

5 files changed

+112
-121
lines changed

MusicLyricApp/Bean/Constants.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ namespace MusicLyricApp.Bean
44
{
55
public static class Constants
66
{
7-
public const string Version = "v4.6";
7+
public const string Version = "v4.7";
88

99
public static readonly string SettingPath = Environment.CurrentDirectory + "\\MusicLyricAppSetting.json";
1010

MusicLyricApp/Bean/MusicLyricsVO.cs

Lines changed: 54 additions & 63 deletions
Original file line numberDiff line numberDiff line change
@@ -207,52 +207,40 @@ public bool IsEmpty()
207207

208208
public class LyricTimestamp : IComparable
209209
{
210-
public long Minute { get; }
211-
212-
public long Second { get; }
213-
214-
public long Millisecond { get; }
215-
216210
public long TimeOffset { get;}
217211

218212
public LyricTimestamp(long millisecond)
219213
{
220214
TimeOffset = millisecond;
221-
222-
Millisecond = millisecond % 1000;
223-
224-
millisecond /= 1000;
225-
226-
Second = millisecond % 60;
227-
228-
Minute = millisecond / 60;
229215
}
230216

231217
public LyricTimestamp(string timestamp)
232218
{
233219
if (string.IsNullOrWhiteSpace(timestamp) || timestamp[0] != '[' || timestamp[timestamp.Length - 1] != ']')
234220
{
235221
// 不支持的格式
222+
TimeOffset = 0;
236223
}
237224
else
238225
{
239226
timestamp = timestamp.Substring(1, timestamp.Length - 2);
240227

241228
var split = timestamp.Split(':');
242229

243-
Minute = GlobalUtils.toInt(split[0], 0);
230+
var minute = GlobalUtils.toInt(split[0], 0);
244231

245232
split = split[1].Split('.');
246233

247-
Second = GlobalUtils.toInt(split[0], 0);
234+
var second = GlobalUtils.toInt(split[0], 0);
235+
236+
TimeOffset = (minute * 60 + second) * 1000;
248237

249238
if (split.Length > 1)
250239
{
251-
Millisecond = GlobalUtils.toInt(split[1], 0);
240+
// 三位毫秒,右填充 0
241+
TimeOffset += GlobalUtils.toInt(split[1].PadRight(3, '0'), 0);
252242
}
253243
}
254-
255-
TimeOffset = (Minute * 60 + Second) * 1000 + Millisecond;
256244
}
257245

258246
public int CompareTo(object input)
@@ -287,20 +275,58 @@ public int CompareTo(object input)
287275
}
288276
}
289277

290-
public string PrintTimestamp(string timestampFormat, DotTypeEnum dotTypeEnum)
278+
public string PrintTimestamp(string timestampFormat, DotTypeEnum dotType)
291279
{
292280
var output = timestampFormat;
293281

282+
int msDigit;
283+
if (output.Contains("SSS"))
284+
{
285+
msDigit = 3;
286+
} else if (output.Contains("SS"))
287+
{
288+
msDigit = 2;
289+
} else if (output.Contains("S"))
290+
{
291+
msDigit = 1;
292+
}
293+
else
294+
{
295+
msDigit = 3;
296+
}
297+
298+
long offset;
299+
if (msDigit == 3)
300+
{
301+
offset = TimeOffset;
302+
}
303+
else
304+
{
305+
if (dotType == DotTypeEnum.DOWN)
306+
{
307+
offset = TimeOffset / 10 * 10;
308+
}
309+
else
310+
{
311+
offset = (TimeOffset + 5) / 10 * 10;
312+
}
313+
}
314+
315+
var ms = offset % 1000;
316+
offset /= 1000;
317+
var minute = offset / 60;
318+
var second = offset - minute * 60;
319+
294320
long actualMinute;
295321
if (output.Contains("HH"))
296322
{
297-
var hour = Minute / 60;
298-
actualMinute = Minute % 60;
323+
var hour = minute / 60;
324+
actualMinute = minute % 60;
299325
output = output.Replace("HH", hour.ToString("00"));
300326
}
301327
else
302328
{
303-
actualMinute = Minute;
329+
actualMinute = minute;
304330
}
305331

306332
if (output.Contains("mm"))
@@ -310,61 +336,26 @@ public string PrintTimestamp(string timestampFormat, DotTypeEnum dotTypeEnum)
310336

311337
if (output.Contains("ss"))
312338
{
313-
output = output.Replace("ss", Second.ToString("00"));
339+
output = output.Replace("ss", second.ToString("00"));
314340
}
315-
341+
316342
if (output.Contains("SSS"))
317343
{
318-
output = output.Replace("SSS", Millisecond.ToString("000"));
344+
output = output.Replace("SSS", ms.ToString("000"));
319345
}
320346

321347
if (output.Contains("SS"))
322348
{
323-
var actualMillisecond = AdjustMillisecondScale(2, dotTypeEnum);
324-
output = output.Replace("SS", actualMillisecond.ToString("00"));
349+
output = output.Replace("SS", (ms / 10).ToString("00"));
325350
}
326351

327352
if (output.Contains("S"))
328353
{
329-
var actualMillisecond = AdjustMillisecondScale(1, dotTypeEnum);
330-
output = output.Replace("S", actualMillisecond.ToString("0"));
354+
output = output.Replace("S", (ms / 100).ToString("0"));
331355
}
332356

333357
return output;
334358
}
335-
336-
/// <summary>
337-
/// 调整毫秒位数
338-
/// </summary>
339-
/// <param name="scale">位数,取值为 1 ~ 3</param>
340-
/// <param name="dotTypeEnum">截位规则</param>
341-
/// <returns></returns>
342-
private long AdjustMillisecondScale(int scale, DotTypeEnum dotTypeEnum)
343-
{
344-
var limit = 1;
345-
for (var i = 0; i < scale; i++)
346-
{
347-
limit *= 10;
348-
}
349-
350-
var actualMillisecond = Millisecond;
351-
352-
while (actualMillisecond >= limit)
353-
{
354-
var round = 0;
355-
if (dotTypeEnum == DotTypeEnum.HALF_UP)
356-
{
357-
if (actualMillisecond % 10 >= 5)
358-
{
359-
round = 1;
360-
}
361-
}
362-
363-
actualMillisecond = actualMillisecond / 10 + round;
364-
}
365-
366-
return actualMillisecond;
367-
}
368359
}
369360

370361
/// <summary>

MusicLyricApp/Utils/LyricUtils.cs

Lines changed: 36 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,8 @@ private static async Task<List<LyricLineVo>> FormatLyric(string originLrc, strin
6565

6666
var translateLyrics = SplitLrc(translateLrc, searchSource);
6767

68+
translateLyrics = DealTranslateLyricDefaultRule(originLyrics, translateLyrics, searchInfo.SettingBean.Config.TranslateLyricDefaultRule);
69+
6870
if (romajiConfig.Enable)
6971
{
7072
translateLyrics = await RomajiUtils.ToRomaji(originLyrics, translateLyrics, romajiConfig);
@@ -106,7 +108,7 @@ private static async Task<List<LyricLineVo>> FormatLyric(string originLrc, strin
106108
throw new NotSupportedException("not support showLrcType: " + showLrcType);
107109
}
108110

109-
return DealTranslateLyricDefaultRule(res, searchInfo.SettingBean.Config.TranslateLyricDefaultRule);
111+
return res;
110112
}
111113

112114
/**
@@ -212,49 +214,33 @@ private static List<LyricLineVo> MergeLrc(List<LyricLineVo> originList, List<Lyr
212214
/**
213215
* 译文缺省逻辑处理
214216
*/
215-
private static List<LyricLineVo> DealTranslateLyricDefaultRule(List<LyricLineVo> voList, TranslateLyricDefaultRuleEnum rule)
217+
private static List<LyricLineVo> DealTranslateLyricDefaultRule(List<LyricLineVo> originList, List<LyricLineVo> translateList, TranslateLyricDefaultRuleEnum rule)
216218
{
217-
if (rule != TranslateLyricDefaultRuleEnum.IGNORE)
219+
if (rule == TranslateLyricDefaultRuleEnum.IGNORE)
218220
{
219-
var timestampCounts = new Dictionary<long, int>();
220-
221-
foreach (var key in voList.Select(one => one.Timestamp.TimeOffset))
222-
{
223-
if (timestampCounts.ContainsKey(key))
224-
{
225-
timestampCounts[key] += 1;
226-
}
227-
else
228-
{
229-
timestampCounts.Add(key,1);
230-
}
231-
}
221+
return translateList;
222+
}
232223

233-
var dealTimestamps = (from pair in timestampCounts where pair.Value == 1 select pair.Key).ToList();
234-
dealTimestamps.Sort((a, b) => a.CompareTo(b));
224+
var originTimeOffsetMap = ConvertLyricLineVoListToMapByTimeOffset(originList);
225+
var translateTimeOffsetMap = ConvertLyricLineVoListToMapByTimeOffset(translateList);
226+
227+
foreach (var pair in translateTimeOffsetMap.Where(pair => originTimeOffsetMap.ContainsKey(pair.Key)))
228+
{
229+
originTimeOffsetMap.Remove(pair.Key);
230+
}
231+
232+
foreach (var pair in originTimeOffsetMap)
233+
{
234+
var content = rule == TranslateLyricDefaultRuleEnum.FILL_ORIGIN ? pair.Value.Content : "";
235235

236-
var dealTimestampIndex = 0;
237-
238-
for (var i = 0; i < voList.Count; i++)
239-
{
240-
var cur = voList[i];
241-
var timestamp = dealTimestamps[dealTimestampIndex];
242-
243-
if (cur.Timestamp.TimeOffset == timestamp)
244-
{
245-
var content = rule == TranslateLyricDefaultRuleEnum.FILL_ORIGIN ? cur.Content : "";
246-
voList.Insert(++i, new LyricLineVo(content, cur.Timestamp));
247-
dealTimestampIndex++;
248-
249-
if (dealTimestampIndex >= dealTimestamps.Count)
250-
{
251-
break;
252-
}
253-
}
254-
}
236+
translateTimeOffsetMap[pair.Key] = new LyricLineVo(content, pair.Value.Timestamp);
255237
}
238+
239+
var res = new List<LyricLineVo>(translateTimeOffsetMap.Values);
240+
241+
res.Sort();
256242

257-
return voList;
243+
return res;
258244
}
259245

260246
/**
@@ -271,5 +257,17 @@ private static int Compare(LyricLineVo originLrc, LyricLineVo translateLrc, bool
271257

272258
return compareTo;
273259
}
260+
261+
private static Dictionary<long, LyricLineVo> ConvertLyricLineVoListToMapByTimeOffset(List<LyricLineVo> lyricLineVos)
262+
{
263+
var map = new Dictionary<long, LyricLineVo>();
264+
265+
foreach (var one in lyricLineVos)
266+
{
267+
map[one.Timestamp.TimeOffset] = one;
268+
}
269+
270+
return map;
271+
}
274272
}
275273
}

MusicLyricAppTest/Bean/LyricTimestampTest.cs

Lines changed: 20 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -18,10 +18,6 @@ public void TestIllegalScenario()
1818
new LyricTimestamp("-1]")
1919
})
2020
{
21-
AreEqual(0, scenario.Minute);
22-
AreEqual(0, scenario.Second);
23-
AreEqual(0, scenario.Millisecond);
24-
2521
AreEqual("[00:00.000]", scenario.PrintTimestamp("[mm:ss.SSS]", DotTypeEnum.DOWN));
2622
}
2723
}
@@ -33,9 +29,6 @@ public void TestCreateByTimestamp()
3329
var bean = new LyricTimestamp(18962305L);
3430

3531
AreEqual(18962305L, bean.TimeOffset);
36-
AreEqual(316, bean.Minute);
37-
AreEqual(2, bean.Second);
38-
AreEqual(305, bean.Millisecond);
3932

4033
AreEqual("[05:16:02+305]", bean.PrintTimestamp("[HH:mm:ss+SSS]", DotTypeEnum.HALF_UP));
4134
AreEqual("[316:02+305]", bean.PrintTimestamp("[mm:ss+SSS]", DotTypeEnum.DOWN));
@@ -52,27 +45,36 @@ public void TestCreateByTimestampStr()
5245
{
5346
// scenario1 [1:2.3]
5447
var scenario1 = new LyricTimestamp("[1:2.3]");
55-
AreEqual(1, scenario1.Minute);
56-
AreEqual(2, scenario1.Second);
57-
AreEqual(3, scenario1.Millisecond);
5848

59-
AreEqual("[01:02.003]", scenario1.PrintTimestamp("[mm:ss.SSS]", DotTypeEnum.DOWN));
49+
AreEqual("[01:02.300]", scenario1.PrintTimestamp("[mm:ss.SSS]", DotTypeEnum.DOWN));
6050

6151
// scenario2 [00:39.17]
6252
var scenario2 = new LyricTimestamp("[[00:39.17]");
63-
AreEqual(0, scenario2.Minute);
64-
AreEqual(39, scenario2.Second);
65-
AreEqual(17, scenario2.Millisecond);
6653

67-
AreEqual("[00:39.017]", scenario2.PrintTimestamp("[mm:ss.SSS]", DotTypeEnum.DOWN));
54+
AreEqual("[00:39.170]", scenario2.PrintTimestamp("[mm:ss.SSS]", DotTypeEnum.DOWN));
6855

6956
// scenario3 [00:39.17]
7057
var scenario3 = new LyricTimestamp("[00:2]");
71-
AreEqual(0, scenario3.Minute);
72-
AreEqual(2, scenario3.Second);
73-
AreEqual(0, scenario3.Millisecond);
7458

7559
AreEqual("[00:02.000]", scenario3.PrintTimestamp("[mm:ss.SSS]", DotTypeEnum.DOWN));
7660
}
61+
62+
[Test]
63+
public void TestIssue109()
64+
{
65+
var scenario = new LyricTimestamp("[04:17.995]");
66+
67+
AreEqual("[04:18.00]", scenario.PrintTimestamp("[mm:ss.SS]", DotTypeEnum.HALF_UP));
68+
69+
scenario = new LyricTimestamp("[04:19.093]");
70+
71+
AreEqual("[04:19.09]", scenario.PrintTimestamp("[mm:ss.SS]", DotTypeEnum.HALF_UP));
72+
73+
scenario = new LyricTimestamp("[00:10.98]");
74+
75+
AreEqual("[00:10.980]", scenario.PrintTimestamp("[mm:ss.SSS]", DotTypeEnum.DOWN));
76+
77+
AreEqual("[00:10.980]", scenario.PrintTimestamp("[mm:ss.SSS]", DotTypeEnum.HALF_UP));
78+
}
7779
}
7880
}

MusicLyricAppTest/Bean/MusicLyricsVOTest.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ public void TestLyricLineVo()
3131

3232
var scenario6 = new LyricLineVo("[01:10.050] 作词 : Kirara Magic");
3333

34-
Assert.AreEqual("[01:10.50]", scenario6.Timestamp.PrintTimestamp("[mm:ss.SS]", DotTypeEnum.HALF_UP));
34+
Assert.AreEqual("[01:10.05]", scenario6.Timestamp.PrintTimestamp("[mm:ss.SS]", DotTypeEnum.HALF_UP));
3535
}
3636
}
3737
}

0 commit comments

Comments
 (0)