ein verregneter Sonntag Morgen ist die beste Gelegenheit, sich mit einem nervigen wx.MediaCtrl-Problem rumzuschlagen

Streamt man mit LoadURI() MP3s über HTTP, hängt sich MediaCtrl bei korrupten Files gnadenlos auf und legt die gesamte Applikation lahm.
Da ein try-except Konstrukt nicht greifen würde und MediaCtrl auch keine Fehlermeldungen an seine Aussenwelt absondert, muss man den haengenden Prozess gewaltsam beenden und MediaCtrl neu starten.
Wichtig ist dabei, dass man auch die Childprozesse killt, da sonst im Hintergrund MediaCtrl.Play() weiterhin versuchen würde, das korrupte File abzuspielen. Kann man selbst überprüfen, indem man die Zeilen
Code: Alles auswählen
wx.CallAfter(self.mp.DestroyChildren)
Gruss, Seven
Code: Alles auswählen
# Demonstartion eines haengenden Play-Aufrufes mit wx.MediaCtrl
# Das erste mit LoadURI() gesladene Mp3 ist korrupt und kann nicht abgespielt werden
# Normalerweise haengt sich wx.MediaCtrl bei soetwas auf.
# Durch Killen des Childprozesses Play() und anschliessendem Killen der wx.MediaCtrl-Instanz mp
# kann das verhindert werden.
# Anschliessend wird eine neue Instanz von wx.MediaCtrl erzeugt und es kann wieder
# abgespielt werden
import wx
import wx.media
class MediaControl(wx.Frame):
def __init__(self,parent,id):
wx.Frame.__init__(self,parent,id)
self.Bind(wx.EVT_CLOSE, self.cancel)
self.initmediacontrol()
# Laden eines korrupten MP3-Streams
self.loadmedia("http://www.sonidorock.org/lala/01.Secret%20Valentine.mp3")
def initmediacontrol(self):
self.mp = wx.media.MediaCtrl(self, size=wx.Size(512,384))
self.mp.Bind(wx.media.EVT_MEDIA_LOADED,self.OnPlay)
def loadmedia(self, med):
self.isplaying = False
self.mp.LoadURI(med)
while not self.isplaying:
wx.YieldIfNeeded()
dp = self.mp.GetDownloadProgress()
print dp
if dp > 0:
# nach 10Sekunden checken, ob abgespielt wird
wx.FutureCall(10000,self.checkifplaying)
break
def OnPlay(self,event):
self.isplaying = True
self.mp.Play()
print "playing"
def checkifplaying(self):
if not self.isplaying:
# Killen der Childprozesse von mp (z.B. Play())
wx.CallAfter(self.mp.DestroyChildren)
# Killen der Instanz mp
wx.CallAfter(self.mp.Destroy)
print "mp.destroyed"
self.initmediacontrol()
# Laden eines intakten MP3-Streams
self.loadmedia("http://www.fileden.com/files/2008/11/29/2205665/fall_out_boy-americas_suitehearts.mp3")
def cancel(self, event=None):
wx.CallAfter(self.mp.DestroyChildren)
wx.CallAfter(self.mp.Destroy)
self.Destroy()
app = wx.PySimpleApp()
frame=MediaControl(parent=None,id=-1)
frame.Show()
app.MainLoop()
Leider ist es doch nicht ganz so einfach, schade, schade. Mit Childdren sind in der Doku wohl offensichhtlich Objekte vom Typ wx.Windows gemeint und keine Kindprozesse von wx.MediaCtrl. Warum diese Methode trotzdem in den meisten von mir getesteten Fällen den hängenden Mediastream beenden konnte, verstehe ich nun doch nicht mehr. Werde wohl noch weiter forschen müssen. Schade, dass wx.MediaCtrl so eine undurchsichtige Blackbox ist, die sich noch nicht einmal mit "try - except" bändigen lässt.