多媒体播放器如何实现歌词和歌曲的相互控制(200分)

Z

zhtq

Unregistered / Unconfirmed
GUEST, unregistred user!
多媒体播放器如何实现歌词和歌曲的相互控制,很类似《千千静听》中的歌词和歌曲的互控
(1)歌词中时间,方便与歌曲互控,
(2)希望能修改以下代码:其他功能都已经实现,就差互控了,
(3)先谢过,联系方式:QQ 280501393。 zhtqiang@126.com
(4)这个播放器已经可以使用,可以试试,就差歌词与歌曲的相互控制了(歌词拖到那里 歌曲唱到那里,歌曲拖到那里歌词也显示到那里)。

unit U_Form1;

interface

uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, ComCtrls, StdCtrls, ExtCtrls, MPlayer, Menus, Buttons, ToolWin,
FileCtrl,mmSystem,ShellApi;

type
TForm1 = class(TForm)
MainMenu1: TMainMenu;
FileMenu: TMenuItem;
DATMenu: TMenuItem;
AVIMenu: TMenuItem;
OpenDialog1: TOpenDialog;
N4: TMenuItem;
WAVMenu: TMenuItem;
MP3Menu: TMenuItem;
AllMenu: TMenuItem;
CoolBar1: TCoolBar;
PlaySB1: TSpeedButton;
StopSB1: TSpeedButton;
PlaySB2: TSpeedButton;
StopSB2: TSpeedButton;
KeepPlaySB: TSpeedButton;
Timer1: TTimer;
ListPanel: TPanel;
ListCB: TComboBox;
ListFileLabel: TLabel;
ProgressLabel: TLabel;
N5: TMenuItem;
ExitMenu: TMenuItem;
PBar1: TProgressBar;
MediaPlayer1: TMediaPlayer;
N1: TMenuItem;
OpenMenu: TMenuItem;
SpeedUpMenu: TMenuItem;
SlowDownMenu: TMenuItem;
EditMenu: TMenuItem;
SongP: TPanel;
TrackBar1: TTrackBar;
Label1: TLabel;
procedure ChooiceFile(Sender: TObject);
procedure CoolBarButton(Sender: TObject);
procedure MediaPlayer1Notify(Sender: TObject);
procedure AllMenuClick(Sender: TObject);
procedure ListCBChange(Sender: TObject);
procedure Timer1Timer(Sender: TObject);
procedure ExitMenuClick(Sender: TObject);
procedure FormCreate(Sender: TObject);
procedure SpeedUpMenuClick(Sender: TObject);
procedure SlowDownMenuClick(Sender: TObject);
procedure EditMenuClick(Sender: TObject);
procedure OpenMenuClick(Sender: TObject);
procedure TrackBar1Change(Sender: TObject);

private
LINES:integer;//计算显示字幕的行数
n:integer;
sl:Tstringlist;
currentplay,currentdisp:integer;//分别记录当前播放的行数和显示的行数

public
Dir:string;
IsLast:boolean;
procedure SpeedButton(T,C1,C2,C3,C4,C5:boolean);
procedure ShowText(SongName:string);
Procedure BmpCreate(LineHeight:word);

end;


var
Form1: TForm1;

MovingStep:integer;
Currline:integer;
Item:TStringList;
bmp:TBitMap;
bRect,R1:TRect;
iDc:HDC;
CurrSongName:string;
implementation

uses U_Form2;

{$R *.dfm}
/////////////////选择播放文件的格式////////////////////////////////
procedure TForm1.ChooiceFile(Sender: TObject);
var
WhichMenu:byte;
begin

WhichMenu:=0;
if (MediaPlayer1.Mode=mpPlaying)or(MediaPlayer1.Mode=mpOpen) then

begin
//如果正在播放或已经打开
MediaPlayer1.Stop;
//停止设备
MediaPlayer1.DeviceType:=dtAutoSelect;
//设置由播放的文件确定设备类型
end;

if Sender is TMenuItem then

begin

