请登录[¤ 阳光论坛 ¤]参与讨论


阳光宝宝
90

 □ 主题: 转:VB制作 smi 字幕文件的方法
 □ 内容: 1楼

      制作 smi 字幕文件的方法 
       
        微软的媒体播放器 wmplayer 使用 smi 字幕文件,可以使字幕与唱词同步。先来了解一下 smi 文件的基本结构: 
       
      <SAMI> 
      <head> 
      <style type="text/css"><!-- 
      p {font-size:24pt;font-family:楷体_GB2312;} 
      .FRCC {lang: ZH-CN;}--> 
      </style> 
      </head> 
      <body> 
      <sync start=10><p class=EGCC>敖包相会(歌手:张振富、耿莲凤) 
      <sync start=25158><p class=EGCC>(男)十五的月亮升上了天空哎 
      …… 
      </body> 
      </SAMI> 
       
        可以看出,smi 文件是用超文本语言写的。注意二点: 
      1.“start=****”时间参数,是以毫秒为单位的。 
      2.“{font-size:24pt;font-family:楷体_GB2312;}”这里只有2个参数,分别是字体大小和字体名称。还可以写成这样: 
       
       { background-color: #000000; text-align: center; font-size: 24pt; font-family: 宋体; font-weight: bold; } 
       
      参数1:可选,字幕条的背景颜色为黑色,缺省为黑色。 
      参数2:可选,文本显示位置为窗口中央,缺省为左。 
      参数3:字体大小。 
      参数4:字体名称。 
      参数5:可选,字体重量为粗体。 
       
        参数的顺序没有严格要求,但必须以分号分隔。 
        下面介绍两种制作 smi 文件的方法。 
       
      一、使用 txt 歌词文件 
        如果我们用 MMControl 控件制作了一个播放器,利用该控件的 Position 属性,我们就可以实时制作 smi 字幕文件。当然,你还必须要有同名的 txt 歌词文件,这可以在网上下载,也可以自己编制。 
        MMControl 控件的 Position属性的作用是:根据指定的 TimeFormat 返回已打开的设备的位置,一般用四字节表示,只读。在使用 Position 属性之前,要先设置属性 TimeFormat=0,这样 Position属性返回的时间单位就是毫秒。 
        新建一个工程,在窗体上添加一个 MMControl 控件(将其名称改为MMC),一个 CommonDialog 控件、三个按纽、一个标签(标签的作用是显示当前的歌词),属性设置为: 
       
      MMControl 控件:在属性页中将所有的自带按纽均设置为无效和不可见。 
      三个按纽控件的名称与标题相同,分别为:openTXT、playMCI、txtTOsmi。 
       
        代码如下: 
       
      Option Explicit 
       
      Dim lrcST As String, smiST As String, txtST As String 
       
      * Sub playMCI_Click() 
      CommonDialog1.Filter = "*.mp3;*.wma|*.mp3;*.wma" 
      With MMC 
       .FileName = openFile(1) 
       .Command = "Open" 
       .TimeFormat = 0 ''时间格式为毫秒 
       .Notify = True ''打开通知 
       .Command = "play" 
      End With 
      End Sub 
       
      * Sub MMC_Done(NotifyCode As Integer) 
      If NotifyCode = 1 Then ''如果播放完毕 
       MMC.Command = "stop" 
       MMC.Command = "close" 
      End If 
      End Sub 
       
      * Sub openTXT_Click() 
      CommonDialog1.Filter = "txt 歌词文件(*.txt)|*.txt" 
      txtST = openFile(0) 
      End Sub 
       
      * Sub txtTOsmi_Click() 
      Dim k1 As Long, t As Long 
       
      If Len(txtST) < 2 Then 
       saveFile 
       Exit Sub 
      End If 
       
      t = MMC.Position ''取得播放时间位置 
      k1 = InStr(txtST, "~") 
      Label1 = Left$(txtST, k1 - 1) 
      txtST = Mid$(txtST, k1 + 1) 
      smiST = smiST & "<sync start=" & t & "><p class=EGCC>" & Label1.Caption & "~" 
      End Sub 
       
      * Function openFile(bj As Boolean) As String 
      On Error GoTo 100 
      CommonDialog1.Flags = &H1808 
      CommonDialog1.DialogTitle = "打开文件" 
      CommonDialog1.ShowOpen 
      If Dir(CommonDialog1.FileName) = "" Then Exit Function 
      If bj Then openFile = CommonDialog1.FileName: Exit Function 
        
      Dim z As String, st As String 
      Open CommonDialog1.FileName For Input As #1 
      Do Until EOF(1) 
       Line Input #1, z 
       If Len(z) > 0 Then st = st & z & "~" ''用这个不常用的字符"~"作为歌词句的分隔符 
      Loop 
      smiST = "": openFile = st 
      100 
      Close 
      End Function 
       
      * Sub saveFile() ''保存smi文件 
      On Error GoTo 100 
      CommonDialog1.DialogTitle = "保存" 
      CommonDialog1.Filter = "smi 文件(*.smi)|*.smi|" 
      CommonDialog1.Flags = &H200A 
      CommonDialog1.ShowSave 
      If CommonDialog1.FileName = "" Then Exit Sub 
      Dim st As String 
      smiST = "<SAMI><head>" & vbCrLf & "<style type=" & Chr(34) & "text/css" & Chr(34) & _ 
       "><!--" & vbCrLf & "p {font-size:24pt;font-family:楷体_GB2312;}" & vbCrLf & _ 
       ".FRCC {lang: ZH-CN;}" & "--></style></head>" & vbCrLf & "<body>" & vbCrLf & _ 
       smiST & "</body></SAMI>" 
      st = Replace(smiST, "~", vbCrLf) 
      Open CommonDialog1.FileName For Output As #1 
      Print #1, st 
      100 
      Close 
      End Sub 
       
        使用方法:首先点击【openTXT】,打开有关的 TXT 歌词文件,然后点击【playMCI】,这时候你就要认真听,当听到歌手将要唱到下一句时,就用鼠标点一下【txtTOsmi】,这样边听边点击地操作,一直到整首歌曲唱完,最后保存。如果不小心,某一句的时间误差太大,还可以用记事本打开 smi 文件修改。 
       
       
      二、利用 lrc 文件转换 
        这个就要简单多了,因为 lrc 文件已经包括了时间参数,好处是可以批量操作。 
        在窗体上再添加二个按纽,名称与标题相同,分别为:openLRC、lrcTOsmi。 
        添加如下代码: 
       
      * Sub openLRC_Click() 
      CommonDialog1.Filter = "Lrc 歌词文件(*.lrc)|*.lrc" 
      lrcST = openFile(0) 
      End Sub 
       
      * Sub lrcTOsmi_Click() 
      Dim k1 As Long ''歌词句在文件中的起始位置 
      Dim k2 As Long ''歌词句的长度 
      Dim t As Long 
      Dim s As String, z As String 
       
      k1 = 1: k2 = InStr(k1, lrcST, "~") 
      Do While k2 > 0 ''如果有"~"字符就继续循环 
       z = Mid$(lrcST, k1, k2 - k1) ''从歌词句中取出含有方括号的字串 
       k1 = k2 + 1 ''设置下一歌词句在文件中的起始位置 
       s = Mid$(z, 2, InStr(z, "]") - 2) ''取出去掉了方括号的字串 
       If IsNumeric(Left$(s, 2)) Then ''如果是时间字串 
       t = Val(s) * 60000 + Val(Mid$(s, 4)) * 1000 ''将时间字串转换为毫秒 
       smiST = smiST & "<sync start=" & t & "><p class=EGCC>" & Mid$(z, InStr(z, "]") + 1) & "~" 
       End If 
       k2 = InStr(k1, lrcST, "~") 
      Loop 
       
      saveFile 
      End Sub 
       
        使用方法:首先点击【openLRC】,打开有关的 lrc 歌词文件,然后点击【lrcTOsmi】,几乎是眨 
      眼间,就已经转换完毕,最后保存。 
       
       
      参考: 
        smi 字幕可以在 wmplayer 播放器窗口显示二行,相当于预告下一句的内容。这两行的颜色可以不相同,例如: 
       
      …… 
      <sync start=10><p class=EGCC><font color=#FFFFFF>十送红军(江西民歌)</font><br><font color=#6888E0>一送(里格)红军,(介支个)下了山,</font> 
      <sync start=17180><p class=EGCC><font color=#6888E0>秋风(里格)细雨,(介支个)缠绵绵。</font><br><font color=#FFFFFF>一送(里格)红军,(介支个)下了山,</font> 
      …… 
       
        代码中超文本标记的意义: 
       
      <font color=#FFFFFF>:定义紧随其后的字体颜色,颜色可以是6位16进制数值(前面要加一个“#”字符),也可以是超文本语言的颜色常数(相当于 VB 的颜色常数),例如:black(黑色)、olive(橄榄色)、teal(鸭绿)等等,共 16 种颜色。 
       
      </font>:先前有关字体的定义到此为止,后面如果没有再次定义,将恢复默认定义。 
       
      <br>:相当于 VB 中的回车换行符。 
       
       
        大家如有兴趣,请自行研究制作方法,并不难。 
       
       
      附:在自制播放器中使用 smi 字幕文件的方法 
       
        在窗体上再添加一个计时器控件,Inteval = 20,Enabled = False。 
        歌词就使用刚制作好的 smi 文件(当然,你也可以再增加一个【openSMI】按纽,请自编代码)。 
        增加一个模块级变量: 
       
      Dim BJMode As Boolean ''True-显示歌词;False-制作歌词 
      Dim posit As Long ''smi文件中的时间参数位置 
       
        在 Sub saveFile() 过程后面增加一句:BJMode = True 
        在 Function openFile 函数后面增加一句:BJMode = False 
        在 Sub playMCI_Click 过程后面增加一句:If BJMode Then posit = 1: Timer1.Enabled = True 
        编写 Timer1_Timer 过程代码: 
       
      * Sub Timer1_Timer() 
      Dim t As Long, k1 As Long, k2 As Long 
      If posit > Len(smiST) - 15 Then Timer1.Enabled = False: Exit Sub 
      k1 = InStr(posit, smiST, "start=") ''查找时间字串 
      t = Val(Mid$(smiST, k1 + 6, 8)) ''取出时间 
      If Abs(MMC.Position - t) < 200 Then ''如果歌词与播放进度的时间差小于200毫秒 
       k1 = InStr(k1, smiST, "EGCC>") ''查找歌词文本起点 
       k2 = InStr(k1, smiST, "~") ''查找歌词文本终点 
       Label1 = Mid$(smiST, k1 + 5, k2 - k1 - 5) ''取出歌词字串显示在标签上 
       posit = k2 + 1 
      End If 
      End Sub 
       
        使用方法:制作完成 smi 文件后,再点击【playMCI】按纽即可。 
       
      
——
      
争分夺秒背单词 → pamphlet  n.小册子
 □ 发帖时间:2012-2-20|10:25:13 |回复|返回|

 页次:1/1页 每页10  本主题贴数0 分页: 1


你还没有登录论坛,所以不能发表你的意见。你可以选择:

1、我已注册,我要

2、我还没注册,我要

3、太麻烦了,我还是

Go Top

Copyright by(C)2003-2015 http://abc.sy578.cn