Die Community zu .NET und Classic VB.
Menü

VB.NET-Tipp 0070: Spieldauer einer Wave-Datei ermitteln

 von 

Beschreibung

Dieser Tipp zeigt, wie mit Hilfe des Media Control Interface (MCI) von Windows die Spieldauer einer Wave-Datei ermittelt werden kann. Die nötigen API-Aufrufe sind in einer Klasse gekapselt.

Schwierigkeitsgrad:

Schwierigkeitsgrad 1

Framework-Version(en):

.NET Framework 1.0, .NET Framework 1.1, .NET Framework 2.0, .NET Framework 3.0, .NET Framework 3.5

.NET-Version(en):

Visual Basic 2002, Visual Basic 2003, Visual Basic 2005, Visual Basic 2008

Download:

Download des Beispielprojektes [12,33 KB]

' Dieser Quellcode stammt von http://www.activevb.de
' und kann frei verwendet werden. Für eventuelle Schäden
' wird nicht gehaftet.

' Um Fehler oder Fragen zu klären, nutzen Sie bitte unser Forum.
' Ansonsten viel Spaß und Erfolg mit diesem Source!

' Projektversion:   Visual Studio 2008
' Option Strict:    An
' Option Explicit:  An
' Option Infer:     Aus
'
' Referenzen: 
'  - System
'  - System.Drawing
'  - System.Windows.Forms
'

' ##############################################################################
' ################################ MainForm.vb #################################
' ##############################################################################
Public Class MainForm
    Private Sub OpenFile(ByVal sender As Object, _
        ByVal e As System.EventArgs) Handles OpenFileButton.Click

        If OpenFileDialog.ShowDialog(Me) = _
            System.Windows.Forms.DialogResult.OK Then

            LengthLabel.Text = "Länge: " & _
                GetWaveLength(OpenFileDialog.FileName).ToString()
        End If
    End Sub

    Private Function GetWaveLength(ByVal path As String) As System.TimeSpan
        Using device As New MediaDevice(path)
            Return device.Length
        End Using
    End Function
End Class

' ##############################################################################
' ############################## MediaDevice.vb ################################
' ##############################################################################
Imports System
Imports System.Runtime.InteropServices
Imports System.Text

