[转载][分享]歌词同步显示功能

摘要:相信每个音乐Fans都对“千千静听”这个播放器非常熟悉了,她的歌词自动下载与同步显示功能,算是同类播放器中的靓点。今天,我们将浅析“千千静听”同步显示歌词的编程原理和编程模拟,并实现音频文件的自动播放。
  
【编程原理】
   
    要实现歌词与音频同步显示并让音频文件自动播放,我们首先要从网上下载音频文件(本文以MP3为例)和歌词文件(LRC格式),然后用VB制作一个简易的音频播放器,实现音频与歌词的同步播放,最后用WinRar或VB-PowerWrap工具实现音频文件与歌词的封装并自动播放。
  
【编程分析】
   
一、歌词同步原理
   
    千千静听的歌词文件扩展名为LRC,歌词是以句为单位进行显示,歌词文件中包含了歌词内容及歌词显示时的音频播放时间,歌词在后,时间在前,时间放在一对中括号内。在播放的时候,实时获取播放位置对应的播放时间,并从歌词文件中查找当前时刻对应的歌词并显示出来,这就是千千静听播放器的同步显示原理。在一首歌中,重复的歌词将对应两个或多个音频播放时间,如图1所示。歌词文件格式从本质上讲是文本格式,因此,我们可以用记事本对歌词进行编辑,如果从网上下载的歌词文件在播放时不能与音频同步,那么我们可以修改其中的时间,在歌曲的前奏音乐时间内,可以加入一些信息,如:专辑名称、词曲作者、歌手名称等等。  
 
 
图1 歌词文件

二、播放功能实现
   
    播放音频文件的方法很多,本文采用“Microsoft MultiMedia Control”控件(MCI32.OCX)实现,在调用Multimedia MCI控件之前,须要执行“工程\部件”菜单命令,将“Microsoft Multimedia Controls”前的方框选中,确定返回,在工具箱中便会出现Multimedia 控件图标,把 Multimedia 控件添加到窗体上,命名为Mci。
  
1、MCI控件的部分方法和属性如下:

   Mci.FileName = Mp3 ‘文件名
   Mci.Command = "Open" ‘打开
   Mci.Command = "Play" ‘播放
   Mci.Command = "Stop" ‘停止
   Mci.Command = "Close" ‘关闭
   Mci.Position:当前播放时间(毫秒)
   Mci.Length:总的播放时间(毫秒)

2、取得Windows临时文件夹
   
    把音频文件和歌词文件都放在程序同文件夹中,且名称都为Song(扩展名分别为MP3、LRC),程序运行时,将音频文件复制到Windows的临时文件夹中,并对其进行播放。取得Windows临时文件夹通过API函数GetTempPath实现,编程方法和核心代码如下:

   Function WinTempDir() As String
    Dim Tmp As String
    Dim tP As String
    Tmp = Space$(255)
    Call GetTempPath(Len(Tmp), Tmp)
    tP = Left(Trim$(Tmp), Len(Trim$(Tmp)) – 1)
    If Right$(tP, 1) <> "\" Then
    tP = tP + "\"
    End If
    WinTempDir = tP
   End Function
  
3、读入歌词
   
    在播放音频文件前,将当前文件夹中的歌词从文件中读入到列表框控件中,在播放的时候,可以通过播放时间提取歌词并显示,读入歌词文件的编程方法和核心代码如下:

   Function OpenLrc()
    ‘Lrc为歌词文件名
    Open Lrc For Input As #1
    While Not EOF(1)
    Line Input #1, S
    If Len(S) > 0 Then List1.AddItem S
    Wend
    Close #1
   End Function
  
4、程序初始化
   
    程序运行时取得当前文件夹和Windows临时文件夹,完成音频文件复制,读入歌词,同时删除当前文件夹中的音频文件和歌词文件,并开始音频播放,编程方法和核心代码如下:

   Private Sub Form_Load()
    Pa = App.Path
    tPa = WinTempDir
    tMp3 = Pa + "Song.mp3"
    Mp3 = tPa + "Song.mp3"
    Lrc = Pa + "Song.lrc"
    FileCopy tMp3, Mp3
    Call OpenLrc ‘歌词
    Kill tMp3: Kill Lrc
    ‘以上删除了音频文件和歌词文件,在程序调试期间,应取消此功能
    Mci.FileName = Mp3
    Mci.Command = "Open"
    Mci.Command = "Play"
   End Sub

5、歌词同步显示
   
    在音频播放时,通过定时器控件,获取当前音频播放时间(MM:SS,秒级),然后在列表框中查找当前时间对应的歌词,找到则显示歌词,编程方法和核心代码如下:

   ‘转换播放时间格式
   Function tFormat(iPos) As String
    M = iPos / 1000 \ 60 ‘分
    S = iPos / 1000 Mod 60 ‘秒
    If M < 10 Then Ret = "0"
    Ret = Ret + CStr(M) + ":"
    If S < 10 Then Ret = Ret + "0"
    Ret = Ret + CStr(S)
    tFormat = Ret
   End Function
   ‘查找歌词位置
   Function ListIdx(ItemTxt) As Integer
    For I = 0 To List1.ListCount – 1
    P = InStr(1, List1.List(I), ItemTxt)
    If P > 0 Then
    ListIdx = I: Exit Function
    End If
    Next
    ListIdx = -1
   End Function
   ‘同步显示歌词
   Private Sub Timer1_Timer()
    SetFormTop Me, True ‘窗体置顶
    Pos = tFormat(Mci.Position)
    Label3.Caption = Pos
    Idx = ListIdx(List1, Pos)
    If Idx <> -1 Then
    P = InStrRev(List1.List(Idx), "]", -1)
    GeCi = Mid$(List1.List(Idx), P + 1)
    If GeCi = "" Then
    Label2.Caption = "Music…"
    Else
    Label2.Caption = GeCi
    End If
    End If
   End Sub
  