WhichMenu:=(Sender as TMenuItem).Tag;
case WhichMenu of //根据所击菜单项确定过滤器扩展名
1: OpenDialog1.Filter:=(Sender as TMenuItem).Caption+'|*.dat';
2: OpenDialog1.Filter:=(Sender as TMenuItem).Caption+'|*.avi';
3: OpenDialog1.Filter:=(Sender as TMenuItem).Caption+'|*.wav';
4: OpenDialog1.Filter:=(Sender as TMenuItem).Caption+'|*.mp3';
5: OpenDialog1.Filter:=(Sender as TMenuItem).Caption+'|*.*';
end;

end;

if OpenDialog1.Execute then

begin

MediaPlayer1.FileName:=OpenDialog1.FileName;
MediaPlayer1.Open;
if (WhichMenu=1)or(WhichMenu=2) then
//视频文件
begin

MediaPlayer1.Display:=Form2;
MediaPlayer1.DisplayRect:=Rect(0,0,Form2.ClientWidth,Form2.ClientHeight);
Form2.Caption:='正在播放:'+MediaPlayer1.FileName;
Form2.Show;
Caption:='正在播放:'+MediaPlayer1.FileName;
SpeedButton(True,false,true,false,false,false);
end else
if (WhichMenu=3)or(WhichMenu=4) then
//音频文件
SpeedButton(false,false,false,true,false,false);
end;

end;


///////coolbarbutton上5个按钮的选择 ///////////////////////////////////////////
procedure TForm1.CoolBarButton(Sender: TObject);
begin

if Sender is TSpeedButton then

case (Sender as TSpeedButton).Tag of
1: begin

Form2.Show;
SpeedButton(true,false,true,false,false,false);
end;

2: begin

Form2.Close;
SpeedButton(false,true,false,false,false,false);
end;

3:begin

MediaPlayer1.Play;
SpeedButton(true,false,false,false,true,false);
end;

4:begin

MediaPlayer1.Stop;
SpeedButton(false,false,false,true,false,false);
end;

5:begin

if (Sender as TSpeedButton).Down then

begin

MediaPlayer1.Play;
SpeedButton(true,false,false,false,false,true);
(Sender as TSpeedButton).Caption:='停止'
end else

begin

MediaPlayer1.Stop;
SpeedButton(false,false,false,false,false,true);
(Sender as TSpeedButton).Caption:='播放';
end;

end;

end;

Caption:='正在播放:'+MediaPlayer1.FileName;
end;


///////////////////////////////连续播放 ///////////////////////////////////////
procedure TForm1.AllMenuClick(Sender: TObject);
var
sr:TSearchRec;
Fileext:String ;
begin

if SelectDirectory('选择目录:', '', Dir) then

begin

if FindFirst(Dir+'/*.*',0,sr)=0 then

begin

ListCB.Items.Clear;
if sr.Attr<>faDirectory then

begin

Fileext:=LowerCase(ExtractFileExt(sr.Name));
if(fileext='.wav')or(fileext='.mp3')or(fileext='.dat')or(fileext='.avi')then

ListCB.Items.Add(sr.Name);
end;

end;

while FindNext(sr)=0do

begin

if (sr.Attr<>faDirectory)then

begin

Fileext:=LowerCase(ExtractFileExt(sr.Name));
if(fileext='.wav')or(fileext='.mp3')or(fileext='.dat')or(fileext='.avi')then

ListCB.Items.Add(sr.Name);
end;

end;

end;

if ListCB.Items.Count=0 then

ShowMessage('你所选择的文件夹中没有有效的音频文件!');
end;


/////////////////控制组件按钮使用////////////////////////////////////////////////////////
procedure TForm1.SpeedButton(T,C1, C2, C3, C4, C5: boolean);
begin

Timer1.Enabled:=T;
ListCB.Enabled:=not KeepPlaySB.Down;
AllMenu.Enabled:=not KeepPlaySB.Down;
PlaySB1.Enabled:=C1 ;
StopSB1.Enabled:=C2 ;
PlaySB2.Enabled:=C3 ;
StopSB2.Enabled:=C4 ;
KeepPlaySB.Enabled:=C5;
EditMenu.Enabled:=C1 or C3 ;
end;


