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

控件|媒体

ASF全名为高级系统格式,是MS大力推宠的一种媒体格式,并已得到广泛支持。其最主要的分支就是用于音频的WMA与视频的WMV,当然还有ASF自身。
在下面地址可下载到ASF格式的说明文档:
http://www.microsoft.com/windows/windowsmedia/format/asfspec.aspx

ASF格式由一个个不同功能的ASF对象组成,每个对象都有一个GUID做标识,你只需识别对象后,按对象格式读结构,就能找到你要的信息。
媒体信息内容都在ASF头部对象ASF_Header_Object中,头部对象又包含若干子对象,其中与媒体信息有关的对象也就三个:ASF_Codec_List_Object、ASF_Content_Description_Object、ASF_Extended_Content_Description_Object,本文也就是针对这三个对象的读写。

'ASF格式的几个与音乐信息相关的对象
Private Const ASF_Header_Object = "{75B22630-668E-11CF-A6D9-00AA0062CE6C}"
Private Const ASF_Codec_List_Object = "{86D15240-311D-11D0-A3A4-00A0C90348F6}"
Private Const ASF_Content_Description_Object = "{75B22633-668E-11CF-A6D9-00AA0062CE6C}"
Private Const ASF_Extended_Content_Description_Object = "{D2D0A440-E307-11D2-97F0-00A0C95EA850}"
'GUID对象标识
Private Type GUID
    dwData1 As Long
    wData2 As Integer
    wData3 As Integer
    abData4(7) 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
'ASF对象标识结构
Private Type ObjHeader
  ID As GUID
  Size(1) As Long
End Type
'ASF文件头对象结构
Private Type ASFHeader
    HeaderInfo As ObjHeader
    NumOfHeader As Long
    Reserved1 As Byte
    Reserved2 As Byte
End Type
'ASF内容描述结构
Private Type ContentDescription
    TitleLength As Integer
    AuthorLength As Integer
    CopyrightLength As Integer
    DescriptionLength As Integer
    RatingLength As Integer
End Type
'ASF描述标签结构
Private Type DescriptorValue
    Type As Integer
    Length As Integer
End Type

