lyh 大爷给的音乐网站相当好用,但是上面的歌词下载下来全 tm 有问题啊。这严重影响了开摆的体验……

前置知识

lrc 文件

歌词文件的扩展名一般为 .lrc,电脑中的 music player 如 PotPlayer 在播放某音乐时会自动在与音乐文件相同的路径下查找同名 lrc 文件。如果查到,就会在播放音乐时同步渲染出歌词。
你可以直接用记事本打开 lrc 文件,然后就会发现里面的内容大约为这个格式:

1
2
[11:45.14]Wha↗t↘ can I↗↘say~
[19:19.81]Man↗ba↗ o↗ut~

[] 内的东西叫做时间戳,表示应该啥时候渲染出这一句歌词。而如果是中英双语的歌词,大概是这样的:

1
2
3
4
[11:45.14]Wha↗t↘ can I↗↘say~
[11:45.14]我能说什么
[19:19.81]Man↗ba↗ o↗ut~
[19:19.81]曼巴出来

对应的中文翻译的时间戳应当与英文的一样。

中文的编码方式

我们知道英文可以用 ASCII 码,每个字符 11 字节,然而中文的编码一般是每个字占 22 字节甚至更多,正常程序中对中文字符串的某位进行处理可能导致表示同一个字的多字节中的其中一个改变,而其他的没变,最终变为乱码。

问题分析

我们发现,从网站上下载下来的歌词文件长这样:

Take Me Hand-DAISHI DANCE&Cécile Corbel.lrc
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
[00:00.0]Take Me Hands - DAISHI DANCE/
[00:23.83]
[00:23.83]Lyrics by:Cecile Corbel
[00:36.89]
[00:36.89]Composed by:DAISHI DANCE/Tomoharu Moriya
[00:59.59]
[00:59.59]In my dreams
[01:01.49]在我的梦里
[01:01.49]I feel your light
[01:03.38]我感受到了你的光芒
[01:03.38]I feel love is born again
[01:07.01]我感受到了爱的重生
[01:07.01]Fireflies
[01:09.020004]萤火虫
[01:09.020004]In the moonlight
[01:10.84]在月光下
[01:10.84]Rising stars
[01:14.479996]随着星星闪耀
[01:14.479996]Remember
[01:16.979996]记住
[01:16.979996]The day
[01:19.11]这个日子
[01:19.11]I fell in love with you
[01:22.03]我与你相爱
[01:22.03]Darling won't you break
[01:26.12]亲爱的 你不会
[01:26.12]My heart
[01:29.979996]让我心碎
[01:29.979996]Take my hand now
[01:31.75]牵着我的手
[01:31.75]Stay close to me
[01:33.81]贴近我的心
[01:33.81]Be my lover
[01:35.68]做我的爱人
[01:35.68]Won't you let me go
[01:37.53]你不会让我离开
[01:37.53]Close your eyes now
[01:39.5]现在 闭上你的双眼
[01:39.5]And you will see
[01:41.34]你将会看到
[01:41.34]There's a rainbow
[01:43.21]有一道彩虹
[01:43.21]For you and me
[01:59.64]专属你我
[01:59.64]As I wake up
[02:01.58]当我醒来
[02:01.58]I see your face
[02:03.49]看着你的脸庞
[02:03.49]I feel love is born again
[02:07.02]我感受到了爱的重生
[02:07.02]Cherry blossom
[02:08.9]樱花烂漫
[02:08.9]Flying birds
[02:10.84]鸟儿飞翔
[02:10.84]In the sky
[02:14.64]在天空里
[02:14.64]Can't you see
[02:16.85]你是否看得见
[02:16.85]The sun
[02:18.34]阳光
[02:18.34]That is shining on the fields
[02:22.12]照射着大地
[02:22.12]Is it shining in
[02:26.33]它是否照射进
[02:26.33]Your heart
[02:29.99]你的心里
[02:29.99]Take my hand now
[02:31.75]牵着我的手
[02:31.75]Stay close to me
[02:33.81]贴近我的心
[02:33.81]Be my lover
[02:35.68]做我的爱人
[02:35.68]Won't you let me go
[02:37.54001]你不会让我离开
[02:37.54001]Close your eyes now
[02:39.52]现在 闭上你的双眼
[02:39.52]And you will see
[02:41.33]你将会看到
[02:41.33]There's a rainbow
[02:43.20999]有一道彩虹
[02:43.20999]For you and me
[02:59.65]专属你我
[02:59.65]And I dream of you
[03:03.36]我都梦见你
[03:03.36]Every night
[03:06.95]在每一个夜晚
[03:06.95]Cause's there only you
[03:10.9]因为 是否只有你
[03:10.9]In my mind
[03:14.49]在我的心里
[03:14.49]Will you be
[03:16.99]你会是
[03:16.99]A stranger or a friend in my life
[03:22.13]我生命中的陌生人 还是一个朋友
[03:22.13]Darling won't you break
[03:25.9]亲爱的 你不会
[03:25.9]My heart
[03:29.99]让我心碎
[03:29.99]Take my hand now
[03:31.75]牵着我的手
[03:31.75]Stay close to me
[03:33.83]贴近我的心
[03:33.83]Be my lover
[03:35.67]做我的爱人
[03:35.67]Won't you let me go
[03:37.52]你不会让我离开
[03:37.52]Close your eyes now
[03:39.47]现在 闭上你的双眼
[03:39.47]And you will see
[03:41.33]你将会看到
[03:41.33]There's a rainbow
[03:43.2]有一道彩虹
[03:43.2]For you and me
[03:45.0]专属你我
[03:45.0]Take my hand now
[03:46.75]牵着我的手
[03:46.75]Stay close to me
[03:48.8]贴近我的心
[03:48.8]Be my lover
[03:50.67]做我的爱人
[03:50.67]Won't you let me go
[03:52.52]你不会让我离开
[03:52.52]Close your eyes now
[03:54.51]现在 闭上你的双眼
[03:54.51]And you will see
[03:56.33]你将会看到
[03:56.33]There's a rainbow
[03:58.19]有一道彩虹
[03:58.19]For you and me
[03:59.7]专属你我
[03:59.7]Darling take my hand now
[04:02.3]牵着我的手
[04:02.3]Stay close to me
[04:03.86]贴近我的心
[04:03.86]Be my lover
[04:05.93]做我的爱人
[04:05.93]Won't you let me go
[04:07.35]不要放开我的手
[04:07.35]Close your eyes now
[04:08.76]现在 闭上你的双眼
[04:08.76]And you will see
[04:11.34]你将会看到
[04:11.34]There's a rainbow
[04:13.19]有一道彩虹
[04:13.19]For you and me
[04:13.21]专属你我