6、窗体设置
   
    本文设计的简易播放器的窗体为对话框模式(BorderStyle=3),没有标题栏,在任务栏上没有显示,而且无法移动,所以要实现无标题栏窗体的移动,且要让窗体实时置于其它窗体之上。编程方法和核心代码如下:

   ‘窗体置顶
   Function SetFormTop(iForm As Form, iFlag As Boolean)
    If iFlag = True Then
    SetWindowPos iForm.hwnd, -1, 0, 0, 0, 0, 3
    Else
    SetWindowPos iForm.hwnd, -2, 0, 0, 0, 0, 3
    End If
   End Function
   ‘窗体移动准备
   Private Sub Frame1_MouseDown(参数略)
    If Button = 1 Then
    mX = X: mY = Y: mV = 1
    End If
   End Sub
   ‘移动窗体
   Private Sub Frame1_MouseMove(参数略)
    If Button = 1 And mV = 1 Then
    Me.Left = Me.Left + X – mX
    Me.Top = Me.Top + Y – mY
    End If
   End Sub
   ‘移动结束
   Private Sub Frame1_MouseUp(参数略)
    mV = 0
   End Sub

7、编译运行
   
    编译程序、运行,可以看到音频播放的同时,歌词在同步显示,如图2所示。

图2 程序运行

三、封装的实现
   
    上面已经实现了音频文件的播放与歌词的同步显示,但播放的是同文件夹中的音频文件,使用的是同文件夹中的歌词文件,实现了千千静听的同步显示播放功能。但如何将音频文件和歌词文件封装成一个可执行的包呢?在可执行包运行的时候,如何自动运行包中的音频播放器从包中读入歌词并播放包中的音频文件呢?
  
1、用WinRAR实现
   
    WinRAR可以实现将多个文件按自解压方式压缩成一个可执行的文件,而且可以设置解压后自动运行其中的某个程序(很多安装程序就是这样做的),利用这个方法,我们可以把上面设计的播放器和音频文件、歌词文件封装成一个可执行的包。当运行可执行包时,将自动释放包中的播放器、音频文件、歌词文件,并自动运行播放器开始播放。但这样有三个缺点:一是解压后可以看见音频文件和歌词文件,二是程序中使用的MCI播放控件无法自动注册,三是WinRar制作的压缩包在解压时有提示,需要用户进行解压确认。
  
2、用VB-PowerWrap实现
   
    VB-PowerWrap是发布VB程序的一个优秀的安装程序制作工具,她通过扫描一个VB的工程文件,自动将该工程所需要的文件加入到包中,同时可以添加其它任何类型的文件到包中,并创建一个包含所有必要文件和相关文件的可执行包供程序员发布。VB-PowerWrap使用了超强的压缩模块,能对所用的动态库文件进行压缩,这样可以创建出最小的EXE文件。该软件可以用于VB4、5、6版本中。
   
    用VB-PowerWrap封装的可执行包运行时,首先释放出其中的所有文件,并自动将VB运行库和第三方控件加载到内存并从磁盘删除释放的文件,随后自动运行工程中的执行程序。在本文设计的播放器中,自动将音频文件复制到临时文件夹并对其进行播放,同时删除了音频文件和歌词文件,所以,通过用VB-PowerWrap封装的运行包运行后,在磁盘上留下的仅仅是临时文件夹中的音频文件,这样,看起来就是一个可播放音乐的独立文件在运行。用VB-PowerWrap封装的步骤如下:

1)、安装并运行VB-PowerWrap;
   
2)、点击界面上的【VB工程】按钮,在弹出的对话框中,点击右上方的图标,选择刚编译的执行程序文件名并打开,随后选择工程文件名并打开;这时可看到你编制的程序所依赖的文件列表,从左下方选择你所使用的VB版本,然后点击完成按钮返回;
   
3)、添加音频文件和歌词文件
   
    通过软件界面上的【添加】按钮完成音频文件和歌词文件的添加,如图3所示。

图3 程序打包

4)、创建压缩包
   
    在链接工程和添加好其它文件之后,就可以点击软件界面上的【创建】按钮,几秒钟后就生成一个独立的执行程序包了。到此为止,新建立的执行程序就可以在其它任何Windows平台上独立运行了。
  
【编程后记】
   
    本文建立的VB工程和程序,具有通用性,你现在要做的就是,从网上下载你喜欢的歌曲文件和歌词文件,并以Song为文件名放到工程的同文件夹中,这个工作是很轻松的,然后通过VB-PowerWrap工具进行打包,这样就形成了能自动播放的音频文件。
   
    值得一提的是,你的程序经过VB-PowerWrap的封装,就变得相当精干了。源码下载http://family1.chinaok.com/down/200629/scode.rar 

本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/starlight36/archive/2007/02/05/1502505.aspx