Aggiunto supporto al threading, l'interfaccia non freeza se

Leonardo Robol [2009-11-01 19:15]
Aggiunto supporto al threading, l'interfaccia non freeza se
si sta caricando un canale
Filename
RaiTV/VideoWidget.py
diff --git a/RaiTV/VideoWidget.py b/RaiTV/VideoWidget.py
index 1bfe557..1dd90a4 100644
--- a/RaiTV/VideoWidget.py
+++ b/RaiTV/VideoWidget.py
@@ -4,7 +4,64 @@
 # Implementazione del Widget per gestire il video
 #

-import pygtk, gtk, gst, cairo
+import pygtk, gtk, gst, cairo, threading
+
+class GstPlayer(threading.Thread):
+
+    def __init__(self, xid, video):
+        threading.Thread.__init__(self)
+        self.xid = xid
+        self.video = video
+
+        self.exit_required = False
+
+    def set_sink(self, sink):
+        assert self.xid
+        self.imagesink = sink
+        self.imagesink.set_xwindow_id(self.xid)
+
+    def on_sync_message(self, bus, message):
+
+        if message.structure is None:
+            return
+        if message.structure.get_name() == 'prepare-xwindow-id':
+            gtk.gdk.threads_enter()
+
+            self.set_sink(message.src)
+            message.src.set_property("force-aspect-ratio", True)
+            gtk.gdk.threads_leave()
+
+    def on_message(self, bus, message):
+        if message.type == gst.MESSAGE_ERROR:
+            err, debug = message.parse_error()
+            print err, debug
+
+    def run(self):
+        self.player = gst.element_factory_make("playbin", "player")
+
+        self.player.set_property
+        bus = self.player.get_bus()
+        bus.enable_sync_message_emission()
+        bus.add_signal_watch()
+        bus.connect("sync-message::element", self.on_sync_message)
+        bus.connect("message", self.on_message)
+
+        self.player.set_property("uri", self.video)
+
+        self.player.set_state(gst.STATE_PLAYING)
+
+        while not self.exit_required:
+            pass
+
+        self.player.set_state(gst.STATE_NULL)
+
+    def exit(self):
+        self.exit_required = True
+
+    def pause(self):
+        self.player.set_state(gst.STATE_PAUSE)
+
+

 class VideoWidget(gtk.DrawingArea):

@@ -17,18 +74,11 @@ class VideoWidget(gtk.DrawingArea):
         self.set_size_request(320,320)
         self.unset_flags(gtk.DOUBLE_BUFFERED)

-        ## Configurazione del player gstreamer
-        self.player = gst.element_factory_make("playbin", "player")
-        bus = self.player.get_bus()
-        bus.enable_sync_message_emission()
-        bus.add_signal_watch()
-        bus.connect("sync-message::element", self.on_sync_message)
-        bus.connect("message", self.on_message)
-
         ## Connetto l'expose-event
         self.connect("expose-event", self.colorize)

         self.playing = False
+        self.player = None


     def colorize(self, widget, event):
@@ -67,44 +117,31 @@ class VideoWidget(gtk.DrawingArea):
             cr.rel_line_to(twidth + 10,0)
             cr.stroke()

-
-
-    def set_sink(self, sink):
-        assert self.window.xid
-        self.imagesink = sink
-        self.imagesink.set_xwindow_id(self.window.xid)
-
+
     def load_video(self, uri):
         """Start video playing with the specified URI"""
         ## Stoppiamo ogni video
-        self.stop()
-        self.player.set_property("uri", uri)
-        self.play()
+        if self.playing:
+            self.stop()
+            self.player.join()
+        self.player = GstPlayer(self.window.xid, uri)
+        self.player.start()
+        self.playing = True

     def pause(self):
-        self.player.set_state(gst.STATE_PAUSED)
+        self.player.pause()

     def stop(self):
         self.playing = False
-        self.player.set_state(gst.STATE_NULL)
+        if self.player is not None:
+            self.player.exit()
+            self.player.join()
+

     def play(self):
         self.playing = True
         self.player.set_state(gst.STATE_PLAYING)

-    def on_sync_message(self, bus, message):
-        if message.structure is None:
-            return
-        if message.structure.get_name() == 'prepare-xwindow-id':
-            gtk.gdk.threads_enter()
-            self.set_sink(message.src)
-            message.src.set_property("force-aspect-ratio", True)
-            gtk.gdk.threads_leave()
-
-    def on_message(self, bus, message):
-        if message.type == gst.MESSAGE_ERROR:
-            err, debug = message.parse_error()
-            print err, debug
-
+
     def reset(self):
         pass
ViewGit