★Delphi版★<幸运播放>★,无限制、完全免费下载版(来者有分)★ ( 积分: 50 )

  • 主题发起人 主题发起人 luckywangxw
  • 开始时间 开始时间
L

luckywangxw

Unregistered / Unconfirmed
GUEST, unregistred user!
http://www.skycn.com/soft/20572.html
http://www.onlinedown.net/soft/30014.htm
★先睹为快★
http://luckyplayer.go3.icpcn.com/images/allsnap.gif
本软件是一款影音播放软件,可以播放当今流行的各种媒体文件
及Flash动画; 体积小巧、界面简洁、操作方便、功能丰富、无须安
装、绿色环保是对她的准确概括; 她会成为您享受音乐与家庭影院
的最佳帮手,并能带给您最动听的音乐和最舒适的享受。

作者水平有限,不足之处还很多,所以还希望您能多多提出宝贵
意见和建议,以便我努力改正,争取把软件做得更好; 如果有喜爱
编程的朋友提供技术方面的帮助,作者将不胜荣幸与感激。
< 说 明 >
系统初始密码:123456

< 文 件 清 单 >
luckyplayer.exe ----- 主程序文件
ExFlash.dll、OtherFace.dll、FlashInfoPlus.dll、Borlndmm.dll
----- 系统动态库文件
luckyplayer.ini ----- 系统配置文件
clrSets.dat --------- 播放列表颜色配置文件
playlst ------------- 播放列表文件夹
playlst/*.lst ------- 播放列表文件
lyrics -------------- 歌词文件夹
lyrics/*.lrc -------- 歌词文件
ReadMe.txt----------- 说明文件
History.txt --------- 更新历史文件
Functions.txt ------- 软件功能介绍文件

<其他>
本软件播放flash动画的部分功能和动态库来源于D-Flasher,在此表示感谢!

[web]
http://luckyplayer.icpcn.com
@@:375771206
LuckyStudio

2004.10.7
 
http://www.skycn.com/soft/20572.html
http://www.onlinedown.net/soft/30014.htm
★先睹为快★
http://luckyplayer.go3.icpcn.com/images/allsnap.gif
本软件是一款影音播放软件,可以播放当今流行的各种媒体文件
及Flash动画; 体积小巧、界面简洁、操作方便、功能丰富、无须安
装、绿色环保是对她的准确概括; 她会成为您享受音乐与家庭影院
的最佳帮手,并能带给您最动听的音乐和最舒适的享受。

作者水平有限,不足之处还很多,所以还希望您能多多提出宝贵
意见和建议,以便我努力改正,争取把软件做得更好; 如果有喜爱
编程的朋友提供技术方面的帮助,作者将不胜荣幸与感激。
< 说 明 >
系统初始密码:123456

< 文 件 清 单 >
luckyplayer.exe ----- 主程序文件
ExFlash.dll、OtherFace.dll、FlashInfoPlus.dll、Borlndmm.dll
----- 系统动态库文件
luckyplayer.ini ----- 系统配置文件
clrSets.dat --------- 播放列表颜色配置文件
playlst ------------- 播放列表文件夹
playlst/*.lst ------- 播放列表文件
lyrics -------------- 歌词文件夹
lyrics/*.lrc -------- 歌词文件
ReadMe.txt----------- 说明文件
History.txt --------- 更新历史文件
Functions.txt ------- 软件功能介绍文件

<其他>
本软件播放flash动画的部分功能和动态库来源于D-Flasher,在此表示感谢!

[web]
http://luckyplayer.icpcn.com
@@:375771206
LuckyStudio

2004.10.7
 
看看还不错
 
哈,,,自绘菜单自己搞定了.
 
不错不错
 
不错不错.楼主能再加入一些格式就好了.
还有就是rmvb的语音分左右功能
 
做得真不錯,繼續努力。
 
呵呵 ̄可惜不是繁體的,看起來還行。實用方面還沒測試過
 
又更新了,欢迎提出意见建议
 
一个朋友要 播放列表 文件管理 和 列表清单及播放清单de代码,顺便贴上
//Treeview自画过程
procedure TfrmPlaylist.TvCustomDrawItem(Sender: TCustomTreeView;
Node: TTreeNode;
State: TCustomDrawState;
var DefaultDraw: Boolean);
var
NodeRect: TRect;
p1,p2:TPoint;
PointInNode:Boolean;
begin

with TV.Canvasdo

begin


tv.Color := colorsets[9];
tv.Font.Color := colorsets[1] ;
font.Assign(tv.Font);

if (node.Index mod 2)=1 then

Brush.Color := colorsets[2]
else

Brush.Color := colorsets[3];

//选取行字体颜色
if (cdsSelected in State) then

font.Color :=colorsets[7];

//播放行 (越靠后的,优先级越高)
if node.Index =mainfrm.currPlayList then

begin

font.Color :=colorsets[5];
Brush.Color := colorsets[4];
end;

//选取行背景
if (cdsSelected in State) then

Brush.Color := colorsets[6];


DefaultDraw:=false;

NodeRect := Node.DisplayRect(false);

p1.X :=NodeRect.left ;
p1.Y :=NodeRect.Top ;
p2.X :=NodeRect.Right ;
p2.Y :=noderect.Bottom;

p1:=tv.ClientToScreen(p1);
p2:=tv.ClientToScreen(p2);

PointInNode:=false;
if (mouse.CursorPos.X >=p1.X) and (mouse.CursorPos.X <=p2.X)
and (mouse.CursorPos.y >=p1.y) and (mouse.CursorPos.y <=p2.y) then

PointInNode:=true;

if (cdsSelected in State) and (cdsFocused in state) then

begin

brush.Style :=bsclear;
stretchdraw(noderect,CurItemImg);
end
else

begin

if PointInNode and (tv.DropTarget =node) and (node<> tv.Selected ) and (sglist.Dragging or tv.Dragging )
and (not PMyRec(node.Data)^.locked) then

brush.Color :=clNavy;

FillRect(NodeRect);
end;


NodeRect:=Node.DisplayRect(true);
NodeRect.Left := NodeRect.Left+7;
NodeRect.Right :=NodeRect.Right +7;
DrawText(Handle, PChar(Node.Text), Length(Node.Text), NodeRect, DT_SINGLELINE or DT_VCENTER);

if node.Index =mainfrm.currPlayList then

begin

NodeRect:=Node.DisplayRect(true);
NodeRect.Left := NodeRect.Left;
draw(nodeRect.Left,nodeRect.Top+(NodeRect.Bottom -NodeRect.Top -curPlaylistImg.Height ) div 2 ,curPlaylistImg );
end;


//焦点框
if (cdsSelected in State) then
//and tv.Focused
begin

NodeRect:=Node.DisplayRect(false);
pen.Color :=colorsets[1];

PenPos := Point(NodeRect.Left , NodeRect.Top );
Lineto(Noderect.Right-1,nodeRect.Top);
Lineto(Noderect.Right-1,nodeRect.bottom-1);
Lineto(Noderect.left,nodeRect.bottom-1);
Lineto(NodeRect.Left , NodeRect.Top);

end;

end;

end;



//播放清单 自画过程
procedure TfrmPlaylist.sglistDrawCell(Sender: TObject;
ACol, ARow: Integer;
Rect: TRect;
State: TGridDrawState);
var drawStr:string;
aRect:TRect;
begin

with Sender as TStringGriddo

begin

DefaultDrawing:=false;
Color := colorsets[9];
if (Arow=0) then
//or (ACol=0)
Canvas.Brush.Color := colorsets[0]
else

begin

if ARow mod 2 =0 then

Canvas.Brush.Color := colorsets[2]
else

Canvas.Brush.Color :=colorsets[3];
end;


canvas.Brush.Style:=bsSolid;
canvas.Font.Name :='宋体';
canvas.Font.Size :=9;
canvas.Font.Color :=colorsets[1];
canvas.font.Style :=[];

//选取行字体颜色
if (acol<=Selection.right) and (acol>=Selection.left) and
(arow>=Selection.top) and (arow <=Selection.bottom) then
//选取的行
canvas.Font.Color :=colorsets[7];

//播放字 字体颜色和背景颜色 是否粗体
if (playerstate<>psClosed) and (mainfrm.GetGridCell('标记',ARow)=mainfrm.playfilesign)
and (tv.Selected.index = mainfrm.currPlayList) then

begin
// 正在播放的
if colorsets[8]=1 then

canvas.font.Style :=[fsbold]
else

canvas.font.Style :=[];

canvas.Font.Color :=colorsets[5];
canvas.Brush.Color :=colorsets[4];
end;


//选取行背景
if (acol<=Selection.right) and (acol>=Selection.left) and
(arow>=Selection.top) and (arow <=Selection.bottom) then
//选取的行
canvas.Brush.Color :=colorsets[6];
//选取行 背景色


if (acol<=Selection.right) and (acol>=Selection.left)
and (arow=sglist.Row ) then

begin

aRect:=Rect;
arect.Bottom :=arect.Bottom -1;
if sglist.Focused then
//选取的行 //sglist.Focused (gdFocused in State)
begin

canvas.Brush.Style :=bsclear;
canvas.StretchDraw(arect,CurItemImg );
canvas.Rectangle(arect);
end
else

begin

canvas.Rectangle(arect);
end;

end
else

Canvas.FillRect(Rect);

drawStr:=trim(cells[acol,arow]);
if (pos(cells[ACol,0] ,'文件名 '+'时间 '+'歌名 '+'全名 '+'歌手 '+'歌词文件 '+'评论 '+'专辑 ')<>0)
and (ARow<>0) then

drawStr:=mainfrm.ResetCharMax(drawStr,rect.Right-rect.Left-2);

if (drawStr='[未指定]') then

drawStr:=' - -'
else
if (drawStr='') and (aCol<>0) then

drawStr:=' -' ;

if (ARow=0) then
begin

//居中
DrawText(Canvas.Handle, PChar(drawStr), Length(drawStr), Rect, DT_CENTER or DT_SINGLELINE or DT_VCENTER or DT_NOPREFIX)
end
else

begin

aRect:=Rect;
offsetrect(aRect,1,0);
aRect.Right :=aRect.Right-2 ;
if (ACol=0) and (ARow>0) then

//第一列
begin

aRect:=Rect;
offsetrect(aRect,2,0);
aRect.Right :=aRect.Right ;
DrawText(Canvas.Handle, PChar(drawStr+' '), Length(drawStr+' '), aRect, dt_RIght or DT_SINGLELINE or DT_VCENTER or DT_NOPREFIX);
end
else
if (pos(cells[ACol,0] , '类型 '+'时间 '+'出版年 '+'流派 '+'最爱 ')<>0) then

//居中
DrawText(Canvas.Handle, PChar(drawStr), Length(drawStr), aRect, DT_CENTER or DT_SINGLELINE or DT_VCENTER or DT_NOPREFIX)
else

//居左
DrawText(Canvas.Handle, PChar(drawStr), Length(drawStr), aRect, DT_SINGLELINE or DT_VCENTER or DT_NOPREFIX);
end;


//特别选取 行
canvas.Pen.Width :=1;
canvas.Pen.Color :=colorsets[1];
canvas.Pen.style :=pssolid;
if length(mainfrm.selList)=RowCount then

if mainfrm.selList[ARow] then
//and (ACol=0)
begin

canvas.MoveTo(rect.left,rect.top);
canvas.LineTo(rect.right,rect.top);

//画左竖线
if ACol=0 then

begin

canvas.MoveTo(rect.left,rect.top);
canvas.LineTo(rect.Left,rect.Bottom-2);
end;

//画右竖线
if aCol=ColCount-1 then

begin

canvas.MoveTo(rect.right-1,rect.top);
canvas.LineTo(rect.right-1,rect.Bottom-2);
end;

//画下横线
canvas.MoveTo(rect.Left,rect.Bottom-2);
canvas.LineTo(rect.right,rect.Bottom-2);
end;

end;

end;

=============================================
const SIG_MYLIST = 'WANGLST';
//用于 播放列表文件

TLstTag = packed record //列表文件Tag 信息格式(共128字节)
Num:integer;
//曲目数量 (4)
Header:array[0..6] of char;
//TAG开始以:'WANGLST'为标志 (7)
Txt:array[0..29] of char;
//列表标题(名称) (30)
No:byte; //列表位置 (1)
Locked:boolean; //是否加锁 (1)
Pwd:array[0..29] of char;
//锁密码 (30)
Comment:array[0..54] of char;
//备注 (55)
end;


=====================================================================================
//------------读取所有播放列表------------------
procedure Tmainfrm.readallList;
var havelist:boolean;
//是否 已经 成功读取一个清单
SearchRec:TSearchRec;
findPath:string;
i:integer;
begin

havelist:=false;

findpath:=GetPlaylstPath+'*.*';
if findfirst(findpath,faAnyfile,searchRec)=0 then

begin

repeat
if (uppercase(extractfileext(searchRec.name))='.LST') then

begin

if not havelist then

begin
//读取列表及其清单
if readlist( searchRec.name,true) then

havelist:=True;
end
else
//读取列表
readlistName( searchRec.name,false);

end;

until findnext(SearchRec)<>0 ;
end ;
findclose(searchRec);


//不存在任何一个清单时,自动创建 空清单
if not havelist then

begin

//createList('');
createList('歌曲');

createList('电影');
createList('Flash动画');
end ;

if mnushowplaylist.Checked then
begin

playlistwindow.tv.Items.GetFirstNode.Selected :=true;
playlistwindow.ListBox1.ItemIndex :=0;

if not PMyRec(playlistwindow.tv.Selected.data)^.locked then

showlist(PMyRec(playlistwindow.tv.Selected.data)^.lfilename)
else

begin

showNullList;
end;

end
else

begin

listIndex:=0;
if not playlists[listIndex].Locked then

showlist(playlists[listIndex].lfilename)
else

begin

showNullList;
end;

end;

end;

//==============读取所有播放列表======================

//----------------度取并显示指定列表(目前为 当前选择列表)-----------------
//aName:目前无用
function Tmainfrm.Showlist(aName:string):boolean;
var i,j:integer;
begin

filenamechg:=false;
listChged:=false;
treeViewNodeChged:=false;

//Reset sglist
for i:=1 to tmpsglist.RowCount-1do

for j:=0 to tmpsglist.ColCount -1do

tmpsglist.Cells[j,i]:='';
for i:=1 to HideColGrid.RowCount-1do

for j:=0 to HideColGrid.ColCount -1do

HideColGrid.Cells[j,i]:='';


//显示指定的清单
if mnushowplaylist.Checked then

readlist(PMyRec(playlistwindow.tv.Selected.data)^.lfilename,false)
else

readlist(playlists[listIndex].lfilename,false);


//取消原来 特别选取
setlength(selList,tmpsglist.RowCount);
for i:=1 to Length(sellist)-1do

sellist:=false;

result:=true;
end;

//================度取并显示指定列表===============

//---------------显示 空列表-----------------------
procedure Tmainfrm.showNullList;
var i,j:integer;
begin

tmpsglist.RowCount :=2;

if MaxColNum-tmpsglist.ColCount >1 then

HideColGrid.ColCount := MaxColNum-tmpsglist.ColCount
else

HideColGrid.ColCount := 1;
if tmpsglist.ColCount <>MaxColNum then

HideColGrid.rowcount :=tmpsglist.RowCount ;

for i:=1 to tmpsglist.RowCount-1do

for j:=0 to tmpsglist.ColCount -1do

tmpsglist.Cells[j,i]:='';
for i:=1 to HideColGrid.RowCount-1do

for j:=0 to HideColGrid.ColCount -1do

HideColGrid.Cells[j,i]:='';

end;

//=====================显示 空列表======================

//-------------------读取列表文件-----------------------
//aName:列表文件
//addSign:读取的同时,是否在TreeView中添加节点
function Tmainfrm.Readlist(aName:string;addSign:boolean):boolean;
var
fs : TFileStream;
s ,sName : String;
i,m,l,g,p1,lNo: Integer;
answer:boolean ;
rootnode,NewNode:TTreenode;
MyRecPtr: PMyRec;

aLocked:boolean;
aPwd:string;

haveId3:boolean;
Info : TLstTag ;
begin

result:=false;

fs := TFileStream.Create(GetPlaylstPath+ aName, fmOpenRead);
with fsdo

begin

try
try
p1:=0;
p1:=1;

//-----------------------
if fs.Size <128 then

begin

fs.Free;
answer:= showQuestion2('非法列表文件1:'+GetPlaylstPath+aName
+#13#13+'是否删除该播放列表文件?');
if answer then

deletefile(GetPlaylstPath+aName);
exit;
end;


ReadBuffer(Info,sizeof(TLstTag));

if info.Header<>SIG_MYLIST then

begin

answer:= showQuestion2('非法列表文件2:'+GetPlaylstPath+aName
+#13#13+'是否删除该播放列表文件?');
exit;
end;


m:=Info.Num ;
sName:=TrimRight(Info.Txt);
lNo:=Info.No;
aLocked:=Info.Locked;
aPwd:=TrimRight(Info.Pwd);
//===============================


if addSign then

begin

if mnushowplaylist.Checked then

begin

rootNode:=playlistwindow.Tv.Items.GetFirstNode;
New(MyRecPtr);
MyRecPtr^.Lfilename := aName;
MyRecPtr^.LNo :=lNo;
MyRecPtr^.locked :=aLocked;
MyRecPtr^.pwd :=aPwd;

NewNode:=playlistwindow.Tv.Items.AddObject(rootNode,sName,MyRecPtr);
//NewNode.Selected :=true;
New(MyRecPtr);
Dispose(MyRecPtr);

playlistwindow.ListBox1.Items.Add(sname);
// playlistwindow.ListBox1.ItemIndex :=0;
// playlistwindow.ListBox1.Selected[0]:=true;
end
else

begin

//***
setlength(playlists,length(playlists)+1);
playLists[length(playlists)-1].LNo :=lNo;
playLists[length(playlists)-1].Lfilename :=aName;
playLists[length(playlists)-1].LTxt := sName;
playLists[length(playlists)-1].Locked :=aLocked;
playLists[length(playlists)-1].pwd :=aPwd;
p1:=57;
//***
end;

end;




if m=0 then

tmpsglist.RowCount :=2
else

tmpsglist.RowCount:=m+1;

if MaxColNum-tmpsglist.ColCount >1 then

HideColGrid.ColCount := MaxColNum-tmpsglist.ColCount
else

HideColGrid.ColCount := 1;
if tmpsglist.ColCount <>MaxColNum then

HideColGrid.rowcount :=tmpsglist.RowCount ;
p1:=58;

for i:=1 to mdo
//m
begin

SetGridCell('No.',inttostr(i),i);
p1:=2;
//Read Whole name
read (l,sizeof(Integer));
setlength(s,l);
read (s[1],l);
p1:=3;
SetGridCell('全名',s,i);

//Get file ext
SetGridCell('类型',copy(extractfileext(s),2,length(extractfileext(s))-1),i);
//Get file simple name
SetGridCell('文件名',copy(extractfilename(s),1,length(extractfilename(s))-length(extractfileext(s))),i);
p1:=4;

//Read time
read (l,sizeof(Integer));
setlength(s,l);
read (s[1],l);
SetGridCell('时间',s,i);
p1:=5;

//read haveId3
read (haveId3, sizeof(Boolean));

p1:=6;
if haveId3 then

begin

//Read title
read (l,sizeof(Integer));
setlength(s,l);
read (s[1],l);

SetGridCell('歌名',s,i);
p1:=7;
//read Artils
read (l,sizeof(Integer));
setlength(s,l);
read (s[1],l);

SetGridCell('歌手',s,i);
p1:=8;
//Read Album
read (l,sizeof(Integer));
setlength(s,l);
read (s[1],l);

SetGridCell('专辑',s,i);
p1:=9;
//Read Year
read (l,sizeof(Integer));
setlength(s,l);
read (s[1],l);

SetGridCell('出版年',s,i);
p1:=10;
//Read Genre
read (g,SizeOf(integer));

SetGridCell('流派',GetGenreName(g),i);
p1:=101;

//Read Comment
read (l,sizeof(Integer));
setlength(s,l);
read (s[1],l);
SetGridCell('评论',s,i);

end;


p1:=11;
//Read 最爱
read (l,sizeof(Integer));
p1:=111;
Setlength(s,l);
p1:=112;
read (s[1],l);
p1:=113;

SetGridCell('最爱',s,i);

p1:=22;
//Read 歌词文件
read (l,sizeof(Integer));
Setlength(s,l);
read (s[1],l);
SetGridCell('歌词文件',s,i);

//Read 标记信息
read (l,sizeof(Integer));
Setlength(s,l);
read (s[1],l);
SetGridCell('标记',s,i);
end;

p1:=33;
result:=true;
except
if p1=1 then

begin

showinformation(' ReadList:因功能上的升级,与老版本列表文件 【'+GetPlaylstPath+aname +'】 不兼容!'
+#13+'请您 【将其 删除 或 移到其他地方】 即可,谢谢合作!'
+#13#13 +' 如有疑问,请与我们联系:wangxwabc@tom.com 或 QQ:375771206' );
end
else

begin

showinformation(' ReadList:'+inttostr(p1)+' 列表:'+sname+' 文件:'+aname
+#13#13+'因功能上的升级,与老版本产生了冲突!'
+#13#13+'如有疑问,请与我们联系:wangxwabc@tom.com 或 QQ:375771206' );
end;

application.Terminate;
end;

finally
free;
if (p1=1) and answer then

begin

deletefile(GetPlaylstPath+aName);
end;

{ if (result=false) and (p1=1) then

begin

deletefile(GetPlaylstPath+ aName);
DelListMnuClick(dellistmnu);
self.BringToFront;
end;
}
end;

end;

end;

//===========================读取列表文件=============================
 
LRC歌词文件解析单元

//原文件名:lyric.pas
//说明:该代码内容可以自由传播,但请注明出处
//ConvertTimeToTimestr函数,我忘记拷贝了,是在别的单元内,目前手边没有,大家可以用datetimetostr或简单一点函数来代替,以后有机会我一定发上来
//////////
unit lyric;
interface
uses Classes,SysUtils;

type
TOneLyric=Record
time:longint;
lyStr:string;
end;


TLyric=class
private
FFilename:string;
FOffset:integer;
//时间补偿值 其单位是毫秒,正值表示整体提前,负值相反。这是用于总体调整显示快慢的。
FAur:string;
//艺人名
FBy:string;
//编者(指编辑LRC歌词的人)
FAl:string;
//专辑名
FTi:string;
//曲名
FCount:integer;

FLyricArray : array of TOneLyric;
function GetLyric(i:integer): TOneLyric ;
function ExistTime(vTime:longint):boolean;

procedure sortLyric;
procedure ResetLyrics(FTxt:Tstrings);
protected
public
constructor Create;
destructor Destroy;
override;
procedure loadLyric(afilename:string);
procedure SetTxt(aLyrics:Tstrings);
procedure UnloadLyric(strs:Tstrings);

//整体提前(正值)或整体延后(负值)atime毫秒
function ChgOffset(atime:integer):boolean;

//提前(正值)/延后(负值)某一句歌词 aTime毫秒
function ChgOneLyric(oldTime:longint;aTime:integer):boolean;

//保存歌词内容到文件
function SaveLyricsToFile(vFileName:string):boolean;

property filename:string read ffilename;
property Ar:string read FAur;
property By:string read FBy;
property Al:string read FAl;
property Ti:string read FTi;
property Offset :integer read FOffset;

property LyricArray[i:integer]: TOneLyric read GetLyric ;

property Count:integer read FCount;
end;


implementation

uses main,pubUnit;

constructor TLyric.Create;
begin

inherited Create;
FTi:='';
FAur:='';
Fal:='';
FBy:='';
FOffset:=0;
end;


function TLyric.ExistTime(vTime:longint):boolean;
var i:integer;
begin

result:=false;
for i:=0 to length(FLyricArray) -1do

if FLyricArray.time =vTime then

begin

result:=true;
break;
end;

end;


procedure TLyric.loadLyric(afilename:string);
var
FTxt:Tstrings;
begin

FTi:='';
FAur:='';
Fal:='';
FBy:='';
FOffset:=0;

FFilename:=afilename;
//载入歌词

FTxt:=TStringlist.create;
FTxt.LoadFromFile(Ffilename);

ResetLyrics(FTxt);

FTxt.Clear;
FTxt.free;
end;


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;


timestr:=copy(curLyric,p1+1,p2-p1-1);
//左右两边为歌词
lyricStr:= copy(curLyric,1,p1-1) + copy(curLyric,p2+1,length(curLyric)-p2) ;

lyricStr:=makeOneLyric(lyricStr);

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-1do

begin

makeOneLyric(FTxt) ;
end;


FCount:=length(FLyricArray) ;
sortLyric;

{if FTi<>'' then
FTi:= replaceWithchr(FTi,'&amp;','&amp;&amp;');
if FAur<>'' then
FAur:= replaceWithchr(FAur,'&amp;','&amp;&amp;');
if FAl<>'' then
FAl:= replaceWithchr(FAl,'&amp;','&amp;&amp;');
if FBy<>'' then
FBy:= replaceWithchr(FBy,'&amp;','&amp;&amp;');
}
//根据 整体时间偏移,重新计算每句歌词时间
for i:=0 to length(FLyricArray)-1do

begin

//FLyricArray.lyStr := replaceWithchr(FLyricArray.lyStr,'&amp;','&amp;&amp;');

if FLyricArray.time >= 0 then

begin

if FLyricArray.time - FOffset>=0 then

FLyricArray.time:=FLyricArray.time - FOffset ;

end
else

FLyricArray.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 -1do

begin

FLyricArray.time :=0;
FLyricArray.lyStr := strs;
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 ;
end;


procedure TLyric.sortLyric;
var i,j:integer;
tmpLyric:TOneLyric;
begin

for i:=0 to length(FLyricArray)-2do

begin

for j:=i to length(FLyricArray)-1do

begin

if FLyricArray[j].time < FLyricArray.time then

begin

tmpLyric:= FLyricArray;
FLyricArray:= 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;

//修改offset 保存文件
afind:=false;
aOffset:=0;
numberLine:=-1;

FTxt:=TStringlist.create;
try
FTxt.LoadFromFile(FFilename);

for i:=0 to FTxt.Count-1do

begin

curLyric:=fTxt;

p1:=pos('[',CurLyric);//第一个‘[’位置
if p1=0 then
begin
//判断是否非法行
continue;
//无 '['
end;

p2:=pos(']',CurLyric);
//第一个‘]’位置
if p2=0 then
begin

continue;
//无 ']'
end;


timestr:=copy(curLyric,p1+1,p2-p1-1);
//左右两边为歌词
lyricStr:= copy(curLyric,1,p1-1) + copy(curLyric,p2+1,length(curLyric)-p2) ;

if copy(Lowercase(timeStr),1,6)='offset' then
//找到 时间补偿串
begin

try
aOffset:= strtoint(copy(timestr,8,length(timestr)-7));
except
continue;
end ;
fTxt:=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;//该时间是否为负.

p1,p2,p3:integer;
timestr,left_lyric,right_lyric:string;
//
time1,time2:longint;
findok:boolean;
isValid:boolean;//

NewTimeLabel:string;
NewTime:longint;

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;

//==========串内 是否有标签==========

//----------目前标签 是否是 指定时间的 标签----------
timestr:=copy(curLyric,p1+1,p2-p1-1);

Left_lyric:= copy(curLyric,1,p1-1);
Right_lyric:= copy(curLyric,p2+1,length(curLyric)-p2) ;

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;

//根据 老时间标签(timerstr)
//生成 新的时间标签
NewTime:=time1*60+time2 - aTime;

//根据 原来是否使用毫秒 和 目前调整的偏移时间是否属于毫秒级别
// 来决定 是否 使用毫秒
UseMS:= (Pos('.',timestr)>0) or (aTime mod 1000 <>0);

//转化时间为时间串例如: 72秒 ==>> '00:01:12.000'
NewTimeLabel:=ConvertTimeToTimestr(NewTime,0,false,true,UseMS,true);

//返回 新的歌词部分
curLyric := left_Lyric + '[' + NewTimeLabel + ']'+ Right_Lyric;

end
else
//还 没找到
begin
//在 该行歌词剩余部分 找找看

if AjustOneLine(Right_lyric) then

begin

//在剩余部分内找到了
curLyric:= Left_lyric+ '[' + timestr +']' +Right_lyric ;

Result:=true;
end
//else
剩余部分内 没有的话 ,只好返回 false 啦
// (函数开始处,已经默认=false)

end;

//=========找到 和 没找到 之后的处理==========

end;

//end function AjustOneLine

begin

AjustOk:=false;
Result:=false;

FTxt:=TStringlist.create;
try
FTxt.LoadFromFile(FFilename);

for i:=0 to FTxt.Count-1do

begin

thisLyric:=FTxt;

if AjustOneLine(thisLyric) then

begin

AjustOk:=true;
//更新 新生成 的歌词行
FTxt:=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-1do

aTxt.Add(LyricArray.lyStr ) ;

aTxt.SaveToFile(vFilename);

Result:=true;
finally
aTxt.Free;
end;

end;


end.
 
后退
顶部