forked from LiteCoder/DoubanFM
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathLyricsShower.cs
158 lines (143 loc) · 5.26 KB
/
LyricsShower.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
/*
* Author : K.F.Storm
* Email : yk000123 at sina.com
* Website : http://www.kfstorm.com
* Reference : http://equinox1993.blog.163.com/blog/static/32205137201031141228418/
* */
using System;
using System.Collections.Generic;
namespace DoubanFM
{
/// <summary>
/// 管理歌词在桌面上的显示
/// </summary>
class LyricsShower
{
/// <summary>
/// 歌词本身
/// </summary>
protected Core.Lyrics Lyrics { get; private set; }
/// <summary>
/// 时间、歌词字典
/// </summary>
public Dictionary<TimeSpan, string> TimeAndLyrics { get; set; }
/// <summary>
/// 排过序的时间列表
/// </summary>
public List<TimeSpan> SortedTimes { get; private set; }
/// <summary>
/// 返回当前的歌词,使用前请先调用Refresh()函数
/// </summary>
public string CurrentLyrics { get; private set; }
/// <summary>
/// 返回下一个歌词,使用前请先调用Refresh()函数
/// </summary>
public string NextLyrics { get; private set; }
/// <summary>
/// 返回上一个歌词,使用前请先调用Refresh()函数
/// </summary>
public string PreviousLyrics { get; private set; }
/// <summary>
/// 返回当前歌词的Index,使用前请先调用Refresh()函数
/// </summary>
public int CurrentIndex { get; private set; }
private TimeSpan currentTime;
/// <summary>
/// 表示歌词显示的当前时刻(不同的时刻意味着不同的显示内容)
/// </summary>
public TimeSpan CurrentTime
{
get { return currentTime; }
set
{
if (currentTime != value)
{
currentTime = value;
Refresh();
}
}
}
/// <summary>
/// Initializes a new instance of the <see cref="LyricsShower"/> class.
/// </summary>
/// <param name="lyrics">歌词</param>
public LyricsShower(Core.Lyrics lyrics)
{
Lyrics = lyrics;
TimeAndLyrics = new Dictionary<TimeSpan, string>();
foreach (var pair in Lyrics.TimeAndLyrics)
{
TimeAndLyrics.Add(pair.Key - Lyrics.Offset, pair.Value);
}
SortedTimes = new List<TimeSpan>(TimeAndLyrics.Keys);
SortedTimes.Sort();
//当相邻的空歌词与非空歌词相差时间太大时,插入一行空歌词,
//以避免双行显示歌词时出现长时间第一行为空、第二行有字的情况。
Reset();
TimeSpan distance = TimeSpan.FromSeconds(2);
var addedTimes = new List<TimeSpan>();
for (int i = -1; i + 1 < SortedTimes.Count; ++i)
{
if (i == -1 && SortedTimes[0] == TimeSpan.Zero) continue;
var time1 = i == -1 ? TimeSpan.Zero : SortedTimes[i];
var time2 = SortedTimes[i + 1];
CurrentTime = time1;
if (time2 - time1 > distance)
{
if (string.IsNullOrWhiteSpace(CurrentLyrics) && !string.IsNullOrWhiteSpace(NextLyrics))
{
addedTimes.Add(time2 - distance);
}
}
}
foreach (var time in addedTimes)
{
TimeAndLyrics.Add(time, string.Empty);
}
SortedTimes = new List<TimeSpan>(TimeAndLyrics.Keys);
SortedTimes.Sort();
Reset();
}
/// <summary>
/// 根据当前时间刷新歌词状态
/// </summary>
protected void Refresh()
{
if (SortedTimes.Count == 0)
{
CurrentIndex = -1;
PreviousLyrics = null;
CurrentLyrics = null;
NextLyrics = null;
}
else
{
while (true)
{
if (CurrentIndex >= 0 && CurrentIndex < SortedTimes.Count && SortedTimes[CurrentIndex] > CurrentTime)
--CurrentIndex;
else if (CurrentIndex + 1 < SortedTimes.Count && SortedTimes[CurrentIndex + 1] <= CurrentTime)
++CurrentIndex;
else break;
}
if (CurrentIndex - 1 >= 0 && CurrentIndex - 1 < SortedTimes.Count)
PreviousLyrics = TimeAndLyrics[SortedTimes[CurrentIndex - 1]];
else PreviousLyrics = null;
if (CurrentIndex >= 0 && CurrentIndex < SortedTimes.Count)
CurrentLyrics = TimeAndLyrics[SortedTimes[CurrentIndex]];
else CurrentLyrics = null;
if (CurrentIndex + 1 >= 0 && CurrentIndex + 1 < SortedTimes.Count)
NextLyrics = TimeAndLyrics[SortedTimes[CurrentIndex + 1]];
else NextLyrics = null;
}
}
/// <summary>
/// 重置歌词状态
/// </summary>
public void Reset()
{
CurrentIndex = -1;
CurrentTime = TimeSpan.MinValue;
}
}
}