Gestione del play/stop migliorata

Leonardo Robol [2009-11-01 18:09]
Gestione del play/stop migliorata
Filename
RaiTV/ChannelLoader.py
RaiTV/Interface.py
RaiTV/VideoWidget.py
raitv.py
ui/RaiTV.ui
diff --git a/RaiTV/ChannelLoader.py b/RaiTV/ChannelLoader.py
index b3fc24f..05978f2 100644
--- a/RaiTV/ChannelLoader.py
+++ b/RaiTV/ChannelLoader.py
@@ -8,10 +8,10 @@ import urllib2, re, httplib

 class ChannelList():

-    def __init__(self):
+    def __init__(self, liststore):

         ## Inizializzo un dizionario di canali
-        self.channels = {}
+        self.channels = liststore

         self.UA = 'Mozilla/5.0 (X11; U; Linux i686; it; rv:1.9.0.6) Gecko/2009011912 Firefox/3.0.11'

@@ -29,21 +29,45 @@ class ChannelList():

         for channel, url in re.findall("<videoUnit name=\"([^\"]*)\".*>.*\\n.*<url>(\S*)</url>", xmlfile):
             url = re.sub(r"&amp;", "&", url)
-            self.channels[channel] = url
+            self.channels.append( (channel,url) )


-    def getChannel(self, key):
+    def getChannel(self, channel):
         """Ottiene il vero canale da cui guardare.. :)"""

-        if not self.channels.has_key(key):
-            return None
+        ## Scorriamo la lista per trovare il canale desiderato
+        # it = self.channels.get_iter_first()

-        host = re.search(r"^.*//([^/]*)/", self.channels[key]).group(1)
-        # print " => host = %s" % host
-        path = re.search(r"%s/(.*)$" % host, self.channels[key]).group(1)
-        # print " => path = %s" % path

-        req = urllib2.Request(self.channels[key],
+
+        if it is None:
+            return None ## Qui c'è poco da fare, la lista è vuota
+
+        ## Devo trovare l'URL associato a channel
+        while it is not None:
+            chan, url = self.channels.get(it, 0)
+            if chan is channel:
+                break
+            else:
+                ## Incremento
+                it  = self.channels.iter_next(it)
+
+        return self.urlToMms(url)
+
+
+    def getChannelFromPath(self, path):
+        """Ottiene l'URL dello streaming puntato da path
+        nella liststore"""
+
+        ## Ottengo l'URL
+        it = self.channels.get_iter(path)
+        url = self.channels.get_value(it, 1)
+
+        return self.urlToMms(url)
+
+    def urlToMms(self, url):
+        """Converte un URL nello streaming MMS"""
+        req = urllib2.Request(url,
                               None,
                               {'User-Agent': self.UA})

@@ -51,6 +75,7 @@ class ChannelList():
         mms = r.read()
         mms = re.search(r"HREF=\"(\S*)\"", mms).group(1)
         return mms
+

     def getChannelList(self):
         return self.channels
diff --git a/RaiTV/Interface.py b/RaiTV/Interface.py
index c62f141..aa09db1 100644
--- a/RaiTV/Interface.py
+++ b/RaiTV/Interface.py
@@ -24,19 +24,19 @@ class UI():
         self.win = self.builder.get_object("win")
         self.listacanali = self.builder.get_object("listacanali")

+        ## La liststore dei canali
+        self.liststore = self.builder.get_object("canalistore")
+
         ## Lista dei canali (in astratto)
-        self.channellist = ChannelList()
-
+        self.channellist = ChannelList(self.liststore)
+
         ## Questo hbox è quello dove dobbiamo inserire
         ## la videowidget
         self.hbox1 = self.builder.get_object("hbox1")

         self.videowidget = VideoWidget()
         self.hbox1.pack_start(self.videowidget)
-
-        ## La liststore dei canali
-        self.liststore = self.builder.get_object("canalistore")
-
+
         ## Visualizziamo il nome del canale
         col = gtk.TreeViewColumn("Selezione canale")
         cell = gtk.CellRendererText()
@@ -53,6 +53,9 @@ class UI():
         self.builder.get_object("pause"), self.builder.get_object("record"), \
         self.builder.get_object("updatelist")

+        ## Colleghiamo il clic sulla lista con il playback del canale
+        self.listacanali.connect("row-activated", self.row_activated_callback)
+
         ## La statusbar
         self.statusbar = self.builder.get_object("statusbar")
         self.sb_info("Applicazione inizializzata")
@@ -85,18 +88,26 @@ class UI():
     def updateChannels(self):
         """Aggiorna la lista dei canali scaricandola direttamente da quella
         della rai. Si rifiuta di aggiornare se la lista ottenuta è vuota"""
+        self.sb_info("Aggiornamento canali in corso...")
         self.channellist.updateChannels()
         self.sb_info("Canali aggiornati")
         if not self.channellist == {}:
-            for channel, url in self.channellist.getChannelList().items():
-                self.liststore.append( (channel, url) )
+            ## Possiamo permetterci di perdere tutti i canali,
+            ## perché sembra che l'operazione sia andata a buon
+            ## fine
+            self.liststore = self.channellist.getChannelList()
+
+    def row_activated_callback(self, treeview, path, column):
+        ## Devo ottenere l'URL da cui prendere lo streaming
+        mmsurl = self.channellist.getChannelFromPath(path)
+        self.sb_info("Connessione a %s..." % mmsurl)
+        self.videowidget.load_video(mmsurl)
+        self.sb_info("Connessione riuscita")

     def start_video(self):
         """Avvia il video"""
         self.videowidget.registerXID()
-        self.videowidget.load_video("file:///home/leonardo/Video/The.Big.Bang.Theory.S03E02.HDTV.XviD-XII.avi")
-        # self.videowidget.load_video("mms://livestream.rai.it.edgestreams.net/reflector:64084?auth=daEcjcOancgdlaecAdqdccmdwbZbkb0aHd.-bk6_3l-b4-JlruuGt&aifp=V001")
-        # self.videowidget.load_video("mms://livestream.rai.it.edgestreams.net/reflector:64084?auth=daEcvcIa9clbgaEbjbfbFdHc_dkcCbUb7dQ-bk7abm-b4-BlvusGo&aifp=V001")
+

     def destroy(self, w):
         """Chiamata per distruggere l'interfaccia"""
diff --git a/RaiTV/VideoWidget.py b/RaiTV/VideoWidget.py
index 2322166..1bfe557 100644
--- a/RaiTV/VideoWidget.py
+++ b/RaiTV/VideoWidget.py
@@ -4,7 +4,7 @@
 # Implementazione del Widget per gestire il video
 #

-import pygtk, gtk, gst
+import pygtk, gtk, gst, cairo

 class VideoWidget(gtk.DrawingArea):

@@ -25,13 +25,49 @@ class VideoWidget(gtk.DrawingArea):
         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)