Private Function GetASFInfo(udtInfo As MusicInfo) As Boolean
    Dim asfh As ASFHeader, bo As ObjHeader, TmpInfo As MusicInfo
    Dim fd As ContentDescription, dv As DescriptorValue, gd As GUID
    Dim a() As String, b() As Byte, Pos As Long, FreeNo As Integer, efl As Integer
    Dim s As String, i As Long, k As Integer, l As Long, j As Long
    Dim en As String, vl As String
   
    On Error GoTo fail
    FreeNo = FreeFile
    Pos = 1
    Open udtInfo.FileName For Binary As #FreeNo
    TmpInfo = udtInfo
    With TmpInfo
        Get #FreeNo, Pos, asfh
        s = GUIDToStr(asfh.HeaderInfo.ID)
        If s <> ASF_Header_Object Then GoTo fail
        Pos = Pos + Len(asfh)
        For l = 1 To asfh.NumOfHeader
            Get #FreeNo, Pos, bo
            s = GUIDToStr(bo.ID)
            Select Case s
                Case ASF_Codec_List_Object
                    Get #FreeNo, , gd
                    Get #FreeNo, , i
                    For j = 1 To i
                        Get #FreeNo, , dv
                        ReDim b(dv.Length * 2 - 1)
                        Get #FreeNo, , b
                        Get #FreeNo, , efl
                        ReDim b(efl * 2 - 1)
                        Get #FreeNo, , b
                        en = b
                        en = Trim$(Replace$(en, vbNullChar, ""))
                        If dv.Type = 2 Then
                            If InStr(1, en, ",") > 0 Then
                                a = Split(en, ",")
                                If InStr(1, a(0), "kbps", vbTextCompare) > 0 Then
                                    .Bits = Val(a(0)) & "Kbps"
                                End If
                                If InStr(1, a(1), "khz", vbTextCompare) > 0 Then
                                    .Sample = Val(a(1)) & "KHz"
                                End If
                            End If
                        ElseIf dv.Type = 1 Then '这里可以取到视频格式信息,因为自己没这个目的,就没写了
                            .MusicType = .MusicType Or mciVIDEO
                        End If
                        Get #FreeNo, , efl
                        ReDim b(efl - 1)
                        Get #FreeNo, , b
                    Next
                Case ASF_Content_Description_Object
                    Get #FreeNo, , fd
                    ReDim b(fd.TitleLength - 1)
                    Get #FreeNo, , b
                    en = b
                    en = Trim$(Replace$(en, vbNullChar, ""))
                    .Title = en
                    ReDim b(fd.AuthorLength - 1)
                    Get #FreeNo, , b
                    en = b
                    en = Trim$(Replace$(en, vbNullChar, ""))
                    .Artist = en
                    If Val(.Year) < 1900 Or Val(.Year) > 2100 Then
                        ReDim b(fd.CopyrightLength - 1)
                        Get #FreeNo, , b
                        en = b
                        en = Trim$(Replace$(en, vbNullChar, ""))
                        a = Split(en, " ")
                        For i = 0 To UBound(a)
                            If Val(a(i)) > 0 Then
                                .Year = Val(a(i))
                                Exit For
                            End If
                        Next
                    End If
                Case ASF_Extended_Content_Description_Object
                    Get #FreeNo, , k
                    For j = 1 To k
                        Get #FreeNo, , efl
                        ReDim b(efl - 1)
                        Get #FreeNo, , b
                        en = b
                        en = LCase$(Trim$(Replace$(en, vbNullChar, "")))
                        Get #FreeNo, , dv
                        Select Case dv.Type
                            Case 0, 1
                                ReDim b(dv.Length - 1)
                                Get #FreeNo, , b
                                vl = b
                                vl = Trim$(Replace$(vl, vbNullChar, ""))
                                Select Case en
                                    Case "title"
                                        .Title = vl
                                    Case "author"
                                        If .Artist = "" Then .Artist = vl
                                    Case "wm/albumartist"
                                        .Artist = vl
                                    Case "wm/writer"
                                        .Writer = vl
                                    Case "wm/composer"
                                        .Composer = vl
                                    Case "wm/albumtitle"
                                        .Album = vl
                                    Case "wm/lyrics"
                                        .Lyrics = Replace$(vl, "  ", " ")
                                    Case "wm/originalreleaseyear"
                                        If .Year = "" Then .Year = Val(vl)
                                    Case "wm/year"
                                        .Year = Val(vl)
                                End Select
                            Case 2, 3
                                ReDim b(3)
                                Get #FreeNo, , b
                            Case 4
                                ReDim b(7)
                                Get #FreeNo, , b
                            Case 5
                                ReDim b(1)
                                Get #FreeNo, , b
                        End Select
                    Next
            End Select
            Pos = Pos + bo.Size(0)
        Next
    End With
    udtInfo = TmpInfo
    GetASFInfo = True
fail:
    Close #FreeNo
End Function

Private Sub Command1_Click()
    Dim i As Long, inf As MusicInfo, s As String
    inf.FileName = Text1.Text
    If GetMusicInfo(inf) Then
        s = "文件:" & inf.FileName & vbCrLf
        s = s & "歌名:" & inf.Title & vbCrLf
        s = s & "唱片:" & inf.Album & vbCrLf
        s = s & "歌手:" & inf.Artist & vbCrLf
        s = s & "作词:" & inf.Writer & vbCrLf
        s = s & "作曲:" & inf.Composer & vbCrLf
        s = s & "年代:" & inf.Year & vbCrLf
        s = s & "采样:" & inf.Bits & vbCrLf
        s = s & "位率:" & inf.Sample & vbCrLf
        s = s & "歌词:" & inf.Lyrics
    Else
        s = "无法取音乐信息"
    End If
    MsgBox s
End Sub

这是一个与上篇相联系的代码,对于一些没定义的函数,可在前面的文章中找到
http://blog.csdn.net/homezj/archive/2005/04/15/349005.aspx

时间: 2016-02-06

无外部控件制作多媒体播放器(三)的相关文章

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

控件|媒体 利用MCI指令制作播放器,简单实用,很适合于做为自己软件的一个附带功能或背景音乐,正是基于这点需求,我准备分几个部分来写: 1.MCI指令的简单使用:2.媒体播放的进度控制与音量调节:3.音乐信息的读取,包括MP3(ID3V1 & ID3V2)与ASF(WMA & WMV)等:4.音乐列表的建立与保存(M3U格式) 本来主要是想写播放音乐的,举个播放视频的例子,没什么别的意思,只是感觉播放音乐实在是简单,没什么可写,同时也是为了说明,MCI放视频也是可以的. Private C

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