/////////////////////////mediaplayer1播放完歌曲notify事件////////////////////////
procedure TForm1.MediaPlayer1Notify(Sender: TObject);
begin

if IsLast=true then
exit;
with MediaPlayer1do

begin

if (NotifyValue=nvFailure) then

Application.Terminate;
if((Mode=mpStopped)or(NotifyValue=nvSuccessful))and(KeepPlaySB.Down=true)then

begin

Stop;
DeviceType:=dtAutoSelect;
if ListCB.ItemIndex=ListCB.Items.Count-1 then

begin

IsLast:=true;
exit;
end else
ListCB.ItemIndex:=ListCB.ItemIndex+1;
FileName:=dir+'/'+ListCB.Items.Strings[ListCB.ItemIndex];
Open;
Play;
Caption:='正在播放:'+MediaPlayer1.FileName;
end;

end;

end;


//////////文件列表的onchange事件////////////////////////////////////////////////
procedure TForm1.ListCBChange(Sender: TObject);
begin

if ListCB.text='' then
exit;
if (MediaPlayer1.Mode=mpPlaying)or(MediaPlayer1.Mode=mpOpen) then

begin

MediaPlayer1.Stop;
MediaPlayer1.DeviceType:=dtAutoSelect;
end;

if ListCB.ItemIndex=ListCB.Items.Count-1 then
IsLast:=true
else
IsLast:=false;
MediaPlayer1.FileName:=dir+'/'+ListCB.text;
MediaPlayer1.Open;
MediaPlayer1.Play;
SpeedButton(true,false,false,false,false,true);
KeepPlaySB.Down:=true;
Caption:='正在播放:'+MediaPlayer1.FileName;
end;


procedure TForm1.Timer1Timer(Sender: TObject);
var
N:byte;
total,nowpos:integer;
begin

total:=round(mediaplayer1.Length div 1000);
//计算媒体长度
nowpos:=round(mediaplayer1.Position div 1000);
//计算当前播放的时间
label1.Caption:='已经播放时间:'+inttostr(nowpos)+'秒/总共需时间:'+inttostr(total)+'秒';
trackbar1.Max:=mediaplayer1.Length;
trackbar1.Min:=0;
trackbar1.Position:=mediaplayer1.Position;//trackbar的位置与媒体播放进度同步

N:=Round(100*MediaPlayer1.Position/(MediaPlayer1.Length+1));
PBar1.Position:=N;
ProgressLabel.Caption:=
Format('列表中第%d个文件 ,播放进度 %d',[ListCB.ItemIndex+1,N])+' %';

BitBlt(iDc,0,0,SongP.Width,SongP.Height,
Bmp.Canvas.Handle,0,Currline,srcCopy);
//改变currline可实现左移右移
Inc(Currline,MovingStep);
if Currline>=bRect.Bottom-SongP.Height+400 then

begin

Timer1.Enabled:=False;
Currline:=0;
end;

end;


/////////////菜单项的退出事件///////////////////////////////////////////////////
procedure TForm1.ExitMenuClick(Sender: TObject);
begin

Application.Terminate;
end;


procedure TForm1.FormCreate(Sender: TObject);
begin

mediaplayer1.TimeFormat:=tfmilliseconds;//设置媒体时间格式以毫秒为单位
label1.Caption:='0:0:0/0:0:0';
//媒体总时间与当前播放时间
MediaPlayer1.TimeFormat:=tfmilliseconds;
SpeedButton(false,false,false,false,false,false);
KeepPlaySB.Down:=true;
CurrSongName:='外婆的澎湖湾.txt';
iDC:=GetDc(SongP.handle);
Currline:=0;
MovingStep:=5;
ShowText(CurrSongName);

end;


procedure TForm1.BmpCreate(LineHeight: word);
var
i,y:integer;
begin