问题主要有两个:

  1. 全错位了,除了第一行,其他每行都应使用上一行的时间戳
  2. 有的时间戳长的吓人,这样的时间戳会导致渲染错误。经我实测,删掉后面多余的部分对渲染没有影响,所以我们直接丢弃超出正常长度的部分就行。

所以我们编写程序对这种格式错误进行修复。
为了解决中文乱码问题,我们使用 fstream 而不是传统的 I/O 方式。

code

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
#include<iostream>
#include<fstream>
using namespace std;
bool f=1;
int main(){
ifstream in(".lrc",ios::binary);
ofstream out("fixed.lrc",ios::binary);
out<<char(0xEF)<<char(0xBB)<<char(0xBF);//防中文乱码
string line,last_time;
while(getline(in,line)){
if(line.empty()){
out<<last_time<<'\n';
continue;
}
auto it=--line.end();
while(it!=line.begin()&&*it==' ')
line.erase(it--);//去除行末空格
string s;
int pos=0;
if(line[pos]=='['){
s.push_back(line[pos++]);
while(pos<(int)line.length()&&line[pos]!=']')
s.push_back(line[pos++]);
if(pos<(int)line.length())
s.push_back(line[pos++]);
}//截取时间戳
if(s.length()>9)
s.erase(9),s.push_back(']');//限制时间戳长度
string content;
while(pos<(int)line.length())
content.push_back(line[pos++]);
if(f){//第一行
out<<"[00:00.0]"<<content<<'\n';
f=0;
}
else if(!last_time.empty()||!content.empty())
out<<last_time<<content<<'\n';
last_time=s;
}
return 0;
}

使用流程

创建 cpp 文件 lrc_fix_tool.cpp 并编译,将待修复歌词的文件名改为 .lrc(这个时候顺便复制原歌词文件名),与 lrc_fix_tool.exe 放在同一路径,运行程序,在相同路径下生成修复好的 fixed.lrc,这时再重命名回去就好啦。
经实测,刚才的问题歌词修改后为:

