论文部分内容阅读
摘要:论述了如何利用Delphi开发LRC歌词编辑器,包括LRC歌词的编辑、显示以及保存。
关键词:LRC;Mp3;歌词编辑
中图分类号:TP311文献标识码:A 文章编号:1009-3044(2007)18-31663-04
Using Delphi development LRC lyrics Editor
WU Chao-bin
(Fujian College of Water Conservancy Electirc Power,Yong'an 366000,China)
Abstract: Discusses how to use Delphi development LRC lyrics editor, including lyrics of the LRC editing, display and preservation.
Key words:LRC; MP3; lyrics editing
1 引言
LRC歌词是一种包含着“[min:sec:msec]”形式的时间标签的、基于纯文本的歌词专用格式。因为是基于纯文本的格式,所以在电脑上能够方便的编辑。其中的时间标签“[min:sec:msec]”就是用于说明本句歌词在什么时候需要显示(min是分钟值、sec是秒钟值,msec是毫秒值)。例如,以下是阿杜《他一定很爱你》的LRC歌词
[ti:他一定很爱你]
[ar:阿杜]
[al:]
[offset:-100]
[00:03.31]他一定很爱你
[00:34.24]我躲在车里 手握著香槟
[00:38.42]想要给你 生日的惊喜
[00:43.44]你越走越近 有两个声音
[00:47.62]我措手不及 只得楞在那里
[00:56.81][01:53.65]我应该在车底 不应该在车里
[01:01.83][01:57.83]看到你们有多甜蜜
[01:06.01][02:02.69]这样一来我也 比较容易死心
[01:11.02][02:07.86]给我离开的勇气
[01:16.04][02:14.55][02:49.66]他一定很爱你 别把我比下去
[01:22.72][02:19.57][02:54.68]分手也只用了一分钟而已
[01:27.74][02:23.75][02:58.86]他一定很爱你 比我会讨好你
[01:32.76][02:28.76][03:03.87]不会像我这样孩子气 为难着你
其中:offset表示时间整体偏移量,正值表示时间往后偏移,负值表示时间往前偏移。
2 程序实现
2.1 程序界面
图1
2.2 歌词编辑方法
首先打开MP3文件,再打开对应的歌词文件(TXT或LRC格式)。单击“播放”按钮,开始播放歌曲,播放歌曲时,在相应的时间标签上单击,即可将当前时间添加至时间标签。歌曲播放完毕后,此时单击时间标签,不会将当前时间添加至时间标签,这样可以修改有错误的时间标签。
2.3 MP3文件的播放以及LRC歌词的显示
为了便于歌词的编辑以及观察编辑的歌词的时间标签是否有误,程序要能够播放MP3文件并能显示LRC歌词。播放MP3文件,这里使用ActiveX控件中的Windows Media Player。安装方法为:单击“Component”菜单下的“Import ActiveX Control …”,在弹出的对话框中选择“Windows Media Player”,将类名改为“TMediaPlay”然后单击“install”按钮。
2.3.1 以下是播放歌曲时将LRC歌词读到数组mgc中的代码。数组mgc中,mgc[i,1],mgc[i,2],mgc[i,3],mgc[i,4]用来存放时间标签,mgc[i,5]用来存放对应的歌词。
procedure TForm1.PlaySpeedButtonClick(Sender: TObject);
varfname,s,s1:string;
F:textFile;
min,sec,msec,i,j,l:integer;
begin
if fileexists(combobox1.Text) then
begin
try
Form1.MediaPlay1.FileName:=ComboBox1.Text;
Form1.MediaPlay1.Play;
l:=round(Form1.MediaPlay1.Duration*1000);
Trackbar1.Max:=l div 1000;
//显示歌曲总时间
min:=ldiv 1000 div 60;
sec:=l div 1000 -min*60;
Form1.Label2.Caption:=format('%2u:%2u',[min,sec]);
Timer1.Enabled:=true;
canclick:=true;
except
begin
timer1.Enabled:=false;
canclick:=false;
messagedlg('不支持的文件格式或其他程序占用音频设备!',mtError,[mbYes],0);
end;
end;
end
else
begin
showmessage('文件不存在!');
timer1.Enabled:=false;
end;
fname:=changeFileExt(ComboBox1.text,'.lrc');
if fileexists(fname) then
begin
toolbar2.Visible:=true;
AssignFile(F, fname);
Reset(F);
//读歌词
mgcn:=0;
moffset:=0;
for i:=1 to 100 do
for j:=1 to 5 do
mgc[i,j]:='';
while not eof(F) do
begin
readln(F,s);
s:=trim(s);
l:=length(s);
s1:=copy(s,2,6);moffset:=0;
if (l>10) and (s1='offset') then moffset:=StrToInt(copy(s,9,l-9));
if (l>10)and (s[3]>='0') and (s[3]<='9') and (s[1]='[') and (s[10]=']') and (s[11]<>'[') then
begin
mgcn:=mgcn+1;
msec:=StrToInt(copy(s,2,2))*60*1000+StrToInt(copy(s,5,2))*1000+
StrToInt(copy(s,8,2))*10;
mgc[mgcn,1]:=IntToStr(msec);
mgc[mgcn,5]:=copy(s,11,l);
end;
if (l>20)and(s[1]='[') and (s[10]=']') and
(s[11]='[') and (s[20]=']') and(s[21]<>'[') then
begin
mgcn:=mgcn+1;
msec:=StrToInt(copy(s,2,2))*60*1000+StrToInt(copy(s,5,2))*1000+
StrToInt(copy(s,8,2))*10;
mgc[mgcn,1]:=IntToStr(msec);
msec:=StrToInt(copy(s,12,2))*60*1000+StrToInt(copy(s,15,2))*1000+
StrToInt(copy(s,18,2))*10;
mgc[mgcn,2]:=IntToStr(msec);
mgc[mgcn,5]:=copy(s,21,l);
end;
if (l>30)and(s[1]='[') and (s[10]=']') and
(s[11]='[') and (s[20]=']') and
(s[21]='[') and (s[30]=']') and
(s[31]<>'[') then
begin
mgcn:=mgcn+1;
msec:=StrToInt(copy(s,2,2))*60*1000+StrToInt(copy(s,5,2))*1000+
StrToInt(copy(s,8,2))*10;
mgc[mgcn,1]:=IntToStr(msec);
msec:=StrToInt(copy(s,12,2))*60*1000+StrToInt(copy(s,15,2))*1000+
StrToInt(copy(s,18,2))*10;
mgc[mgcn,2]:=IntToStr(msec);
msec:=StrToInt(copy(s,22,2))*60*1000+StrToInt(copy(s,25,2))*1000+
StrToInt(copy(s,28,2))*10;
mgc[mgcn,3]:=IntToStr(msec);
mgc[mgcn,5]:=copy(s,31,l);
end;
if (l>40)and(s[1]='[') and (s[10]=']') and
(s[11]='[') and (s[20]=']') and
(s[21]='[') and (s[30]=']') and
(s[31]='[') and (s[40]=']') and
(s[41]<>'[') then
begin
mgcn:=mgcn+1;
msec:=StrToInt(copy(s,2,2))*60*1000+StrToInt(copy(s,5,2))*1000+
StrToInt(copy(s,8,2))*10;
mgc[mgcn,1]:=IntToStr(msec);
msec:=StrToInt(copy(s,12,2))*60*1000+StrToInt(copy(s,15,2))*1000+
StrToInt(copy(s,18,2))*10;
mgc[mgcn,2]:=IntToStr(msec);
msec:=StrToInt(copy(s,22,2))*60*1000+StrToInt(copy(s,25,2))*1000+
StrToInt(copy(s,28,2))*10;
mgc[mgcn,3]:=IntToStr(msec);
msec:=StrToInt(copy(s,32,2))*60*1000+StrToInt(copy(s,35,2))*1000+
StrToInt(copy(s,38,2))*10;
mgc[mgcn,4]:=IntToStr(msec);
mgc[mgcn,5]:=copy(s,41,l);
end;
end;
//读歌词结束
closefile(F);
Timer2.Enabled:=true;
end
else
begin
toolbar2.Visible:=false;
Timer2.Enabled:=false;
end;
end;
2.3.2 歌词编辑是否正确,需要进行验证,以下是利用时间控件,在label3标签中显示LRC歌词的代码
procedure TForm1.Timer2Timer(Sender: TObject);
var msec,i,j,l:integer;
begin
l:=round(Form1.MediaPlay1.CurrentPosition*1000);
//在Label3中显示歌词
for i:=1 to mgcn do
for j:=1 to 4 do
begin
if mgc[i,j]<>'' then
begin
msec:=StrToInt(mgc[i,j]);
if abs(msec-l-moffset)<150 then
Label3.Caption:=mgc[i,5];
end;
end;
end;
2.4 编辑LRC歌词的代码
2.4.1 将歌词读入网格中
procedure TForm1.OpenFSpeedButtonClick(Sender: TObject);
var F:textfile;
s,s1,ti,ar,al,offset:string;
gc:array [1..100,1..5] of string;
i,j,l,gcn:integer;
begin
OpenDialog1.Filter:='文本文件(*.txt)|*.txt|歌词文件(*.lrc)|*.lrc';
if OpenDialog1.Execute then
begin
if Opendialog1.FilterIndex=1 then
begin
//读取txt文件格式,将歌词放到网格中
AssignFile(F, OpenDialog1.FileName);
Reset(F);
for i:=1 to StringGrid1.RowCount-1 do
for j:=0 to StringGrid1.ColCount-1 do
StringGrid1.Cells[j,i]:='';
i:=1;
while not eof(F) do
begin
readln(F,s);
s:=trim(s);
if s<>'' then
begin
i:=i+1;
StringGrid1.RowCount:=i;
StringGrid1.Cells[4,i-1]:=s;
end;
end;
closefile(F);
end
else
begin
AssignFile(F, OpenDialog1.FileName);
Reset(F);
//读LRC歌词,将时间标签和歌词读到数组 gc 中
gcn:=0;
ar:=''; ti:=''; al:=''; offset:='';
for i:=1 to 100 do
for j:=1 to 5 do
gc[i,j]:='';
while not eof(F) do
begin
readln(F,s);
s:=trim(s);
l:=length(s);
s1:=copy(s,2,2) ;
if s1='ar' then ar:=copy(s,5,l-5);
if s1='ti' then ti:=copy(s,5,l-5);
if s1='al' then al:=copy(s,5,l-5);
s1:=copy(s,2,6);
if s1='offset' then offset:=copy(s,9,l-9);
if (l>10)and(s[1]='[') and (s[10]=']') and (s[11]<>'[') then
begin
gcn:=gcn+1;
gc[gcn,1]:=copy(s,1,10);
gc[gcn,5]:=copy(s,11,l);
end;
if (l>20)and(s[1]='[') and (s[10]=']') and
(s[11]='[') and (s[20]=']') and(s[21]<>'[') then
begin
gcn:=gcn+1;
gc[gcn,1]:=copy(s,1,10);
gc[gcn,2]:=copy(s,11,10);
gc[gcn,5]:=copy(s,21,l);
end;
if (l>30)and(s[1]='[') and (s[10]=']') and
(s[11]='[') and (s[20]=']') and
(s[21]='[') and (s[30]=']') and
(s[31]<>'[') then
begin
gcn:=gcn+1;
gc[gcn,1]:=copy(s,1,10);
gc[gcn,2]:=copy(s,11,10);
gc[gcn,3]:=copy(s,21,10);
gc[gcn,5]:=copy(s,31,l);
end;
if (l>40)and(s[1]='[') and (s[10]=']') and
(s[11]='[') and (s[20]=']') and
(s[21]='[') and (s[30]=']') and
(s[31]='[') and (s[40]=']') and
(s[41]<>'[') then
begin
gcn:=gcn+1;
gc[gcn,1]:=copy(s,1,10);
gc[gcn,2]:=copy(s,11,10);
gc[gcn,3]:=copy(s,21,10);
gc[gcn,4]:=copy(s,31,10);
gc[gcn,5]:=copy(s,41,l);
end;
end;
//读歌词结束,将时间标签和歌词文件放入网格中
Edit2.Text:=ti;
Edit3.Text:=ar;
Edit4.Text:=al;
Edit5.Text:=offset;
StringGrid1.RowCount:=gcn+1;
for i:=1 to gcn do
forj:=0 to 4 do
StringGrid1.Cells[j,i]:=gc[i,j+1];
closeFile(F);
end;
end;
end;
2.4.2 将歌曲播放的当前时间放到文本框中。
procedure TForm1.Timer1Timer(Sender: TObject);
var min,sec,msec,len:integer;
s:string;
t:TDateTime;
begin
len:=round(Form1.MediaPlay1.CurrentPosition*1000);
Form1.TrackBar1.Position:=len div 1000;
oldpos:=len div 1000;
min:=len div 1000 div 60;
sec:=len div 1000-min*60;
msec:=len mod 1000;
s:=format('%2d:%2d:%2d.%3d',[0,min,sec,msec]);
t:=StrToDatetime(s);
Form1.Edit1.text:=formatDateTime('nn:ss.zzz',t);
//播放结束时的操作
if (Form1.MediaPlay1.Duration*1000-len)<300 then
Form1.StopSpeedButtonClick(sender);
end;
2.4.3 单击网格相应位置,将当前时间添加到时间标签中
procedure TForm1.StringGrid1Click(Sender: TObject);
begin
if canclick and (StringGrid1.col<4) then
StringGrid1.Cells[StringGrid1.Col,StringGrid1.Row]:=
'['+copy(Edit1.Text,1,8)+']';
end;
2.5 保存编辑好的LRC歌词
LRC歌词编辑完成后,需要将其保存,以下是保存LRC歌词的代码。
procedure TForm1.SaveSpeedButtonClick(Sender: TObject);
var F:textFile;
i,j:integer;
fname,s:string;
begin
//保存歌词文件
saveDialog1.InitialDir:=mdir;
SaveDialog1.FileName:=changeFileExt(ComboBox1.text,'.lrc');
if SaveDialog1.Execute then
begin
fname:=saveDialog1.FileName;
AssignFile(F, fname);
Rewrite(F);
writeln(F,'[ti:'+Edit2.text+']');
writeln(F,'[ar:'+Edit3.text+']');
writeln(F,'[al:'+Edit4.text+']');
writeln(F,'[offset:'+Edit5.text+']');
for i:=1 to StringGrid1.RowCount-1 do
begin
s:='';
for j:=0 to StringGrid1.ColCount-1 do
s:=s+StringGrid1.Cells[j,i];
writeln(F,s);
end;
closefile(F);
end;
end;
以是代码在Delphi 7.0中调试通过。
3 结束语
本文详细介绍了如何利用Delphi开发一个LRC歌词编辑器,并给出了全部源代码,广大的Delphi编程爱好者可以在此文的基础上,开发出功能更完整的LRC歌词编辑器。
参考文献:
[1]明日科技. Delphi开发技术大全[M]. 人民邮电出版社,2007.
[2]明日科技. Delphi组件参考大全[M]. 人民邮电出版社,2006.
[3]吕伟臣. 精通Delphi 7.0 [M].科学出版社,2004.
注:本文中所涉及到的图表、注解、公式等内容请以PDF格式阅读原文。
关键词:LRC;Mp3;歌词编辑
中图分类号:TP311文献标识码:A 文章编号:1009-3044(2007)18-31663-04
Using Delphi development LRC lyrics Editor
WU Chao-bin
(Fujian College of Water Conservancy Electirc Power,Yong'an 366000,China)
Abstract: Discusses how to use Delphi development LRC lyrics editor, including lyrics of the LRC editing, display and preservation.
Key words:LRC; MP3; lyrics editing
1 引言
LRC歌词是一种包含着“[min:sec:msec]”形式的时间标签的、基于纯文本的歌词专用格式。因为是基于纯文本的格式,所以在电脑上能够方便的编辑。其中的时间标签“[min:sec:msec]”就是用于说明本句歌词在什么时候需要显示(min是分钟值、sec是秒钟值,msec是毫秒值)。例如,以下是阿杜《他一定很爱你》的LRC歌词
[ti:他一定很爱你]
[ar:阿杜]
[al:]
[offset:-100]
[00:03.31]他一定很爱你
[00:34.24]我躲在车里 手握著香槟
[00:38.42]想要给你 生日的惊喜
[00:43.44]你越走越近 有两个声音
[00:47.62]我措手不及 只得楞在那里
[00:56.81][01:53.65]我应该在车底 不应该在车里
[01:01.83][01:57.83]看到你们有多甜蜜
[01:06.01][02:02.69]这样一来我也 比较容易死心
[01:11.02][02:07.86]给我离开的勇气
[01:16.04][02:14.55][02:49.66]他一定很爱你 别把我比下去
[01:22.72][02:19.57][02:54.68]分手也只用了一分钟而已
[01:27.74][02:23.75][02:58.86]他一定很爱你 比我会讨好你
[01:32.76][02:28.76][03:03.87]不会像我这样孩子气 为难着你
其中:offset表示时间整体偏移量,正值表示时间往后偏移,负值表示时间往前偏移。
2 程序实现
2.1 程序界面
图1
2.2 歌词编辑方法
首先打开MP3文件,再打开对应的歌词文件(TXT或LRC格式)。单击“播放”按钮,开始播放歌曲,播放歌曲时,在相应的时间标签上单击,即可将当前时间添加至时间标签。歌曲播放完毕后,此时单击时间标签,不会将当前时间添加至时间标签,这样可以修改有错误的时间标签。
2.3 MP3文件的播放以及LRC歌词的显示
为了便于歌词的编辑以及观察编辑的歌词的时间标签是否有误,程序要能够播放MP3文件并能显示LRC歌词。播放MP3文件,这里使用ActiveX控件中的Windows Media Player。安装方法为:单击“Component”菜单下的“Import ActiveX Control …”,在弹出的对话框中选择“Windows Media Player”,将类名改为“TMediaPlay”然后单击“install”按钮。
2.3.1 以下是播放歌曲时将LRC歌词读到数组mgc中的代码。数组mgc中,mgc[i,1],mgc[i,2],mgc[i,3],mgc[i,4]用来存放时间标签,mgc[i,5]用来存放对应的歌词。
procedure TForm1.PlaySpeedButtonClick(Sender: TObject);
varfname,s,s1:string;
F:textFile;
min,sec,msec,i,j,l:integer;
begin
if fileexists(combobox1.Text) then
begin
try
Form1.MediaPlay1.FileName:=ComboBox1.Text;
Form1.MediaPlay1.Play;
l:=round(Form1.MediaPlay1.Duration*1000);
Trackbar1.Max:=l div 1000;
//显示歌曲总时间
min:=ldiv 1000 div 60;
sec:=l div 1000 -min*60;
Form1.Label2.Caption:=format('%2u:%2u',[min,sec]);
Timer1.Enabled:=true;
canclick:=true;
except
begin
timer1.Enabled:=false;
canclick:=false;
messagedlg('不支持的文件格式或其他程序占用音频设备!',mtError,[mbYes],0);
end;
end;
end
else
begin
showmessage('文件不存在!');
timer1.Enabled:=false;
end;
fname:=changeFileExt(ComboBox1.text,'.lrc');
if fileexists(fname) then
begin
toolbar2.Visible:=true;
AssignFile(F, fname);
Reset(F);
//读歌词
mgcn:=0;
moffset:=0;
for i:=1 to 100 do
for j:=1 to 5 do
mgc[i,j]:='';
while not eof(F) do
begin
readln(F,s);
s:=trim(s);
l:=length(s);
s1:=copy(s,2,6);moffset:=0;
if (l>10) and (s1='offset') then moffset:=StrToInt(copy(s,9,l-9));
if (l>10)and (s[3]>='0') and (s[3]<='9') and (s[1]='[') and (s[10]=']') and (s[11]<>'[') then
begin
mgcn:=mgcn+1;
msec:=StrToInt(copy(s,2,2))*60*1000+StrToInt(copy(s,5,2))*1000+
StrToInt(copy(s,8,2))*10;
mgc[mgcn,1]:=IntToStr(msec);
mgc[mgcn,5]:=copy(s,11,l);
end;
if (l>20)and(s[1]='[') and (s[10]=']') and
(s[11]='[') and (s[20]=']') and(s[21]<>'[') then
begin
mgcn:=mgcn+1;
msec:=StrToInt(copy(s,2,2))*60*1000+StrToInt(copy(s,5,2))*1000+
StrToInt(copy(s,8,2))*10;
mgc[mgcn,1]:=IntToStr(msec);
msec:=StrToInt(copy(s,12,2))*60*1000+StrToInt(copy(s,15,2))*1000+
StrToInt(copy(s,18,2))*10;
mgc[mgcn,2]:=IntToStr(msec);
mgc[mgcn,5]:=copy(s,21,l);
end;
if (l>30)and(s[1]='[') and (s[10]=']') and
(s[11]='[') and (s[20]=']') and
(s[21]='[') and (s[30]=']') and
(s[31]<>'[') then
begin
mgcn:=mgcn+1;
msec:=StrToInt(copy(s,2,2))*60*1000+StrToInt(copy(s,5,2))*1000+
StrToInt(copy(s,8,2))*10;
mgc[mgcn,1]:=IntToStr(msec);
msec:=StrToInt(copy(s,12,2))*60*1000+StrToInt(copy(s,15,2))*1000+
StrToInt(copy(s,18,2))*10;
mgc[mgcn,2]:=IntToStr(msec);
msec:=StrToInt(copy(s,22,2))*60*1000+StrToInt(copy(s,25,2))*1000+
StrToInt(copy(s,28,2))*10;
mgc[mgcn,3]:=IntToStr(msec);
mgc[mgcn,5]:=copy(s,31,l);
end;
if (l>40)and(s[1]='[') and (s[10]=']') and
(s[11]='[') and (s[20]=']') and
(s[21]='[') and (s[30]=']') and
(s[31]='[') and (s[40]=']') and
(s[41]<>'[') then
begin
mgcn:=mgcn+1;
msec:=StrToInt(copy(s,2,2))*60*1000+StrToInt(copy(s,5,2))*1000+
StrToInt(copy(s,8,2))*10;
mgc[mgcn,1]:=IntToStr(msec);
msec:=StrToInt(copy(s,12,2))*60*1000+StrToInt(copy(s,15,2))*1000+
StrToInt(copy(s,18,2))*10;
mgc[mgcn,2]:=IntToStr(msec);
msec:=StrToInt(copy(s,22,2))*60*1000+StrToInt(copy(s,25,2))*1000+
StrToInt(copy(s,28,2))*10;
mgc[mgcn,3]:=IntToStr(msec);
msec:=StrToInt(copy(s,32,2))*60*1000+StrToInt(copy(s,35,2))*1000+
StrToInt(copy(s,38,2))*10;
mgc[mgcn,4]:=IntToStr(msec);
mgc[mgcn,5]:=copy(s,41,l);
end;
end;
//读歌词结束
closefile(F);
Timer2.Enabled:=true;
end
else
begin
toolbar2.Visible:=false;
Timer2.Enabled:=false;
end;
end;
2.3.2 歌词编辑是否正确,需要进行验证,以下是利用时间控件,在label3标签中显示LRC歌词的代码
procedure TForm1.Timer2Timer(Sender: TObject);
var msec,i,j,l:integer;
begin
l:=round(Form1.MediaPlay1.CurrentPosition*1000);
//在Label3中显示歌词
for i:=1 to mgcn do
for j:=1 to 4 do
begin
if mgc[i,j]<>'' then
begin
msec:=StrToInt(mgc[i,j]);
if abs(msec-l-moffset)<150 then
Label3.Caption:=mgc[i,5];
end;
end;
end;
2.4 编辑LRC歌词的代码
2.4.1 将歌词读入网格中
procedure TForm1.OpenFSpeedButtonClick(Sender: TObject);
var F:textfile;
s,s1,ti,ar,al,offset:string;
gc:array [1..100,1..5] of string;
i,j,l,gcn:integer;
begin
OpenDialog1.Filter:='文本文件(*.txt)|*.txt|歌词文件(*.lrc)|*.lrc';
if OpenDialog1.Execute then
begin
if Opendialog1.FilterIndex=1 then
begin
//读取txt文件格式,将歌词放到网格中
AssignFile(F, OpenDialog1.FileName);
Reset(F);
for i:=1 to StringGrid1.RowCount-1 do
for j:=0 to StringGrid1.ColCount-1 do
StringGrid1.Cells[j,i]:='';
i:=1;
while not eof(F) do
begin
readln(F,s);
s:=trim(s);
if s<>'' then
begin
i:=i+1;
StringGrid1.RowCount:=i;
StringGrid1.Cells[4,i-1]:=s;
end;
end;
closefile(F);
end
else
begin
AssignFile(F, OpenDialog1.FileName);
Reset(F);
//读LRC歌词,将时间标签和歌词读到数组 gc 中
gcn:=0;
ar:=''; ti:=''; al:=''; offset:='';
for i:=1 to 100 do
for j:=1 to 5 do
gc[i,j]:='';
while not eof(F) do
begin
readln(F,s);
s:=trim(s);
l:=length(s);
s1:=copy(s,2,2) ;
if s1='ar' then ar:=copy(s,5,l-5);
if s1='ti' then ti:=copy(s,5,l-5);
if s1='al' then al:=copy(s,5,l-5);
s1:=copy(s,2,6);
if s1='offset' then offset:=copy(s,9,l-9);
if (l>10)and(s[1]='[') and (s[10]=']') and (s[11]<>'[') then
begin
gcn:=gcn+1;
gc[gcn,1]:=copy(s,1,10);
gc[gcn,5]:=copy(s,11,l);
end;
if (l>20)and(s[1]='[') and (s[10]=']') and
(s[11]='[') and (s[20]=']') and(s[21]<>'[') then
begin
gcn:=gcn+1;
gc[gcn,1]:=copy(s,1,10);
gc[gcn,2]:=copy(s,11,10);
gc[gcn,5]:=copy(s,21,l);
end;
if (l>30)and(s[1]='[') and (s[10]=']') and
(s[11]='[') and (s[20]=']') and
(s[21]='[') and (s[30]=']') and
(s[31]<>'[') then
begin
gcn:=gcn+1;
gc[gcn,1]:=copy(s,1,10);
gc[gcn,2]:=copy(s,11,10);
gc[gcn,3]:=copy(s,21,10);
gc[gcn,5]:=copy(s,31,l);
end;
if (l>40)and(s[1]='[') and (s[10]=']') and
(s[11]='[') and (s[20]=']') and
(s[21]='[') and (s[30]=']') and
(s[31]='[') and (s[40]=']') and
(s[41]<>'[') then
begin
gcn:=gcn+1;
gc[gcn,1]:=copy(s,1,10);
gc[gcn,2]:=copy(s,11,10);
gc[gcn,3]:=copy(s,21,10);
gc[gcn,4]:=copy(s,31,10);
gc[gcn,5]:=copy(s,41,l);
end;
end;
//读歌词结束,将时间标签和歌词文件放入网格中
Edit2.Text:=ti;
Edit3.Text:=ar;
Edit4.Text:=al;
Edit5.Text:=offset;
StringGrid1.RowCount:=gcn+1;
for i:=1 to gcn do
forj:=0 to 4 do
StringGrid1.Cells[j,i]:=gc[i,j+1];
closeFile(F);
end;
end;
end;
2.4.2 将歌曲播放的当前时间放到文本框中。
procedure TForm1.Timer1Timer(Sender: TObject);
var min,sec,msec,len:integer;
s:string;
t:TDateTime;
begin
len:=round(Form1.MediaPlay1.CurrentPosition*1000);
Form1.TrackBar1.Position:=len div 1000;
oldpos:=len div 1000;
min:=len div 1000 div 60;
sec:=len div 1000-min*60;
msec:=len mod 1000;
s:=format('%2d:%2d:%2d.%3d',[0,min,sec,msec]);
t:=StrToDatetime(s);
Form1.Edit1.text:=formatDateTime('nn:ss.zzz',t);
//播放结束时的操作
if (Form1.MediaPlay1.Duration*1000-len)<300 then
Form1.StopSpeedButtonClick(sender);
end;
2.4.3 单击网格相应位置,将当前时间添加到时间标签中
procedure TForm1.StringGrid1Click(Sender: TObject);
begin
if canclick and (StringGrid1.col<4) then
StringGrid1.Cells[StringGrid1.Col,StringGrid1.Row]:=
'['+copy(Edit1.Text,1,8)+']';
end;
2.5 保存编辑好的LRC歌词
LRC歌词编辑完成后,需要将其保存,以下是保存LRC歌词的代码。
procedure TForm1.SaveSpeedButtonClick(Sender: TObject);
var F:textFile;
i,j:integer;
fname,s:string;
begin
//保存歌词文件
saveDialog1.InitialDir:=mdir;
SaveDialog1.FileName:=changeFileExt(ComboBox1.text,'.lrc');
if SaveDialog1.Execute then
begin
fname:=saveDialog1.FileName;
AssignFile(F, fname);
Rewrite(F);
writeln(F,'[ti:'+Edit2.text+']');
writeln(F,'[ar:'+Edit3.text+']');
writeln(F,'[al:'+Edit4.text+']');
writeln(F,'[offset:'+Edit5.text+']');
for i:=1 to StringGrid1.RowCount-1 do
begin
s:='';
for j:=0 to StringGrid1.ColCount-1 do
s:=s+StringGrid1.Cells[j,i];
writeln(F,s);
end;
closefile(F);
end;
end;
以是代码在Delphi 7.0中调试通过。
3 结束语
本文详细介绍了如何利用Delphi开发一个LRC歌词编辑器,并给出了全部源代码,广大的Delphi编程爱好者可以在此文的基础上,开发出功能更完整的LRC歌词编辑器。
参考文献:
[1]明日科技. Delphi开发技术大全[M]. 人民邮电出版社,2007.
[2]明日科技. Delphi组件参考大全[M]. 人民邮电出版社,2006.
[3]吕伟臣. 精通Delphi 7.0 [M].科学出版社,2004.
注:本文中所涉及到的图表、注解、公式等内容请以PDF格式阅读原文。