if bmp<>nil then
bmp.free;
bmp:=TBitMap.Create;
with bRectdo
//Rect 矩形坐标(左上x,左下y,右上x,右下y)
begin

Top:=0;
Left:=0;
Right:=SongP.Width;
Bottom:=LineHeight*Item.Count+Height;//行高*行数+form高度
end;

Bmp.Height:=bRect.Bottom;//图片高度
Bmp.Width:=bRect.Right;
Bmp.Canvas.Brush.Color:=clInfoText;
Bmp.Canvas.FillRect(bRect);
Bmp.Canvas.Font.Color:=clRed;
//控制显示字体颜色
Bmp.Canvas.Font.Size:=LineHeight div 2 ;
//控制显示字体颜色
Bmp.Canvas.Brush.Style:=bsClear ;
R1:=bRect;
y:=SongP.Height-100;
for i:=0 to Item.Count-1do

begin

R1.Top:=y;
R1.Bottom:=R1.Top+LineHeight;
DrawText(Bmp.Canvas.Handle,pChar(Item),-1,R1,Dt_Center or Dt_Top);//中对齐
//DrawText(Bmp.Canvas.Handle,pChar(Item),-1,R1,Dt_Left or Dt_Top);
//左对齐
//DrawText(Bmp.Canvas.Handle,pChar(Item),-1,R1,Dt_Right or Dt_Top);//右对齐
Inc(y,LineHeight);
end;

end;


procedure TForm1.ShowText(SongName: string);
var
ss:string;
ReadFile:TextFile;
begin

if SongName='' then
exit;
AssignFile(ReadFile,SongName);
Reset(ReadFile);
Item:=TStringList.Create;
while not eof(ReadFile)do

begin

Readln(ReadFile,ss);
Item.Add(ss);
end;

CloseFile(ReadFile);
BmpCreate(30);
Item.Free;//释放串
end;


//////////////加快滚动速度//////////////////////////////////////////////////////
procedure TForm1.SpeedUpMenuClick(Sender: TObject);
begin

if MovingStep<SongP.ClientHeight then
inc(MovingStep);
end;


///////////////减慢滚动速度/////////////////////////////////////////////////////
procedure TForm1.SlowDownMenuClick(Sender: TObject);
begin

if MovingStep>1 then
dec(MovingStep);
end;


///////////////编辑歌词/////////////////////////////////////////////////////////
procedure TForm1.EditMenuClick(Sender: TObject);
begin

if CurrSongName='' then

ShellExecute(0,'Open','NotePad.exe',nil,nil,1)
else

ShellExecute(0,'Open',Pchar(CurrSongName),nil,nil,1)
end;


//////////////打开歌词//////////////////////////////////////////////////////////
procedure TForm1.OpenMenuClick(Sender: TObject);
begin

OpenDialog1.Filter:='文本文件(*.txt)|*.txt|所有文件(*.*)|*.*';
if OpenDialog1.Execute then

begin

CurrSongName:=OpenDialog1.FileName;
ShowText(OpenDialog1.FileName);
end;

end;


//trackbar1的onchange事件,控制媒体播放位置和播放的进度
procedure TForm1.TrackBar1Change(Sender: TObject);
begin

timer1.Enabled:=false;
mediaplayer1.Stop;
//停止播放
mediaplayer1.Position:=trackbar1.Position;//将媒体位置设置为拖动的位置
mediaplayer1.Play;
//继续从当前位置播放
timer1.Enabled:=true;

end;


end.
 
Z

zhtq

Unregistered / Unconfirmed
GUEST, unregistred user!
这个问题难啊
 
L

luzhouman

Unregistered / Unconfirmed
GUEST, unregistred user!
在歌词文件中设置好与歌曲对应的时间点(要以出现多次)像这样,然后就好处理了

