【DirectX】 AudioVideoPlayback 中的事件BUG

當訪問 Video 中的 Audio 屬性時,會形成 Video 的全部事件失效。
通過反匯查看源碼,原來在訪問Audio屬性時,Audio會經過當前Video對象建立一個新實例。
而這個新實例會覆蓋掉當前的 Video 對象,所以全部以前註冊的事件都會失效。安全

解決辦法,就是利用 Audio 來進行事件註冊。
可是要注意的是,必需要訪問過一次 Audio,讓 Audio 生成實例以後,再進行動態事件的綁定!
同時,不要再使用 Video 的靜態綁定了,原先的動態綁定也不要緊,由於都會失效,因此不須要取消事件綁定了。ide

另外:記得必定要用變量來保存Audio對象,不然每次使用 Video.Audio 訪問的都是一個新建立的對象!!!spa

Dim vod As New Video("視頻路徑")
Dim ado As Audio = vod.Audio '這裏Audio會覆蓋Video的實例
ado.Volume = -10000    '靜音
' 綁定事件
AddHandler ado.Starting, AddressOf vod_Starting
AddHandler ado.Ending, AddressOf vod_Ending
' 綁定容器
vod.Owner = Panel1
vod.Owner.Width = vod.DefaultSize.Width
vod.Owner.Height = vod.DefaultSize.Height
' 開始播放
vod.Play()

 

附一個完整的安全實例:code

Dim vod As Video

Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
    Dim fp As String
    Using op As New OpenFileDialog
        If op.ShowDialog = Windows.Forms.DialogResult.Cancel Then
            Return
        End If
        fp = op.FileName
    End Using

    If vod IsNot Nothing AndAlso vod.Playing Then
        vod.Stop()
        vod.Dispose()
        vod = Nothing
    End If

    ' 嘗試第一次視頻實例化
    Try
        vod = New Video(fp)
    Catch ex As Exception
        MsgBox("視頻載入問題")
        Return
    End Try

    Dim ado As Audio = Nothing
    ' 嘗試音頻實例化
    Try
        ado = vod.Audio
        ado.Volume = -10000
        ' 嘗試將事件綁定(採用Audio)
        AddHandler ado.Starting, AddressOf vod_Starting
        AddHandler ado.Ending, AddressOf vod_Ending
    Catch ex As Exception
        'MsgBox("音頻出錯!")

        ' 音頻出錯表示視頻沒有音頻,但實例化Audio即會讓Video全部事件無效化,所以仍須要從新實例化一個新對象
        ado.Dispose()
        vod.Dispose()
        vod = New Video(fp)
        ' 嘗試將事件綁定(採用Video)
        AddHandler vod.Starting, AddressOf vod_Starting
        AddHandler vod.Ending, AddressOf vod_Ending
    End Try

    ' 其餘設置
    vod.Owner = Panel1
    vod.Owner.Width = vod.DefaultSize.Width
    vod.Owner.Height = vod.DefaultSize.Height

    ' 播放~
    vod.Play()
End Sub


Private Sub vod_Starting(ByVal sender As Object, ByVal e As System.EventArgs)
    ' 開始播放
End Sub

Private Sub vod_Ending(ByVal sender As Object, ByVal e As System.EventArgs)
    vod.CurrentPosition = 0.0 '馬上重播
    'vod.Play() '這行無所謂
End Sub
相關文章
相關標籤/搜索