Take Me Hand-DAISHI DANCE&Cécile Corbel.lrc
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
[00:00.0]Take Me Hands - DAISHI DANCE/
[00:00.0]
[00:23.83]Lyrics by:Cecile Corbel
[00:23.83]
[00:36.89]Composed by:DAISHI DANCE/Tomoharu Moriya
[00:36.89]
[00:59.59]In my dreams
[00:59.59]在我的梦里
[01:01.49]I feel your light
[01:01.49]我感受到了你的光芒
[01:03.38]I feel love is born again
[01:03.38]我感受到了爱的重生
[01:07.01]Fireflies
[01:07.01]萤火虫
[01:09.02]In the moonlight
[01:09.02]在月光下
[01:10.84]Rising stars
[01:10.84]随着星星闪耀
[01:14.47]Remember
[01:14.47]记住
[01:16.97]The day
[01:16.97]这个日子
[01:19.11]I fell in love with you
[01:19.11]我与你相爱
[01:22.03]Darling won't you break
[01:22.03]亲爱的 你不会
[01:26.12]My heart
[01:26.12]让我心碎
[01:29.97]Take my hand now
[01:29.97]牵着我的手
[01:31.75]Stay close to me
[01:31.75]贴近我的心
[01:33.81]Be my lover
[01:33.81]做我的爱人
[01:35.68]Won't you let me go
[01:35.68]你不会让我离开
[01:37.53]Close your eyes now
[01:37.53]现在 闭上你的双眼
[01:39.5]And you will see
[01:39.5]你将会看到
[01:41.34]There's a rainbow
[01:41.34]有一道彩虹
[01:43.21]For you and me
[01:43.21]专属你我
[01:59.64]As I wake up
[01:59.64]当我醒来
[02:01.58]I see your face
[02:01.58]看着你的脸庞
[02:03.49]I feel love is born again
[02:03.49]我感受到了爱的重生
[02:07.02]Cherry blossom
[02:07.02]樱花烂漫
[02:08.9]Flying birds
[02:08.9]鸟儿飞翔
[02:10.84]In the sky
[02:10.84]在天空里
[02:14.64]Can't you see
[02:14.64]你是否看得见
[02:16.85]The sun
[02:16.85]阳光
[02:18.34]That is shining on the fields
[02:18.34]照射着大地
[02:22.12]Is it shining in
[02:22.12]它是否照射进
[02:26.33]Your heart
[02:26.33]你的心里
[02:29.99]Take my hand now
[02:29.99]牵着我的手
[02:31.75]Stay close to me
[02:31.75]贴近我的心
[02:33.81]Be my lover
[02:33.81]做我的爱人
[02:35.68]Won't you let me go
[02:35.68]你不会让我离开
[02:37.54]Close your eyes now
[02:37.54]现在 闭上你的双眼
[02:39.52]And you will see
[02:39.52]你将会看到
[02:41.33]There's a rainbow
[02:41.33]有一道彩虹
[02:43.20]For you and me
[02:43.20]专属你我
[02:59.65]And I dream of you
[02:59.65]我都梦见你
[03:03.36]Every night
[03:03.36]在每一个夜晚
[03:06.95]Cause's there only you
[03:06.95]因为 是否只有你
[03:10.9]In my mind
[03:10.9]在我的心里
[03:14.49]Will you be
[03:14.49]你会是
[03:16.99]A stranger or a friend in my life
[03:16.99]我生命中的陌生人 还是一个朋友
[03:22.13]Darling won't you break
[03:22.13]亲爱的 你不会
[03:25.9]My heart
[03:25.9]让我心碎
[03:29.99]Take my hand now
[03:29.99]牵着我的手
[03:31.75]Stay close to me
[03:31.75]贴近我的心
[03:33.83]Be my lover
[03:33.83]做我的爱人
[03:35.67]Won't you let me go
[03:35.67]你不会让我离开
[03:37.52]Close your eyes now
[03:37.52]现在 闭上你的双眼
[03:39.47]And you will see
[03:39.47]你将会看到
[03:41.33]There's a rainbow
[03:41.33]有一道彩虹
[03:43.2]For you and me
[03:43.2]专属你我
[03:45.0]Take my hand now
[03:45.0]牵着我的手
[03:46.75]Stay close to me
[03:46.75]贴近我的心
[03:48.8]Be my lover
[03:48.8]做我的爱人
[03:50.67]Won't you let me go
[03:50.67]你不会让我离开
[03:52.52]Close your eyes now
[03:52.52]现在 闭上你的双眼
[03:54.51]And you will see
[03:54.51]你将会看到
[03:56.33]There's a rainbow
[03:56.33]有一道彩虹
[03:58.19]For you and me
[03:58.19]专属你我
[03:59.7]Darling take my hand now
[03:59.7]牵着我的手
[04:02.3]Stay close to me
[04:02.3]贴近我的心
[04:03.86]Be my lover
[04:03.86]做我的爱人
[04:05.93]Won't you let me go
[04:05.93]不要放开我的手
[04:07.35]Close your eyes now
[04:07.35]现在 闭上你的双眼
[04:08.76]And you will see
[04:08.76]你将会看到
[04:11.34]There's a rainbow
[04:11.34]有一道彩虹
[04:13.19]For you and me
[04:13.19]专属你我

打开 PotPlayer 播放,歌词正确渲染,问题解决。
如果是只有一种语言的歌词修个时间戳长度就好了。

其他

感谢 Kenba 提供“前置知识”部分的歌词。