[00:00]东风破.mp3
[00:05]演唱:周杰伦
[00:10]编缉人:风帆
[00:14]一盏离愁
[00:16]孤单伫立在窗口
[00:20]我在门后
[00:22]假装你人还没走
[00:27]旧地如重游
[00:29]月圆更寂寞
[00:33]夜半清醒的烛火
[00:36]不忍苛责我
[02:29][00:40]一壶漂泊
[02:31][00:42]浪迹天涯难入喉
[02:35][00:46]你走之后
[02:37][00:48]酒暖回忆思念瘦
[02:42][00:54]水向东流
[02:44][00:56]时间怎么偷
[02:48][01:00]花开就一次成熟
[02:51][01:03]我却错过
[03:50][02:58][01:10]谁在用琵琶弹奏
[03:53][03:01][01:13]一曲东风破
[03:57][03:05][01:17]岁月在墙上剥落
[04:00][03:08][01:19]看见小时候
[04:04][03:12][01:23]犹记得那年
[04:06][03:14][01:25]我们都还很年幼
[04:10][03:18][01:30]而如今琴声幽幽
[04:13][03:21][01:32]我的等候你没听过
[04:17][03:24][01:36]谁在用琵琶弹奏
[04:20][03:27][01:39]一曲东风破
[04:23][03:30][01:43]枫叶将故事染色
[04:26][03:34][01:45]结局我看透
[04:30][03:37][01:49]籬笆外的古道
[04:33][03:40][01:52]我牵著你走过
[04:37][03:43][01:56]荒烟漫草的年头
[04:40][03:47][01:59]就连分手都很沉默
[02:04]东风破-周杰伦
 
Z

zhtq

Unregistered / Unconfirmed
GUEST, unregistred user!
luzhouman:
你好,我已经可以实现:歌曲拖到那,歌词显示到那。 但如何实现歌词拖到那,歌曲就播放那呢? 拖歌词好象有点难因为我的歌词是: DrawText,就是以下两段改怎么改能?
procedure TForm1.BmpCreate(LineHeight: word);
var
i,y:integer;
begin

if bmp<>nil then
bmp.free;
bmp:=TBitMap.Create;
with bRectdo
//Rect 矩形坐标(左上x,左下y,右上x,右下y)
begin

Top:=0;
Left:=0;
Right:=SongP.Width;
Bottom:=LineHeight*Item.Count+Height;//行高*行数+form高度
end;

Bmp.Height:=bRect.Bottom;//图片高度
Bmp.Width:=bRect.Right;
Bmp.Canvas.Brush.Color:=clInfoText;
Bmp.Canvas.FillRect(bRect);
Bmp.Canvas.Font.Color:=clRed;
//控制显示字体颜色
Bmp.Canvas.Font.Size:=LineHeight div 2 ;
//控制显示字体颜色
Bmp.Canvas.Brush.Style:=bsClear ;
R1:=bRect;
y:=SongP.Height-100;
for i:=0 to Item.Count-1do

begin

R1.Top:=y;
R1.Bottom:=R1.Top+LineHeight;
DrawText(Bmp.Canvas.Handle,pChar(Item),-1,R1,Dt_Center or Dt_Top);//中对齐
//DrawText(Bmp.Canvas.Handle,pChar(Item),-1,R1,Dt_Left or Dt_Top);
//左对齐
//DrawText(Bmp.Canvas.Handle,pChar(Item),-1,R1,Dt_Right or Dt_Top);//右对齐
Inc(y,LineHeight);
end;

end;


procedure TForm1.ShowText(SongName: string);
var
ss:string;
ReadFile:TextFile;
begin

if SongName='' then
exit;
AssignFile(ReadFile,SongName);
Reset(ReadFile);
Item:=TStringList.Create;
while not eof(ReadFile)do

begin

Readln(ReadFile,ss);
Item.Add(ss);
end;

CloseFile(ReadFile);
BmpCreate(30);
Item.Free;//释放串
end;
 
L

luzhouman

Unregistered / Unconfirmed
GUEST, unregistred user!
mediaplayer1.Position = 播放点
 

Similar threads

I
回复
0
查看
660
import
I
I
回复
0
查看
611
import
I
I
回复
0
查看
654
import
I
I
回复
0
查看
434
import
I
顶部