0

私は VB.net VS2012 を使用していますが、オーディオ ファイルの再生についてサポートが必要です。

これが私のコードです:

''' <summary>
''' This class is a wrapper for the Windows API calls to play wave, midi or mp3 files.
''' </summary>
''' <remarks>
''' </remarks>
Public Class AudioFile
'***********************************************************************************************************
'        Class:  PlayFile
'   Written By:  Blake Pell (bpell@indiana.edu)
' Initial Date:  03/31/2007
' Last Updated:  02/04/2009
'***********************************************************************************************************

' Windows API Declarations
Private Declare Function mciSendString Lib "winmm.dll" Alias "mciSendStringA" (ByVal lpstrCommand As String, ByVal lpstrReturnString As String, ByVal uReturnLength As Int32, ByVal hwndCallback As Int32) As Int32

''' <summary>
''' Constructor:  Location is the filename of the media to play.  Wave files and Mp3 files are the supported formats.
''' </summary>
''' <param name="Location"></param>
''' <remarks></remarks>
Public Sub New(ByVal location As String)
    Me.Filename = location
End Sub

''' <summary>
''' Plays the file that is specified as the filename.
''' </summary>
''' <remarks></remarks>
Public Sub Play()

    If _filename = "" Or Filename.Length <= 4 Then Exit Sub

    Select Case Right(Filename, 3).ToLower
        Case "mp3"
            mciSendString("open """ & _filename & """ type mpegvideo alias audiofile", Nothing, 0, IntPtr.Zero)

            Dim playCommand As String = "play audiofile from 0"

            If _wait = True Then playCommand += " wait"

            mciSendString(playCommand, Nothing, 0, IntPtr.Zero)
        Case "wav"
            mciSendString("open """ & _filename & """ type waveaudio alias audiofile", Nothing, 0, IntPtr.Zero)
            mciSendString("play audiofile from 0", Nothing, 0, IntPtr.Zero)
        Case "mid", "idi"
            mciSendString("stop midi", "", 0, 0)
            mciSendString("close midi", "", 0, 0)
            mciSendString("open sequencer!" & _filename & " alias midi", "", 0, 0)
            mciSendString("play midi", "", 0, 0)
        Case Else
            Throw New Exception("File type not supported.")
            Call Close()
    End Select

    IsPaused = False

End Sub

''' <summary>
''' Pause the current play back.
''' </summary>
''' <remarks></remarks>
Public Sub Pause()
    mciSendString("pause audiofile", Nothing, 0, IntPtr.Zero)
    IsPaused = True
End Sub

''' <summary>
''' Resume the current play back if it is currently paused.
''' </summary>
''' <remarks></remarks>
Public Sub [Resume]()
    mciSendString("resume audiofile", Nothing, 0, IntPtr.Zero)
    IsPaused = False
End Sub

''' <summary>
''' Stop the current file if it's playing.
''' </summary>
''' <remarks></remarks>
Public Sub [Stop]()
    mciSendString("stop audiofile", Nothing, 0, IntPtr.Zero)
End Sub

''' <summary>
''' Close the file.
''' </summary>
''' <remarks></remarks>
Public Sub Close()
    mciSendString("close audiofile", Nothing, 0, IntPtr.Zero)
End Sub

Private _wait As Boolean = False
''' <summary>
''' Halt the program until the .wav file is done playing.  Be careful, this will lock the entire program up until the
''' file is done playing.  It behaves as if the Windows Sleep API is called while the file is playing (and maybe it is, I don't
''' actually know, I'm just theorizing).  :P
''' </summary>
''' <value></value>
''' <returns></returns>
''' <remarks></remarks>
Public Property Wait() As Boolean
    Get
        Return _wait
    End Get
    Set(ByVal value As Boolean)
        _wait = value
    End Set
End Property

''' <summary>
''' Sets the audio file's time format via the mciSendString API.
''' </summary>
''' <value></value>
''' <returns></returns>
''' <remarks></remarks>
ReadOnly Property Milleseconds() As Integer
    Get
        Dim buf As String = Space(255)
        mciSendString("set audiofile time format milliseconds", Nothing, 0, IntPtr.Zero)
        mciSendString("status audiofile length", buf, 255, IntPtr.Zero)

        buf = Replace(buf, Chr(0), "") ' Get rid of the nulls, they muck things up

        If buf = "" Then
            Return 0
        Else
            Return CInt(buf)
        End If
    End Get
End Property

''' <summary>
''' Gets the status of the current playback file via the mciSendString API.
''' </summary>
''' <value></value>
''' <returns></returns>
''' <remarks></remarks>
ReadOnly Property Status() As String
    Get
        Dim buf As String = Space(255)
        mciSendString("status audiofile mode", buf, 255, IntPtr.Zero)
        buf = Replace(buf, Chr(0), "")  ' Get rid of the nulls, they muck things up
        Return buf
    End Get
End Property

''' <summary>
''' Gets the file size of the current audio file.
''' </summary>
''' <value></value>
''' <returns></returns>
''' <remarks></remarks>
ReadOnly Property FileSize() As Integer
    Get
        Try
            Return My.Computer.FileSystem.GetFileInfo(_filename).Length
        Catch ex As Exception
            Return 0
        End Try
    End Get
End Property

''' <summary>
''' Gets the channels of the file via the mciSendString API.
''' </summary>
''' <value></value>
''' <returns></returns>
''' <remarks></remarks>
ReadOnly Property Channels() As Integer
    Get
        Dim buf As String = Space(255)
        mciSendString("status audiofile channels", buf, 255, IntPtr.Zero)

        If IsNumeric(buf) = True Then
            Return CInt(buf)
        Else
            Return -1
        End If
    End Get
End Property

''' <summary>
''' Used for debugging purposes.
''' </summary>
''' <value></value>
''' <returns></returns>
''' <remarks></remarks>
ReadOnly Property Debug() As String
    Get
        Dim buf As String = Space(255)
        mciSendString("status audiofile channels", buf, 255, IntPtr.Zero)

        Return Str(buf)
    End Get
End Property

Private _isPaused As Boolean = False
''' <summary>
''' Whether or not the current playback is paused.
''' </summary>
''' <value></value>
''' <returns></returns>
''' <remarks></remarks>
Public Property IsPaused() As Boolean
    Get
        Return _isPaused
    End Get
    Set(ByVal value As Boolean)
        _isPaused = value
    End Set
End Property

Private _filename As String
''' <summary>
''' The current filename of the file that is to be played back.
''' </summary>
''' <value></value>
''' <returns></returns>
''' <remarks></remarks>
Public Property Filename() As String
    Get
        Return _filename
    End Get
    Set(ByVal value As String)

        If My.Computer.FileSystem.FileExists(value) = False Then
            Throw New System.IO.FileNotFoundException
            Exit Property
        End If

        _filename = value
    End Set
End Property
End Class

このコードはうまく機能します。オーディオ ファイルの再生が終了したときに呼び出されるイベントを作成する方法を教えてください。オーディオ ファイルが終了すると、「ステータス」は「停止」になります。これがいつ発生するかを確認し、イベントを作成するにはどうすればよいですか?

4

2 に答える 2

0

再生ステータスが変更されたときのコールバックを登録する方法がないように思われるため、オブザーバー(つまりタイマー)を使用する必要があります。

Private WithEvents StatusMonitor As New Timers.Timer(100)
Private Property LastStatus As String

Private Sub StatusMonitor_Elapsed(sender As Object, e As Timers.ElapsedEventArgs) Handles StatusMonitor.Elapsed
    If Not String.Equals(Me.Status, Me.LastStatus) Then
        Me.LastStatus = Me.Status
        RaiseEvent PlaybackStatusChanged(Me, New PlaybackStatusChangedEventArgs(Me.Status))
    End If
End Sub

Public Event PlaybackStatusChanged(sender As Object, e As PlaybackStatusChangedEventArgs)

Public Class PlaybackStatusChangedEventArgs
    Inherits EventArgs

    Private _status As String

    Public Sub New(status As String)
        _status = status
    End Sub

    Public ReadOnly Property Status As String
        Get
            Return _status
        End Get
    End Property
End Class

これは、ステータスをプライベートプロパティに保存し、100ミリ秒ごとに現在のステータスと比較します。ステータスが変更された場合はPlaybackStatusChanged、新しいステータスを含む引数とともにイベントが発生します。次に、このイベントをリッスンし、e.Statusから直接取得しているかのようにイベントコールバックをチェックインできますAudioFile.Status

編集

いくつかのテストを実行した後、statusプロパティの動作に一貫性がないことがわかりました。私には理解できない理由で、それは多くの空白も返すようです。とにかく、結果として、ステータスイベントに渡されるステータスは間違っています。

于 2013-02-16T22:31:03.637 に答える
0

どうすればいいのかわかりません。しかし、あなたができることはこれです。メイン フォームで、lol のような文字列を文字列として Dim します

ボタンの場合は、次のコードを設定します。

lol = "Audio file path goes here :3"
    Dim audio As New AudioFile(lol)
    Timer1.Start()
    audio.Play()

タイマーを追加し、その間隔を 10 に設定します。

タイマー コードの場合、これを追加します。

 Dim audio As New AudioFile(lol)
    If audio.Status.Contains("stopped") Then
        audio.Play()
    End If

そうすれば、曲の再生が終了すると、タイマーが自動的に再生を再開します。そして、その変数にある音声ファイル用に設定されているので、その変数とブームにパスを設定するボタンを持っているだけです。あなたのセット。

それが役に立ったことを願っています...

于 2013-02-22T02:20:05.217 に答える