控件|媒体 音乐文件列表也是个不容忽视的问题,自己定个格式当然可以,但好在大家熟悉的M3U格式并不复杂,MediaPlayer或WinAmp都支持它,通用性也好,比起wpl要简易得多,所以我就来介绍一下M3U格式文件的制作与读写 M3U是文本文件,以#EXTM3U开头,每个音乐条目占1-2行,当存在扩展信息时,首行采用#EXTINF:开头,第二行才是文件名:当没有扩展信息时,只是简单的一行,就是文件名:文件名可包含路径,也可不包含,不包含时音乐文件应该是与M3U文件在同一目录下. 整个格式就这么

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

控件|媒体 本来想写点进度控制与音量调整的代码的,后来发现还是太简单了,就是几个MCI命令,来回搬弄,自己都没兴趣写下去.所以我想还是写些独门一点的:音乐信息的读取! 目前常见的主流音乐格式就两种,MP3与WMA,它们都有在文件中保存音乐信息的特定格式,MP3使用的当然是家喻户晓的ID3格式,分为V1与V2两个版本:WMA是MS的宠儿,它只是ASF格式的一个分支,当然遵循ASF的包装规则. 怎么获取它们包含的音乐信息呢?一般是自己读取,当然XP系统开始提供了音乐文件的详细信息资料,利用FSO可以

vc++6 0-用vc++6.0 利用windows media player控件制作播放器时

问题描述 用vc++6.0 利用windows media player控件制作播放器时 在win7 64位环境下 要对 播放器进行暂停 快进等操作时 调用 CWMPcontrols 函数时 显示 'CWMPcontrols.h': No such file or directory 头文件 也加了 cwmpcontrols.h 头文件换成小写也是不行的 也说不能打开 没有这个文件 cwmpcontrols.h 头文件是存在的在工程目录下: 解决方案 你的VC++版本太旧,没有这个头文件.建议你

vs2008-VS2008制作多媒体播放器,WindowsMediaPlayer控件按钮出错

问题描述 VS2008制作多媒体播放器,WindowsMediaPlayer控件按钮出错 播放媒体后,按停止键(WindowsMediaPlayer),再将鼠标移至菜单栏(没有点击),立刻又继续播放 以下是部分代码: BOOL CPLAYERDlg::OnInitDialog() { CDialog::OnInitDialog(); SetIcon(m_hIcon, TRUE); // Set big icon SetIcon(m_hIcon, FALSE); // Set small icon

BCB控件制作和消息处理

1 前言 作为和delphi类似的rad(rapid application development)工具,c++ builder的强大功能不仅体现在数据库开发方面,也凸现于应用程序开发上(令人称绝的是这两方面结合得非常好).仅就应用程序而言,要真正体现c++ builder的优势,开发出高质量的软件,则在拖拉拽放之外,尚需用到一些进阶技术.如消息处理.dll.ole.线程.sdk编程.c++ builder在这些方面都或多或少有独到的优势.此外,可以方便地制作自定义控件,也是c++ build

wpf日历控件制作过程分析(2) 自定义样式属性

接上篇wpf日历控件制作过程分析(1) 定义header 在header中,我们看到了定义一个自定义样式TitleStyle 1.自定义样式 看后台代码定义 Code /**//// <summary> /// The DependencyProperty for the TitleStyle property. /// Flags: none /// Default Value: null /// </summary> public static readonly Depende

C/S模式开发中如何利用WebBrowser控件制作导航窗体

原文:C/S模式开发中如何利用WebBrowser控件制作导航窗体 转自: CSDN 相信不少同学们都做过MIS系统的开发,今天这里不讨论B/S模式开发的问题.来谈谈winform开发.用过市面上常见进销存系统的同学肯定知道,在进入系统之后一般在mdi窗体中系统自动打开一个导航子窗体.将一些常见的功能以非常直观的图形展示给用户.观察市面上的此类产品,该功能基本是所有mdi窗体开发的管理系统中必备的功能窗体.下面我们就来分析一下如何在.net中实现这个功能.幸好我上次做了一个类似的系统,里面也用到

Silverlight实用窍门系列:39.Silverlight中使用Frame和Page控件制作导航【附带实例源码】

在Silverlight中有时需要进入不同的XAML页面,但是一般情况下是不能实现"前进"和"后退"的,在这里我们可以使用Frame+Page控件制作导航功能实现上一页和下一页的跳转功能. 在本文中我们制作一个实例如下:添加一个Frame控件,然后点击"加载UC"和"加载PageShow"按钮加载UC.xaml和PageShow.xaml页面.在加载后我们可以通过鼠标右键菜单中的"上一页"和"下一