看实例玩编程(25):巧动手,解决MP3压缩层次判断
软件世界
问题的提出:近日看第22期《电脑报》,发现一篇关于MP3的文章,是说由于某些MP3播放器只能播放Layer3格式的文件,可以用Winamp的文件信息功能预先查看某个文件是否为Layer3格式的文件,对于Layer2的文件挑出来用超级解霸进行转换后再拷到MP3播放器中。笔者觉得这个方法实现起来有一定麻烦,必须手动播放每一个文件然后才能查看文件的格式,对于大量文件来说,是不可想象的。但编程会很容易解决这个问题。
问题的难点:要判断文件格式,需要首先获取MP3文件的头信息,但笔者在Internet上搜索了一天也没能找到相关的教程,笔者决定另辟蹊径:既然MP3文件有头,那么肯定会有固定的格式,不同格式的文件头数据必然不同。笔者读取Layer3文件的最前面5个字节,数据是:255 251 146 128 0,Layer2文件的数据是:255 253 130 0 33,由此可见,判断第二个字节的值即可获取MP3文件的层次。那么这么判断是否可行呢,笔者随机打开任何其他文件,都可得到同样的结论,于是说明该方法是可行的。另外一点需要注意:对于带有ID3v2信息的文件须做特殊处理,因为它有一个额外的文件头,上面的标志字节会移动到这个头的后面。这样的文件的第二个字节是68。
问题的解决:我们用VB6来编程解决。新建一个EXE工程,在主窗口上放置两个标签,Caption改为搜索路径和输出路径。两个文本框,并将Name分别改为PathX和OutPathX、一个命令按钮(Name:StartX,Caption:开始),对StartX按钮编写代码如下:
给出非Layer3文件清单
Private Sub StartX_Click()
If Pathx.Text <> “” Then '输出文件名清单
Set Fs = CreateObject(“scripting.filesystemobject”)
Set fsxx = Fs.createtextfile(CurDir & “\filelist.txt”, 1)
Set fd = Fs.getfolder(Pathx.Text)
If Not Fs.folderexists(Outpathx.Text) Then
Fs.createfolder Outpathx.Text
End If
StartX.Enabled = False
ChargeAllFiles fd, Fs, fsxx '遍历文件夹下非Layer3的MP3文件并输出
fsxx.Close
Set fsxx = Nothing
Set fd = Nothing
Set Fs = Nothing
StartX.Enabled = True
Shell “notepad.exe ” & CurDir & “\filelist.txt”, vbNormalFocus
Else
MsgBox “未指定搜索路径”,“提示”
End If
End Sub
输出非Layer3文件
其中用到的过程ChargeAllFiles的功能是遍历指定文件夹下的全部文件和子文件夹,并将非Layer3的MP3文件移动到输出路径下。代码如下:
Private Sub ChargeAllFiles(ByVal folderSx As Object, ByVal FsX As Object, ByVal FsFile As Object)
For Each filesx In folderSx.Files
If UCase(Right(filesx, 3)) = “MP3” Then '找出MP3文件
If GetLayer(filesx.Path) <> 3 Then '判断文件压缩层次
FsX.movefile filesx.Path, Outpathx.Text & “\” & filesx.Name
Else
FsFile.writeline Left(filesx.Name, InStr
Rev(filesx.Name, “.”) - 1)
End If
End If
Next
For Each SubFld In folderSx.subfolders
ChargeAllFiles SubFld, FsX, FsFile
Next
End Sub
判断音乐文件层次
在这个过程中用到的函数GetLayer即是判断MP3文件的格式。代码如下:
Public Function GetLayer(fName As String) As Integer
Dim ContentX As Byte, FnX As Integer
FnX = FreeFile
Open fName For Binary As #FnX
Get #FnX, , ContentX
Get #FnX, , ContentX '移动到第二字节
If ContentX = 68 Then '文件有ID3v2信息的处理方式
Do While ContentX <> 255
Get #FnX, , ContentX
Loop
Get #FnX, , ContentX
End If
If ContentX = 251 Then '根据文件头字节数判断文件压缩层次
GetLayer = 3
ElseIf ContentX = 253 Then
GetLayer = 2
Else
GetLayer = 255
End If
Close #FnX
End Function
程序功能很简单。运行代码后,在指定位置即可得到全部非Layer3文件,并且最后会弹出一个文本文件显示全部MP3文件的文件名,这样瞬间就可以挑选大量文件及获取文件名,快试一试吧。
本程序在WinXP+VB6环境下通过。
点评:本实例最大的亮点是作者解决未知MP3文件的头文件格式的方法。这类情况普遍出现在串并口通讯、IP包格式等问题中。在编程时缺乏专业资料的朋友不用犯愁,不妨借鉴一下他的方法。