Public Class MediaDevice

    Implements IDisposable

    Private Const mObjectName As String = "MediaDevice"

    Private Declare Auto Function mciGetErrorString Lib "winmm.dll" ( _
        ByVal fdwError As UInteger, _
        ByVal lpszErrorText As StringBuilder, _
        ByVal cchErrorText As Integer) As Boolean
    Private Declare Auto Function mciSendCommand Lib "winmm.dll" ( _
        ByVal wDeviceID As UInteger, _
        ByVal uMsg As UInteger, _
        ByVal dwFlags As UInteger, _
        ByRef lpOpen As MCI_WAVE_OPEN_PARMS) As UInteger
    Private Declare Auto Function mciSendCommand Lib "winmm.dll" ( _
        ByVal wDeviceID As UInteger, _
        ByVal uMsg As UInteger, _
        ByVal dwFlags As UInteger, _
        ByRef lpClose As MCI_CLOSE_PARMS) As UInteger
    Private Declare Auto Function mciSendCommand Lib "winmm.dll" ( _
        ByVal wDeviceID As UInteger, _
        ByVal uMsg As UInteger, _
        ByVal dwFlags As UInteger, _
        ByRef lpStatus As MCI_STATUS_PARMS) As UInteger

    <StructLayout(LayoutKind.Sequential, CharSet:=CharSet.Auto)> _
    Private Structure MCI_WAVE_OPEN_PARMS
        Public dwCallback As UIntPtr
        Public wDeviceID As UInteger
        Public lpstrDeviceType As UIntPtr
        Public lpstrElementName As String
        Public lpstrAlias As UIntPtr
        Public dwBufferSeconds As UInteger
    End Structure

    <StructLayout(LayoutKind.Sequential, CharSet:=CharSet.Unicode)> _
    Private Structure MCI_CLOSE_PARMS
        Public dwCallback As UIntPtr
    End Structure

    <StructLayout(LayoutKind.Sequential, CharSet:=CharSet.Unicode)> _
    Private Structure MCI_STATUS_PARMS
        Public dwCallback As UIntPtr
        Public dwReturn As UInteger
        Public dwItem As UInteger
        Public dwTrack As UInteger
    End Structure

    Private Const mErrorTextLength As Integer = 128

    Private Const MCI_OPEN As UInteger = &H803UI
    Private Const MCI_CLOSE As UInteger = &H804UI
    Private Const MCI_STATUS As UInteger = &H814UI

    Private Const MCI_WAIT As UInteger = &H2UI
    Private Const MCI_TRACK As UInteger = &H10UI
    Private Const MCI_STATUS_ITEM As UInteger = &H100UI
    Private Const MCI_OPEN_ELEMENT As UInteger = &H200UI
    Private Const MCI_OPEN_TYPE_ID As UInteger = &H1000UI
    Private Const MCI_OPEN_TYPE As UInteger = &H2000UI

    Private Const MCI_DEVTYPE_WAVEFORM_AUDIO As UInteger = 522UI
    Private Const MCI_STATUS_LENGTH As UInteger = &H1UI

    Private mDisposed As Boolean
    Private mOpen As Boolean
    Private mDevice As UInteger

    Public Sub New(ByVal path As String)
        Open(path)
    End Sub

    Public Sub Open(ByVal path As String)
        If mDisposed Then Throw New ObjectDisposedException(mObjectName)
        If mOpen Then Close()
        Dim Params As MCI_WAVE_OPEN_PARMS
        Params.lpstrDeviceType = New UIntPtr(MCI_DEVTYPE_WAVEFORM_AUDIO)
        Params.lpstrElementName = path
        If CheckResult(mciSendCommand(0, MCI_OPEN, MCI_WAIT Or _
            MCI_OPEN_ELEMENT Or MCI_OPEN_TYPE Or MCI_OPEN_TYPE_ID, Params)) Then

            mOpen = True
            mDevice = Params.wDeviceID
        End If
    End Sub

    Public Sub Close()
        If mOpen Then
            Dim Params As MCI_CLOSE_PARMS
            If CheckResult(mciSendCommand(mDevice, MCI_CLOSE, _
                MCI_WAIT, Params)) Then

                mOpen = False
                mDevice = 0
            End If
        End If
    End Sub

    Public ReadOnly Property Length() As TimeSpan
        Get
            If mDisposed Then Throw New ObjectDisposedException(mObjectName)
            Dim Params As MCI_STATUS_PARMS
            Params.dwItem = MCI_STATUS_LENGTH
            Params.dwTrack = 1
            If CheckResult(mciSendCommand(mDevice, MCI_STATUS, _
                MCI_WAIT Or MCI_TRACK Or MCI_STATUS_ITEM, Params)) Then

                Return TimeSpan.FromMilliseconds(Params.dwReturn)
            End If
        End Get
    End Property

    Private Function CheckResult(ByVal result As UInteger) As Boolean
        If result = 0 Then
            Return True
        Else
            Dim builder As New StringBuilder(mErrorTextLength)
            If mciGetErrorString(result, builder, mErrorTextLength) Then
                Throw New MediaException(builder.ToString())
            Else
                Throw New MediaException()
            End If
        End If
    End Function

    Protected Overridable Sub Dispose(ByVal disposing As Boolean)
        If Not mDisposed Then
            Close()
            mDisposed = True
        End If
    End Sub

    ' This code added by Visual Basic to correctly implement the 
    '  disposable pattern.
    Public Sub Dispose() Implements IDisposable.Dispose
        ' Do not change this code.  Put cleanup code in 
        ' Dispose(ByVal disposing As Boolean) above.
        Dispose(True)
        GC.SuppressFinalize(Me)
    End Sub
End Class

' ##############################################################################
' ############################# MediaException.vb ##############################
' ##############################################################################
Imports System
Imports System.Text

Public Class MediaException
    Inherits Exception

    Public Sub New()
        MyBase.New()
    End Sub

    Public Sub New(ByVal message As String)
        MyBase.New(message)
    End Sub
End Class

Ihre Meinung  

Falls Sie Fragen zu diesem Artikel haben oder Ihre Erfahrung mit anderen Nutzern austauschen möchten, dann teilen Sie uns diese bitte in einem der unten vorhandenen Themen oder über einen neuen Beitrag mit. Hierzu können sie einfach einen Beitrag in einem zum Thema passenden Forum anlegen, welcher automatisch mit dieser Seite verknüpft wird.

Wo kommt der Befehl, - Basis 2 24.06.13 09:29 12 Antworten

Archivierte Nutzerkommentare 

Klicken Sie diesen Text an, wenn Sie die 1 archivierten Kommentare ansehen möchten.
Diese stammen noch von der Zeit, als es noch keine direkte Forenunterstützung für Fragen und Kommentare zu einzelnen Artikeln gab.
Aus Gründen der Vollständigkeit können Sie sich die ausgeblendeten Kommentare zu diesem Artikel aber gerne weiterhin ansehen.

Kommentar von Jogi am 06.02.2011 um 13:07

Habe diese Version unter RC 7, 64 Bit ausprobiert. Leider funktioniert das nur 32 Bit, aber nicht unter 64 Bit.
Ich suche immer noch an einer Lösung, die Länge einer Wav Datei auszulesen.