抽时间把写功能完成了,本地测试通过,但是仅试了几个文件,没有充分测试,还是有可能会损坏文件,所以在使用前最好能做好备份测试一下
wmaExif.class.asp
测试代码:wma.asp
wmaExif.class.asp
- <%
- 'Author: dragonbbc
- 'Email: dragonbbc@163.com
- 'Blog: http://blog.csdn.net/dragonbbc
- '参考资料:
- 'http://linle.ycool.com/post.1255557.html
- 'http://www.itlearner.com/Article/2007/3944.shtml
- '需指定的属性
- 'File
- '可用方法
- 'CheckSize 检查文件大小
- 'Parse 读取信息
- 'GetInfo(TagName)
- 'SetInfo(TagName)
- 'SavaChange
- 'SaveTo(FileName)
- '常见TagName
- '标准Tag: Title, Artist, Copyright, Description
- '扩展Tag: WM/AlbumTitle, WM/EncodedBy, WM/Genre, WM/Lyrics, WM/Track, WM/Year, WM/URL, WM/UserWebURL, WMFSDKVersion, WM/TrackNumber
- Class wmaExif
- Public File '文件
- Public debugMode 'Debug模式
- Private objStream
- Private headtag, bodytag, std_tag, ext_tag
- Private headsize,headext1,tagnum,headext2,headbuf,bodysize,bodyext,bodybuf
- Private framebuf(),sectionbuf(),std_buf,ext_buf
- Private items1, items2
- Private isStdChanged, isExtChanged, extAddnum
- Private std_no, ext_no
- Private addExtbuf
- Private Sub Class_Initialize()
- headtag = "3026b2758e66cf11a6d900aa0062ce6c"
- bodytag = "3626b2758e66cf11a6d900aa0062ce6c"
- std_tag = "3326b2758e66cf11a6d900aa0062ce6c"
- ext_tag = "40a4d0d207e3d21197f000a0c95ea850"
- items1 = Array("Title", "Artist", "Copyright", "Description", "Reserved")
- 'items2 = Array("AlbumTitle", "EncodedBy", "Genre", "Lyrics", "Track", _
- ' "Year", "URL", "UserWebURL", "TrackNumber")
- isStdChanged = False
- isExtChanged = False
- extAddnum = 0
- End Sub
- Private Sub Class_Terminate
- on error resume next
- CloseStream
- End Sub
- 'CheckSize
- Public Function CheckSize()
- CheckSize = False
- CreateStream
- If ReadHeader = False Then Err("文件头读取失败")
- If ReadBody = False Then Err("文件头读取失败")
- DebugMsg("Head:"&CStr(headsize))
- DebugMsg("Body:"&Cstr(bodysize))
- DebugMsg("Total:"&objStream.size)
- If objStream.Size <> headsize + bodysize Then Err("文件大小有误")
- CheckSize = True
- CloseStream
- End Function
- 'GetInfo
- Public Function GetInfo(TagName)
- TagName = Replace(TagName, "/", "")
- If Eval("Not IsEmpty("&TagName&")") Then
- Execute("GetInfo = "&TagName)
- End If
- End Function
- 'SetInfo
- Public Function SetInfo(TagName, TagValue)
- SetInfo = False
- Select Case TagName
- Case "Title"
- If Eval(TagName&" <> TagValue") Then
- Execute(TagName&" = TagValue")
- isStdChanged = True
- End If
- Case "Artist"
- If Eval(TagName&" <> TagValue") Then
- Execute(TagName&" = TagValue")
- isStdChanged = True
- End If
- Case "CopyRight"
- If Eval(TagName&" <> TagValue") Then
- Execute(TagName&" = TagValue")
- isStdChanged = True
- End If
- Case "Description"
- If Eval(TagName&" <> TagValue") Then
- Execute(TagName&" = TagValue")
- isStdChanged = True
- End If
- Case "Reserved"
- If Eval(TagName&" <> TagValue") Then
- Execute(TagName&" = TagValue")
- isStdChanged = True
- End If
- Case Else
- tTagName = TagName
- TagName = Replace(TagName, "/", "")
- If Eval("IsEmpty("&TagName&")") Then
- Execute(TagName&" = TagValue")
- extAddnum = extAddnum + 1
- nbuf = WriteString(tTagName)
- nlen = LenB(nbuf)
- flag = 0
- vbuf = WriteString(TagValue)
- vlen = LenB(vbuf)
- addExtbuf = addExtbuf&WriteShort_UL(nlen)&nbuf&WriteShort_UL(flag)&WriteShort_UL(vlen)&vbuf
- ElseIf Eval(TagName&" <> TagValue") Then
- Execute(TagName&" = TagValue")
- isExtChanged = True
- End If
- End Select
- End Function
- 'SaveChange
- Public Function SaveChange()
- SaveTo(File)
- End Function
- 'SaveToFile
- Public Function SaveTo(FileName)
- 'Rebuild Standard frame
- If isStdChanged Then
- For i = 0 To 4
- Execute("tmpstr = "&items1(i))
- tmpbuf = WriteString(tmpstr)
- tmpStdbuf1 = tmpStdbuf1&WriteShort_UL(LenB(tmpbuf))
- tmpStdbuf2 = tmpStdbuf2&tmpbuf
- Next
- If IsEmpty(std_no) Then
- DebugMsg("standard frame added")
- std_buf = WriteHex(std_tag)&WriteLong_UL(24+10+LenB(tmpStdbuf2))&Chr(0)&Chr(0)&tmpStdbuf1&tmpStdbuf2
- Else
- DebugMsg("standard frame changed")
- framebuf(std_no) = LeftB(framebuf(std_no), 16)&WriteLong_UL(24+10+LenB(tmpStdbuf2))&MidB(framebuf(std_no), 21, 4)&tmpStdbuf1&tmpStdbuf2
- End If
- End If
- 'Rebuild Extended frame
- If isExtChanged Then
- DebugMsg("extended frame changed")
- For i = 0 To Ubound(sectionbuf)
- If IsEmpty(sectionbuf(i)) Then Exit For
- nlen = ReadShort_UL(MidB(sectionbuf(i), 1, 2))
- nbuf = ReadString(MidB(sectionbuf(i), 3, nlen))
- flag = ReadShort_UL(MidB(sectionbuf(i), 3+nlen, 2))
- Execute("vbuf = "&Replace(nbuf,"/",""))
- If flag = 0 Then
- vbuf = WriteString(vbuf)
- Else
- vbuf = WriteShort_UL(vbuf)&Chr(0)
- End If
- vlen = LenB(vbuf)
- tmpExtbuf = tmpExtbuf&MidB(sectionbuf(i), 1, 2+nlen+2)&WriteShort_UL(vlen)&vbuf
- Next
- framebuf(ext_no) = LeftB(framebuf(ext_no), 16)&WriteLong_UL(24+2+LenB(tmpExtbuf))&MidB(framebuf(ext_no), 21, 6)&tmpExtbuf
- End If
- If extAddnum > 0 Then
- If IsEmpty(ext_no) Then
- ext_buf = WriteHex(ext_tag)&WriteLong_UL(24+2+LenB(addExtbuf))&Chr(0)&Chr(0)&WriteShort_UL(extAddnum)&addExtbuf
- DebugMsg("extended frame generated")
- Else
- framebuf(ext_no) = LeftB(framebuf(ext_no), 16)&WriteLong_UL(LenB(framebuf(ext_no))+LenB(addExtbuf))&MidB(framebuf(ext_no), 21, 4)&WriteShort_UL(Ubound(sectionbuf)+extAddnum)&MidB(framebuf(ext_no), 27)&addExtbuf
- End If
- DebugMsg("extended frame added "&extAddnum&" content")
- End If
- For i = 1 To Ubound(framebuf)
- DebugMsg("merging framebuf"&i&",size:"&LenB(framebuf(i)))
- tmpheadbuf = tmpheadbuf&framebuf(i)
- Next
- If IsEmpty(std_no) Then
- DebugMsg("standard frame added,size:"&LenB(std_buf))
- tmpheadbuf = tmpheadbuf&std_buf
- End If
- If IsEmpty(ext_no) Then
- DebugMsg("extended frame added,size:"&LenB(std_buf))
- tmpheadbuf = tmpheadbuf&ext_buf
- End If
- totalframes = Ubound(framebuf)
- If Not IsEmpty(std_buf) Then totalframes = totalframes + 1
- If Not IsEmpty(ext_buf) Then totalframes = totalframes + 1
- tmpwmabuf = WriteHex(headtag)&WriteLong_UL(LenB(tmpheadbuf)+30) _
- & Cstr(headext1)&WriteLong_UL(totalframes)&Cstr(headext2)&tmpheadbuf _
- & WriteHex(bodytag)&WriteLong_UL(bodysize)&Cstr(bodyext)&CStr(bodybuf)
- DebugMsg("headext1(to write):"&ReadHex(Cstr(headext1)))
- DebugMsg("headext2(to write):"&ReadHex(Cstr(headext2)))
- DebugMsg("headsize(to write):"&LenB(tmpheadbuf)+30)
- DebugMsg("bodysize(to write):"&bodysize)
- DebugMsg("filesize(to write):"&LenB(tmpwmabuf))
- CreateStream
- With objStream
- .position = 0
- .Type = 2
- .WriteText tmpwmabuf
- .SetEOS
- .position = 0
- .Type = 1
- .Read(2)
- tmpbuf = .Read
- .position = 0
- .Write tmpbuf
- .SetEOS
- DebugMsg("end position(to write):"&.position)
- DebugMsg("file size(to write):"&.Size)
- .SaveToFile FileName,2
- End With
- CloseStream
- End Function
- 'Parse
- Public Function Parse()
- CreateStream
- If ReadHeader = False Then Exit Function
- DebugMsg("find "&tagnum&" frames,total size:"&LenB(headbuf))
- ReDim framebuf(tagnum)
- head_off = 1
- For j = 1 To tagnum
- If Not IsEmpty(std_no) And Not IsEmpty(ext_no) Then
- framebuf(j) = MidB(headbuf,head_off)
- DebugMsg("escape other frames,start from position:"&CStr(head_off)&",total size:"&LenB(framebuf(j)))
- Exit For
- End If
- frame_head = MidB(headbuf, head_off, 24)
- frametag = ReadHex(LeftB(frame_head, 16))
- framesize = ReadLong_UL(MidB(frame_head,17,4))
- framebuf(j) = MidB(headbuf,head_off,framesize)
- DebugMsg("frame"&j&":"&ReadHex(frame_head)&" size:"&framesize)
- head_off = head_off + 24
- If frametag = std_tag Then
- DebugMsg("standard frame no:"&j&" size:"&framesize)
- std_no = j
- Dim lenx(5)
- tmp_off = 0
- For i = 0 To 4
- lenx(i) = ReadShort_UL(MidB(headbuf, head_off+2*i, 2))
- tempstr = ReadString(MidB(headbuf, head_off+10+tmp_off, lenx(i)))
- tmp_off = tmp_off + lenx(i)
- Execute(items1(i)&" = tempstr")
- Next
- head_off = head_off + 10 + tmp_off
- DebugMsg("current offeset:"&Cstr(head_off))
- ElseIf frametag = ext_tag Then
- DebugMsg("extended frame no:"&j&" size:"&framesize)
- ext_no = j
- inum = ReadShort_UL(MidB(headbuf, head_off, 2))
- Redim sectionbuf(inum)
- tmp_off = 2
- k = 0
- While k < inum And tmp_off+24 < framesize
- nlen = ReadShort_UL(MidB(headbuf, head_off+tmp_off, 2))
- nbuf = ReadString(MidB(headbuf, head_off+tmp_off+2, nlen))
- flag = ReadShort_UL(MidB(headbuf, head_off+tmp_off+2+nlen, 2))
- vlen = ReadShort_UL(MidB(headbuf, head_off+tmp_off+2+nlen+2, 2))
- vbuf = MidB(headbuf, head_off+tmp_off+2+nlen+4, vlen)
- If flag = 0 Then
- vbuf = ReadString(vbuf)
- Else
- vbuf = ReadShort_UL(vbuf)
- End If
- 'on error resume next
- Execute(Replace(nbuf,"/","")&" = vbuf")
- 'err.clear
- sectionbuf(k) = MidB(headbuf, head_off+tmp_off, 6+nlen+vlen)
- tmp_off = tmp_off + 6 + nlen + vlen
- k = k + 1
- Wend
- head_off = head_off + framesize-24
- DebugMsg("current offeset:"&Cstr(head_off))
- Else
- head_off = head_off + framesize-24
- DebugMsg("current offeset:"&Cstr(head_off))
- End If
- Next
- CloseStream
- End Function
- 'get the header
- Private Function ReadHeader()
- ReadHeader = False
- buf = objStream.Read(30)
- If ReadHex(LeftB(buf, 16)) <> headtag Then Exit Function
- headsize = ReadLong_UL(MidB(buf,17,4))
- headext1 = MidB(buf,21,4)
- tagnum = ReadLong_UL(MidB(buf,25,4))
- headext2 = MidB(buf,29,2)
- DebugMsg("headext1:"&ReadHex(headext1))
- DebugMsg("headext2:"&ReadHex(headext2))
- headbuf = objStream.Read(headsize-30)
- ReadHeader = True
- End Function
- 'get the body
- Private Function ReadBody()
- ReadBody = False
- buf = objStream.Read(24)
- If ReadHex(LeftB(buf, 16)) <> bodytag Then Exit Function
- bodysize = ReadLong_UL(MidB(buf,17,4))
- bodyext = MidB(buf,21,4)
- DebugMsg("bodyext:"&ReadHex(bodyext))
- bodybuf = objStream.Read(bodysize-24)
- ReadBody = True
- End Function
- 'CreateStream
- Public Function CreateStream()
- on error resume next
- Set objStream = Server.CreateObject("ADODB.Stream")
- objStream.Type = 1
- objStream.Open
- Err.clear
- objStream.LoadFromFile File
- If err<>0 Then
- File = server.mappath(File)
- objStream.LoadFromFile File
- End If
- Err.clear
- End Function
- 'CloseStream
- Public Function CloseStream()
- objStream.close
- Set objStream = nothing
- End Function
- 'Read String From Byte
- Private Function ReadString(binstr)
- If LenB(binstr) > 2 And ReadHex(RightB(binstr, 2)) = "0000" Then
- ReadString = LeftB(binstr, LenB(binstr)-2)
- Else
- ReadString = binstr
- End If
- End Function
- 'Read Hex From Byte
- Private Function ReadHex(binstr)
- ReadHex = ""
- on error resume next
- For i = 1 To LenB(binstr)
- ReadHex = ReadHex & Hex((AscB(MidB(binstr,i,1)) And &HF0)/16) & Hex(AscB(MidB(binstr,i,1)) And &H0F)
- Next
- ReadHex = LCase(ReadHex)
- End Function
- 'Read Unsigned Long(Little Endian) From Byte
- Private Function ReadLong_UL(binstr)
- ReadLong_UL = 0
- on error resume next
- ReadLong_UL = AscB(MidB(binstr,1,1)) + AscB(MidB(binstr,2,1))*256 + AscB(MidB(binstr,3,1))*65536 + AscB(MidB(binstr,4,1))*16777216
- End Function
- 'Read Unsigned Short(Little Endian) From Byte
- Private Function ReadShort_UL(binstr)
- ReadShort_UL = 0
- on error resume next
- ReadShort_UL = AscB(MidB(binstr,1,1)) + AscB(MidB(binstr,2,1))*256
- End Function
- 'Write String To Byte
- Private Function WriteString(rawstr)
- If LenB(rawstr) = 0 Then
- WriteString = rawstr
- Else
- WriteString = rawstr&Chr(0)
- End If
- End Function
- 'Write Hex To Byte
- Private Function WriteHex(hexstr)
- For i = 1 To Len(hexstr)/2
- WriteHex = WriteHex & ChrB("&H"&Mid(hexstr, i*2-1, 2))
- Next
- End Function
- 'Write Unsigned Long(Little Endian) To Byte
- Private Function WriteLong_UL(lnum)
- WriteLong_UL = ChrB(lnum Mod 256) & ChrB(lnum/256 Mod 256) & ChrB(lnum/65536 Mod 256) & ChrB(lnum/16777216 Mod 256)
- End Function
- 'Write Unsigned Short(Little Endian) To Byte
- Private Function WriteShort_UL(snum)
- WriteShort_UL = ChrB(snum Mod 256) & ChrB(snum/256 Mod 256)
- End Function
- 'Print error message
- Private Function Err(errmsg)
- Response.Write "<b>err:</b>"
- Response.Write errmsg
- Response.End
- End Function
- 'Print debug message
- Private Function DebugMsg(msg)
- If DebugMode = True Then
- Response.Write "<b>Debug:</b>"
- Response.Write msg
- Response.Write "<br />"
- End If
- End Function
- End Class
- %>
测试代码:wma.asp
- <!-- #include file="wmaExif.class.asp" -->
- <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
- <html xmlns="http://www.w3.org/1999/xhtml">
- <head>
- <meta http-equiv="Content-Type" content="text/html; charset=gb2312" />
- <title>利用ASP获取WMA的TAG信息</title>
- </head>
- <body>
- <%
- dim info
- set info = New wmaExif
- set info.File=request("soundPath")
- If info.CheckSize = True Then
- info.Parse
- Response.write "歌名:"&info.GetInfo("Title")&"<br/>"
- Response.write "歌手:"&info.GetInfo("Artist")&"<br/>"
- Response.write "版权:"&info.GetInfo("CopyRight")&"<br/>"
- Response.write "注释:"&info.GetInfo("Description")&"<br/>"
- Response.write "专辑:"&info.GetInfo("WM/AlbumTitle")&"<br/>"
- Response.write "曲目:"&info.GetInfo("WM/TrackNumber")&"<br/>"
- Response.write "发行年份:"&info.GetInfo("WM/Year")&"<br/>"
- Response.write "类型:"&info.GetInfo("WM/Genre")&"<br/>"
- Response.write "测试:"&info.GetInfo("AverageLevel")&"<br/>"
- ' info.SetInfo "Title", info.GetInfo("Title")
- info.SetInfo "Title", "歌名测试"
- info.SetInfo "Artist", "歌手测试"
- info.SetInfo "CopyRight", "版权测试"
- info.SetInfo "Description", "备注测试"
- info.SetInfo "WM/Year", "2009"
- info.SetInfo "WM/AlbumTitle", "test"
- info.SetInfo "WM/AlbuadmTitle", "test1"
- ' info.SaveChange
- info.SaveTo(server.mappath("test.wma"))
- Else
- Response.Write "error"
- End If
- set info = Nothing
- %>
- </body>
- </html>