Imports System.Threading Imports System.Windows.Threading Public Class AsxController ' ' Open Source Code by Julien Bouquillon from revolunet ' -> julien@bouquillon.com ' ' This class simulate an ASX playlist over a MediaElement ' It allows more control and prevent failures ' Correct some MediaElement/ASX native bugs ' ' example use : ' ' Public MyAsxController As AsxController ' MyAsxController = New AsxController(player) ' MyAsxController.LoadAsx("/path/to/playlist.asx") ' MyAsxController.StartPlay() ' Private player As MediaElement Private asx As New XmlDataProvider Private asx_uri As String = "" Private playlist_index As Integer = 0 Private playlist_count As Integer = 0 Private tmr_end_playlistitem As DispatcherTimer = New DispatcherTimer() Private tmr_buffering As DispatcherTimer = New DispatcherTimer() ' buffer timeout if errors in streams for example Public buffering_timeout As TimeSpan = TimeSpan.FromSeconds(5) Public Sub New(ByVal playerref) Me.player = playerref AddHandler Me.player.MediaFailed, AddressOf Me.MediaFailed AddHandler Me.player.MediaEnded, AddressOf Me.MediaEnded AddHandler Me.player.MediaOpened, AddressOf Me.MediaOpened AddHandler Me.player.BufferingStarted, AddressOf Me.BufferingStarted AddHandler Me.player.BufferingEnded, AddressOf Me.BufferingEnded AddHandler tmr_end_playlistitem.Tick, AddressOf tmr_end_playlistitem_ended AddHandler tmr_buffering.Tick, AddressOf tmr_buffering_ended tmr_buffering.Interval = buffering_timeout asx.IsAsynchronous = False asx.Source = Nothing End Sub Public Sub LoadAsx(ByVal asxuri As String) tmr_end_playlistitem.Stop() tmr_buffering.Stop() player.Stop() player.Close() Me.asx_uri = asxuri If System.IO.File.Exists(asx_uri) Then asx.Source = New Uri(asx_uri) asx.Refresh() If Not asx.Document.DocumentElement Is Nothing Then Dim items As Xml.XmlNodeList = asx.Document.DocumentElement.SelectNodes("*/ENTRY/REF") playlist_index = 0 playlist_count = items.Count End If End If End Sub Private Function secondsFromTime(ByVal inTime As String) ' this translate ASX duration format in seconds ' dont care about Fractions If inTime.IndexOf(".") > -1 Then inTime = inTime.Substring(0, inTime.IndexOf(".")) End If Dim arrTime As Array = inTime.Split(":") Dim seconds As Integer = 0 If arrTime.Length = 3 Then seconds += CInt(arrTime(0)) * 3600 seconds += CInt(arrTime(1)) * 60 seconds += CInt(arrTime(2)) End If Return seconds End Function Private Sub NextItem() If playlist_count = 0 Then Exit Sub If playlist_index >= playlist_count Then playlist_index = 0 Dim item As Xml.XmlNode = asx.Document.DocumentElement.SelectNodes("*/ENTRY").Item(playlist_index) Dim uri As String = item.SelectSingleNode("REF").Attributes.ItemOf("href").Value player.Close() player.Source = New Uri(uri) player.Play() ' gestion duration If Not item.SelectSingleNode("DURATION") Is Nothing Then If Not item.SelectSingleNode("DURATION").Attributes("value") Is Nothing Then ' +1s hack for display delay Dim seconds As Integer = secondsFromTime(item.SelectSingleNode("DURATION").Attributes("value").Value) + 1 tmr_end_playlistitem.Interval = TimeSpan.FromSeconds(seconds) tmr_end_playlistitem.Start() End If End If playlist_index += 1 End Sub Private Sub tmr_buffering_ended(ByVal sender As Object, ByVal e As EventArgs) tmr_end_playlistitem.Stop() NextItem() End Sub Private Sub tmr_end_playlistitem_ended(ByVal sender As Object, ByVal e As EventArgs) tmr_end_playlistitem.Stop() NextItem() End Sub Public Sub ReloadAsx() Me.LoadAsx(asx_uri) End Sub Private Sub MediaEnded() tmr_buffering.Stop() ' wait for MediaEndedTimeout from ASX DURATION but not for videos (auto end) If player.NaturalDuration.HasTimeSpan() Then 'video MediaEnded NextItem() End If End Sub Private Sub MediaFailed() tmr_buffering.Stop() NextItem() End Sub Private Sub MediaOpened() tmr_buffering.Stop() End Sub Private Sub BufferingStarted() tmr_buffering.Start() End Sub Private Sub BufferingEnded() tmr_buffering.Stop() End Sub Public Sub StopPlay() tmr_buffering.Stop() tmr_end_playlistitem.Stop() player.Stop() End Sub Public Sub StartPlay() playlist_index = 0 NextItem() End Sub End Class