function TLyric.ExistTime(vTime:longint):boolean; var i:integer; begin result:=false; for i:=0 to length(FLyricArray) -1 do if FLyricArray[i].time =vTime then begin result:=true; break; end; end;
procedure TLyric.loadLyric(afilename:string); var FTxt:Tstrings; begin FTi:='; FAur:='; Fal:='; FBy:='; FOffset:=0;
procedure TLyric.SetTxt(aLyrics:Tstrings); begin FTi:='; FAur:='; Fal:='; FBy:='; FOffset:=0;
//载入歌词 ResetLyrics(aLyrics); end;
//根据歌词文件 载入每行歌词 procedure TLyric.ResetLyrics(FTxt:Tstrings); var i:integer; function makeOneLyric(CurLyric:string):string; var p1,p2,p3:integer; timestr,lyricstr:string; time1,time2:longint;
isFuSign:boolean; begin p1:=pos('[',CurLyric);//第一个‘[’位置 if p1=0 then begin //判断是否非法行 result:= CurLyric; //无 '[' exit; end; p2:=pos(']',CurLyric); //第一个‘]’位置 if p2=0 then begin result:= CurLyric; exit; //无 ']' end;
if copy(Lowercase(timeStr),1,2)='ar' then //作者信息 FAur:= copy(timestr,4,length(timestr)-3) else if copy(Lowercase(timeStr),1,2)='ti' then //曲目标题 FTi:= copy(timestr,4,length(timestr)-3) else if copy(Lowercase(timeStr),1,2)='al' then //专辑名 FAl:= copy(timestr,4,length(timestr)-3) else if copy(Lowercase(timeStr),1,2)='by' then //编辑LRC歌词的人 FBy:= copy(timestr,4,length(timestr)-3) else if copy(Lowercase(timeStr),1,6)='offset' then //时间补偿值 try FOffset:= strtoint(copy(timestr,8,length(timestr)-7)) except FOffset:=0; end else //此时为 时间标记 begin p3:= pos(':',timestr) ; if p3>0 then begin //判断是否非法行 isFuSign:=false; try time1:=strtoint(copy(timestr,1,p3-1))*1000; if time1<0 then isFuSign:=true; //记录 该 时间标签 为 负(小于零) except //非法歌词行 exit; //分钟有误 end;
try time2:= trunc( strtofloat(copy(timestr,p3+1,length(timestr)-p3)) *1000); if isFuSign then time2:=-time2; except exit; //秒 有误 end;
if not ExistTime(time1*60+time2) then begin setLength(FLyricArray,length(FLyricArray)+1); //if trim(lyricStr)=' then // lyricStr:= '(Music)'; with FLyricArray[length(FLyricArray)-1] do begin time :=time1*60+time2; lystr:=lyricStr; end; result:=lyricStr; end; end; end;
end; begin SetLength(FLyricArray,0);
//解析歌词各部分 for i:= 0 to FTxt.count-1 do begin makeOneLyric(FTxt[i]) ; end;
FCount:=length(FLyricArray) ; sortLyric;
{if FTi<>' then FTi:= replaceWithchr(FTi,'&','&&'); if FAur<>' then FAur:= replaceWithchr(FAur,'&','&&'); if FAl<>' then FAl:= replaceWithchr(FAl,'&','&&'); if FBy<>' then FBy:= replaceWithchr(FBy,'&','&&'); } //根据 整体时间偏移,重新计算每句歌词时间 for i:=0 to length(FLyricArray)-1 do begin //FLyricArray[i].lyStr := replaceWithchr(FLyricArray[i].lyStr,'&','&&');
if FLyricArray[i].time >= 0 then begin if FLyricArray[i].time - FOffset>=0 then FLyricArray[i].time:=FLyricArray[i].time - FOffset ;
end else FLyricArray[i].time:=0; end; end;
procedure TLyric.UnloadLyric(strs:Tstrings); var i:integer; begin SetLength(FLyricArray,strs.Count ); FCount:= strs.Count; for i:=0 to strs.Count -1 do begin FLyricArray[i].time :=0; FLyricArray[i].lyStr := strs[i]; end;
FTi:='; FAur:='; Fal:='; FBy:='; FOffset:=0;
end;
destructor TLyric.Destroy; begin SetLength(FLyricArray,0);
inherited Destroy; end;
function TLyric.GetLyric(i:integer): TOneLyric ; begin if (i>=0) and (i<length(FLyricArray)) then result:=FLyricArray[i] ; end;
procedure TLyric.sortLyric; var i,j:integer; tmpLyric:TOneLyric; begin for i:=0 to length(FLyricArray)-2 do begin for j:=i to length(FLyricArray)-1 do begin if FLyricArray[j].time < FLyricArray[i].time then begin tmpLyric:= FLyricArray[i]; FLyricArray[i]:= FLyricArray[j]; FLyricArray[j]:= tmpLyric; end; end; end; end;
function TLyric.ChgOffset(atime:integer):boolean;//提前(正值)或延后(负值)atime毫秒 var i,numberLine:integer; p1,p2,p3:integer; timestr,lyricstr,CurLyric,signStr:string; aOffset:longint; afind:boolean; FTxt:Tstrings; begin Result:=false;
for i:=0 to FTxt.Count-1 do begin curLyric:=fTxt[i];
p1:=pos('[',CurLyric);//第一个‘[’位置 if p1=0 then begin //判断是否非法行 continue; //无 '[' end; p2:=pos(']',CurLyric); //第一个‘]’位置 if p2=0 then begin continue; //无 ']' end;
if copy(Lowercase(timeStr),1,6)='offset' then //找到 时间补偿串 begin try aOffset:= strtoint(copy(timestr,8,length(timestr)-7)); except continue; end ; fTxt[i]:=copy(curLyric,1,p1-1) +'[offset:'+inttostr(aOffset+aTime) +']' +copy(curLyric,p2+1,length(curLyric)-p2);
if aOffset+aTime=0 then FTxt.Delete(i);
fTxt.SaveToFile(FFilename); afind:=true; break; end else begin if numberLine=-1 then begin signStr:=copy(Lowercase(timeStr),1,2) ; if (signStr<>'ar') and (signStr<>'al') and (signStr<>'ti') and (signStr<>'by') then begin p3:= pos(':',timestr) ; if p3>0 then //为时间标记 numberLine:=i; //记录行号 end; end; end; end;
if (not afind) and (numberLine<>-1) then begin //fTxt.Add('[offset:'+inttostr(aOffset+aTime) +']'); fTxt.Insert(numberline, '[offset:'+inttostr(aOffset+aTime) +']'); fTxt.SaveToFile(FFilename); end;
//重新载入歌词 loadLyric(FFilename);
result:=true;
FTxt.Clear; finally FTxt.free; end; end;
function TLyric.ChgOneLyric(oldTime:longint;aTime:integer):boolean; var i:integer; FTxt:Tstrings; AjustOk:boolean; thisLyric:string;
function AjustOneLine(var curLyric:string):boolean; var isFu:boolean;//该时间是否为负.
UseMS:boolean; begin //---------该串内 是否有标签 ---------- p1:=pos('[',CurLyric);//第一个‘[’位置 if p1=0 then begin //判断是否非法行 Result:=false; //无 '[' exit; end; p2:=pos(']',CurLyric); //第一个‘]’位置 if p2=0 then begin result:= false; exit; //无 ']' end; //==========串内 是否有标签==========
isValid:=true; findok:=false; p3:= pos(':',timestr) ; if p3>0 then begin //判断是否 合法时间标签 isFu:=false; try time1:=strtoint(copy(timestr,1,p3-1))*1000; if time1<0 then isFu:=true; except //非法歌词行 isValid:=false; //分钟有误 end;
try if isValid then begin time2:= trunc( strtofloat(copy(timestr,p3+1,length(timestr)-p3)) *1000); if isFu then time2:=-time2; end; except isValid:=false; //秒 有误 end;
if isValid and (time1*60+time2 - FOffset = oldtime) then //找到 指定时间串 findOk:=true; //找到 啦 啦 啦 ...
end; //非法行 判断结束 //==========是否找到 指定时间标签==========
//-------找到 和 没找到 之后的处理 ---------- if findok then begin Result:= true;
for i:=0 to FTxt.Count-1 do begin thisLyric:=FTxt[i];
if AjustOneLine(thisLyric) then begin AjustOk:=true; //更新 新生成 的歌词行 FTxt[i]:=thisLyric;
break; end; end;
if AjustOk then begin //保存歌词文件 FTxt.SaveToFile(FFilename);
//重新载入歌词 loadLyric(FFilename);
Result:=true; end;
FTxt.Clear; finally FTxt.free; end;
end;
//保存歌词内容到文件 function TLyric.SaveLyricsToFile(vFileName:string):boolean; var i:integer; aTxt:Tstrings ; begin result:=false; if FCount<=0 then exit;
aTxt:=Tstringlist.Create; try if FTi <>' then aTxt.Add('歌名:'+FTi); if FAur <>' then aTxt.Add('歌手:'+FAur); if Fal <>' then aTxt.Add('专辑:'+Fal); // if Fby <>' then // lbxpreview.Items.Add('歌词编辑:'+Fby); if aTxt.Count >0 then aTxt.Add('--- --- --- --- --- --- ---');
for i:=0 to FCount-1 do aTxt.Add(LyricArray[i].lyStr ) ;