歌词流(Delphi /伪代码)

时间:2009-12-08 17:40:57

标签: delphi

我想建立一个程序,让歌曲的歌词在屏幕上运行。像这样:

http://www.youtube.com/watch?v=kIAiBvD9njM

你能帮助我吗?

算法:

  • 将标记推到适合音乐的行的右侧
  • 让当前行上方的一行消失
  • 在当前行上方插入一个新行

需要什么?

  • 歌曲的歌词(每行一行)
  • 时间发短信数据? (线路何时开始/结束)

有些方法对我有很大帮助。任何部分的伪代码甚至Delphi代码都会很棒。

4 个答案:

答案 0 :(得分:5)

如果您对pascal中的卡拉OK代码感兴趣,请务必查看 UltraStar Deluxe

这是一款超级光滑且非常受欢迎的卡拉OK应用程序。该项目是活跃的,它是开源的。它可以使用FPC编译到各种平台。你可以从Delphi和Lazarus编译它..很好。

http://ultrastardx.sourceforge.net/

我的邻居认为我的狗是他们最糟糕的噩梦,直到​​我找到了这个程序。

查看实际操作:po-po-po-pokerface po-po-pokerface.. mum mum mum mah!:)

答案 1 :(得分:3)

假设您有一个文本文件,其中包含要显示的文本以及何时高亮显示的注释时间(字幕文件的种类,例如标准提案w3c定时文本(http://www.w3.org/AudioVideo/TT/)或SUB - 多个媒体播放器使用的电影字幕文件格式。

您的程序必须首先读取并解析文本文件,然后解码带注释的时间。将它插入名为Subtitles的字符串列表中,哪些项目也会保留与此类似的对象

type tSubtitle = class
  num : integer;
  prevTime, fromTime : tdatetime;
  toTime, nextTime: tdatetime;
  text: string;
end;

您可能希望扩展对象以保留一些突出显示属性。

然后你只需要显示与计时器同步的那些对象。

procedure TForm1.Timer1Timer(Sender: TObject);
var rt : TDateTime;
    done:boolean; 
    si,st,sb:integer; 
    s:string;
begin
  rt:=now-startTime;
  st:=0;
  sb:=subtitles.Count;  // binary search the subtitle for the current time
  repeat
     si:=(st+sb) div 2;
     s:=TSubtitle(subtitles.Objects[si-1]);
     done:= ((t>=s.prevTime) and (t<=s.nextTime));
     if not done then 
     begin
        if t>s.prevTime then st:=si 
        else if t<s.nextTime then sb:=si;
        if st=sb then done:=true;
     end;
  until done;
  // do what you want with s
end;

答案 2 :(得分:2)

另一种选择是创建您自己解析的标记,其中包含文本和延迟时间。虽然定时器可以正常工作,但问题是随着时间的推移,它不够准确,无法提供可靠的结果,因为它基于消息传递而被解雇。相反,我会根据您希望事件发生的音乐文件开头的距离来执行触发器。如果某些其他应用程序拦截过程受阻,这也可以让系统赶上来,并且应该有助于保持同步。

简单的事情:

00:00:15;LYRIC;This is lyric line 1
00:00:18;FADEOUT
然后,您可以将其解析为采取适当操作的相应对象列表。

答案 3 :(得分:0)

你应该基于TGraphicControl / TCustomControl(任何带有画布的东西)创建一个新类并添加一个字符串属性,现在你必须创建一个定时器作为私有变量,并通过你的类发布它的间隔值,就像这样 ...

type TLyricViewer = class(TGraphicControl)
     private
       FTimer : TTimer;
       FLyric : string;
       FBitmap : TBitmap;// offset bitmap on which you draw
       // some more variables to store paint information
     private
       procedure OnNextWord(Sender: TObject);// assign this to FTimer.OnTimer event
     public
       constructor Create(AOwner: TComponent);
       destructor Destroy; override;
     public
       procedure StartLyric;
       procedure StopLyric; 
       procedure Paint; override;
     published
       property WordInterval : Integer|Cardinal
         read GetWordInterval write SetWordInterval;
end;
...
procedure TLyricViewer.Paint;
begin
 // here is where the magic happends
end;

constructor TLyricViewer.Create(AOwner: TComponent);
begin
 // create timer, bitmap and set default properties
end;

destructor TLyricViewer.Destroy;
begin
  // free and nil the timer and bitmap
  inherited Destroy;
end;

剩下的由您决定,在您获得报酬之后,为此工作:)