-    def do_expose_event(self, event):
-        if self.imagesink:
-            self.imagesink.expose()
-            return False
-        else:
-            return True
+        self.playing = False
+
+
+    def colorize(self, widget, event):
+        """Quando la finestra viene creata la coloriamo di
+        nero. Poi sarà tutto lavoro per gstreamer"""
+
+        ## Ci permettiamo di disegnare sopra il filmato
+        ## se e solo se non c'è un filmato che sta andando! :)
+
+        if not self.playing:
+            cr = self.window.cairo_create()
+            ## Non facciamo lavoro extra e coloriamo solo ciò
+            ## che è stato scoperto
+            cr.rectangle(event.area.x, event.area.y,
+                         event.area.width, event.area.height)
+
+            cr.clip()
+
+            width, height = self.window.get_size()
+
+            cr.set_source_rgb(0,0,0)
+            cr.rectangle(0,0,width,height)
+            cr.fill()
+
+            cr.set_source_rgb(0.5,0,0)
+            st = "RaiTV :)"
+            cr.set_font_size(height/20)
+            cr.select_font_face("Comic Sans MS")
+            xbearing , ybearing, twidth, theight, xadvance, yadvance = cr.text_extents(st)
+
+            cr.move_to(width/2 - twidth/2, 1.6*height/3 - theight/5)
+            cr.show_text(st)
+
+            cr.set_line_width(3)
+            cr.move_to(width/2 - twidth/2 - 5 , 1.6* height/3)
+            cr.rel_line_to(twidth + 10,0)
+            cr.stroke()
+
+

     def set_sink(self, sink):
         assert self.window.xid
@@ -40,17 +76,20 @@ class VideoWidget(gtk.DrawingArea):

     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()

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

     def stop(self):
+        self.playing = False
         self.player.set_state(gst.STATE_NULL)

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

     def on_sync_message(self, bus, message):
@@ -68,27 +107,4 @@ class VideoWidget(gtk.DrawingArea):
             print err, debug

     def reset(self):
-        drawable = self.window
-        width, height = drawable.get_size()
-        print width, height
-        # Creo il graphic context, sperando che si
-        # aggiorni.
-        gc = gtk.gdk.GC(drawable,
-                        gtk.gdk.Color(2,15,70),
-                        gtk.gdk.Color(0,67,0)
-                        )
-
-        drawable.draw_rectangle(gc,
-                                True,
-                                5,
-                                5,
-                                width,
-                                height)
-
-        ## Qua dovremmo far vedere che la finestra
-        ## diventa nera e invece non lo fa
-        self.realize()
-
-    def registerXID(self):
-        self.XID = self.window.xid
-
+        pass
diff --git a/raitv.py b/raitv.py
old mode 100644
new mode 100755
index 296070f..6e4cb7d
--- a/raitv.py
+++ b/raitv.py
@@ -1,4 +1,4 @@
-#
+#!/usr/bin/env python
 # -*- coding: utf-8 -*-
 #
 #
@@ -9,7 +9,6 @@ from RaiTV import VideoWidget, Interface
 ui = Interface.UI()

 ui.show_all()
-ui.start_video()

 gtk.main()

diff --git a/ui/RaiTV.ui b/ui/RaiTV.ui
index 2b3c7f5..f0481bd 100644
--- a/ui/RaiTV.ui
+++ b/ui/RaiTV.ui
@@ -11,6 +11,7 @@
     </columns>
   </object>
   <object class="GtkWindow" id="win">
+    <property name="title" translatable="yes">RaiTV prerelease</property>
     <child>
       <object class="GtkVBox" id="vbox1">
         <property name="visible">True</property>
ViewGit