分享
 
 
 

无外部控件制作多媒体播放器(二)

王朝other·作者佚名  2006-01-09
窄屏简体版  字體: |||超大  

本来想写点进度控制与音量调整的代码的,后来发现还是太简单了,就是几个MCI命令,来回搬弄,自己都没兴趣写下去。所以我想还是写些独门一点的:音乐信息的读取!

目前常见的主流音乐格式就两种,MP3与WMA,它们都有在文件中保存音乐信息的特定格式,MP3使用的当然是家喻户晓的ID3格式,分为V1与V2两个版本;WMA是MS的宠儿,它只是ASF格式的一个分支,当然遵循ASF的包装规则。

怎么获取它们包含的音乐信息呢?一般是自己读取,当然XP系统开始提供了音乐文件的详细信息资料,利用FSO可以真接从系统那里读取到,这不在本文范围,毕竟不用控件更自由,通用性更好。所以,有必要去深入一下这几种音乐信息格式。还是用代码说话吧,先说说MP3的ID3V1与ID3V2的格式。

ID3V1很简单,共128个字节,写在文件尾部,格式如下:

Private Type Mp3ID3V1

Header As String * 3

Title As String * 30

Artist As String * 30

Album As String * 30

Year As String * 4

Comment As String * 30

Genre As String * 1

End Type

ID3V2是后来出现的,可扩展性很强,写在文件头部,采用标签组格式,分两部分,一是标签组的总头部,一是每个子标签的头部,分别定义如下:

Private Type Mp3ID3V2

Header As String * 3

Ver As Byte

Revision As Byte

Flag As Byte

Size(3) As Byte

End Type

Private Type Mp3ID3V2Tag

Tag As String * 4

Size(3) As Byte

Flag(1) As Byte

End Type

为了组织音乐信息的方便,我还定义了一个自己的结构,以便于使用:

'音乐类型

Private Enum MediaType

mciMIDI = 1

mciMP3 = 2

mciASF = 4

mciVIDEO = 8

mciWAVE = 16

End Enum

'装载音乐信息的结构

Private Type MusicInfo

FileName As String

MusicType As MediaType

Title As String

Artist As String

Album As String

Year As String

Lyrics As String

Writer As String

Composer As String

Bits As String

Sample As String

Length As Long

End Type

'我习惯于用代码说明问题,所以还是看看代码吧

Private Function GetMusicInfo(udtInfo As MusicInfo) As Boolean

Dim strFileName As String, a() As String, i As Long

With udtInfo

strFileName = Dir(.FileName, vbNormal Or vbHidden Or vbReadOnly Or vbSystem Or vbArchive)

If strFileName = vbNullString Then Exit Function

.MusicType = GetMCIType(strFileName)

If .MusicType And mciMP3 Then

GetMusicInfo = GetMP3Info(udtInfo)

ElseIf .MusicType And mciASF Then

GetMusicInfo = GetASFInfo(udtInfo)

End If

End With

End Function

Private Function GetMCIType(strFileName As String) As MediaType

Dim ext As String

If strFileName <> vbNullString Then

ext = LCase$(Mid$(strFileName, InStrRev(strFileName, ".")))

Select Case ext

Case ".mpg", ".mpeg", ".avi", ".mpe", ".mpa", ".m1v", ".ifo", ".vob"

GetMCIType = mciVIDEO

Case ".mp3"

GetMCIType = mciMP3

Case ".wav", ".snd", ".aif", ".au", ".aifc", ".aiff"

GetMCIType = mciWAVE

Case ".asf", ".wma", ".wm", ".wmd"

GetMCIType = mciASF

Case ".wmv"

GetMCIType = mciASF Or mciVIDEO

Case ".mid", ".midi", ".rmi"

GetMCIType = mciMIDI

End Select

End If

End Function

Private Function GetMP3Info(udtInfo As MusicInfo) As Boolean

Dim FreeNo As Long, n(1) As Byte, b() As Byte, TmpInfo As MusicInfo

Dim Power As Long, v As Long, j As Long, Tagh As Mp3ID3V2Tag

Dim id3 As Mp3ID3V1, s As String, Pos As Long, id32 As Mp3ID3V2

Dim sz As Long, s1 As String

TmpInfo = udtInfo

On Error GoTo exitg

FreeNo = FreeFile

Open TmpInfo.FileName For Binary As #FreeNo

With TmpInfo

Pos = LOF(FreeNo) - 127

If Pos > 0 Then

Get #FreeNo, Pos, id3

If UCase$(id3.Header) = "TAG" Then

s = Trim$(Replace$(id3.Title, vbNullChar, vbNullString))

If Len(s) > 0 Then

s = Replace$(s, "-", vbNullString)

s = Replace$(s, "——", vbNullString)

s = Replace$(s, ".mp3", vbNullString, , , vbTextCompare)

.Title = s

End If

