【DirectX】AudioVideoPlayback 中的事件BUG
当访问 Video 中的 Audio 属性时,会造成 Video 的所有事件失效。
经过反汇查看源码,原来在访问Audio属性时,Audio会通过当前Video对象创建一个新实例。
而这个新实例会覆盖掉当前的 Video 对象,因此所有之前注册的事件都会失效。
解决办法,就是利用 Audio 来进行事件注册。
但是要注意的是,必须要访问过一次 Audio,让 Audio 生成实例之后,再进行动态事件的绑定!
同时,不要再使用 Video 的静态绑定了,原先的动态绑定也没关系,因为都会失效,所以不需要取消事件绑定了。
另外:记得一定要用变量来保存Audio对象,否则每次使用 Video.Audio 访问的都是一个新创建的对象!!!
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()
附一个完整的安全实例: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
本作品采用 知识共享署名-相同方式共享 4.0 国际许可协议 进行许可。