s = Trim$(Replace$(id3.Artist, vbNullChar, vbNullString))

If Len(s) > 0 Then

.Title = Replace$(.Title, s, vbNullString)

.Artist = s

End If

s = Trim$(Replace$(id3.Album, vbNullChar, vbNullString))

If Len(s) > 0 Then .Album = s

s = Trim$(Replace$(id3.Year, vbNullChar, vbNullString))

If Len(s) > 0 Then .Year = s

End If

End If

Get #FreeNo, 1, id32

If id32.Header = "ID3" Then

sz = (id32.Size(1) And &H7F) * &H400 + (id32.Size(2) And &H7F) * &H80 + (id32.Size(3) And &H7F)

Pos = sz + 10

s1 = String(4, vbNullChar)

Get #FreeNo, , Tagh

Do While Not (Tagh.Tag = s1 Or Seek(FreeNo) > sz + 10)

j = Tagh.Size(1) * &H10000 + Tagh.Size(2) * &H100 + Tagh.Size(3)

If j > 0 Then

ReDim b(j - 1)

Get #FreeNo, , b

s = StrConv(b, vbUnicode)

s = Trim$(Replace$(s, vbNullChar, ""))

Select Case Tagh.Tag

Case "TIT2"

.Title = s

Case "TPE1"

.Artist = s

Case "TALB"

.Album = s

Case "TCOM"

.Composer = s

Case "TEXT"

.Writer = s

Case "TYER"

.Year = s

Case "USLT"

s = Replace$(s, " ", " ")

If LCase$(Left$(s, 3)) = "chi" Then

.Lyrics = Mid$(s, 4)

ElseIf LCase$(Left$(s, 3)) = "eng" Then

.Lyrics = Mid$(s, 4)

Else

.Lyrics = s

End If

End Select

End If

Get #FreeNo, , Tagh

Loop

Else

Pos = 1

End If

Get #FreeNo, Pos, n

sz = Pos

If Not (n(0) = &HFF And n(1) >= &HFA And n(1) <= &HFF) Then

Do While Not (n(0) = &HFF And n(1) = &HFB)

Pos = Pos + 1

If Seek(FreeNo) - sz > 8192 Then GoTo exitg

Get #FreeNo, Pos, n

Loop

End If

Get #FreeNo, , n

v = 0

For j = 4 To 7

Power = 2 ^ j

If (n(0) And Power) = Power Then v = v + Power

Next

v = v \ 16

.Bits = Trim$(Mid$("144 320 32 48 56 64 80 96 112 128 160 192 224 256 320 ", v * 4 + 1, 4)) & "Kbps"

v = 0

For j = 2 To 3

Power = 2 ^ j

If (n(0) And Power) = Power Then v = v + Power

Next

v = v \ 4

.Sample = Trim$(Mid$("44 48 32 ?? ", v * 3 + 1, 3)) & "KHz"

End With

udtInfo = TmpInfo

GetMP3Info = True

exitg:

Close #FreeNo

End Function

还有个ASF格式,有点烦,下篇再做说明吧!

 
 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
2023年上半年GDP全球前十五强
 百态   2023-10-24
美众议院议长启动对拜登的弹劾调查
 百态   2023-09-13
上海、济南、武汉等多地出现不明坠落物
 探索   2023-09-06
印度或要将国名改为“巴拉特”
 百态   2023-09-06
男子为女友送行,买票不登机被捕
 百态   2023-08-20
手机地震预警功能怎么开?
 干货   2023-08-06
女子4年卖2套房花700多万做美容:不但没变美脸,面部还出现变形
 百态   2023-08-04
住户一楼被水淹 还冲来8头猪
 百态   2023-07-31
女子体内爬出大量瓜子状活虫
 百态   2023-07-25
地球连续35年收到神秘规律性信号,网友:不要回答!
 探索   2023-07-21
全球镓价格本周大涨27%
 探索   2023-07-09
钱都流向了那些不缺钱的人,苦都留给了能吃苦的人
 探索   2023-07-02
倩女手游刀客魅者强控制(强混乱强眩晕强睡眠)和对应控制抗性的关系
 百态   2020-08-20
美国5月9日最新疫情:美国确诊人数突破131万
 百态   2020-05-09
荷兰政府宣布将集体辞职
 干货   2020-04-30
倩女幽魂手游师徒任务情义春秋猜成语答案逍遥观:鹏程万里
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案神机营:射石饮羽
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案昆仑山:拔刀相助
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案天工阁:鬼斧神工
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案丝路古道:单枪匹马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:与虎谋皮
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:李代桃僵
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:指鹿为马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:小鸟依人
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:千金买邻
 干货   2019-11-12
 
推荐阅读
 
 
 
>>返回首頁<<
 
靜靜地坐在廢墟上,四周的荒凉一望無際,忽然覺得,淒涼也很美
© 2005- 王朝網路 版權所有