Vu-meter added (based on a vertical ProgressBar)
authorDavid Testé <soonum@gnu.org>
Fri, 4 Mar 2016 22:36:13 +0000 (23:36 +0100)
committerDavid Testé <soonum@gnu.org>
Fri, 4 Mar 2016 22:36:13 +0000 (23:36 +0100)
stream_2016/libre-streamer.py

index dce3bed283a8aa6884deb3da9c10edc84c6fd387..027ea54da65672ab873f28812e26a48420a803f4 100755 (executable)
@@ -20,7 +20,8 @@
 # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 # TODO list:
 # ----------
-#    - Display the Gst element 'videotestsrc', in case of failure of the pipeline
+#    - Implement a method to switch to webcam feed if Elphel cam feed is lost
+#    - Display the Gst element 'videotestsrc', in case of failure of the whole pipeline
 #    - Add a checkbox to enable/disable options (storing/streaming - storing only - stream only - etc...)
 #    - Add a function to get the ip address of the camera automatically (see github.com/paulmilliken)
 #    - Create a module for the network configuration (fan/cpu, ifconfig, stream server,etc)
@@ -53,6 +54,7 @@ from time import time, gmtime, strftime
 import gi
 gi.require_version('Gtk', '3.0')
 from gi.repository import Gtk
+from gi.repository import Gdk
 gi.require_version('Gst', '1.0')
 from gi.repository import Gst
 from gi.repository import GdkX11
@@ -83,11 +85,23 @@ class Streamgui(object):
         vbox_streaminfo = Gtk.VBox(False, 0)
         vbox_cpuinfo = Gtk.VBox(False, 0)
         hbox = Gtk.HBox(False, 0)
+        hbox_videoaudio = Gtk.HBox(False, 0)
         hbox_time = Gtk.HBox(False, 0)
         
         self.videowidget = Gtk.DrawingArea()
         self.videowidget.set_size_request(600, 400)
 
+        self.vumeter = Gtk.ProgressBar()
+        self.vumeter.set_orientation(Gtk.Orientation.VERTICAL)
+        self.vumeter.set_inverted(True)
+## Use CSS to modify the color of ProgressBar
+##        color = Gdk.RGBA()
+##        Gdk.RGBA.parse(color, 'rgb(240,0,150)')
+##        print ("Color: ", color)
+##        self.vumeter.override_background_color(Gtk.StateFlags.NORMAL, color)
+##        self.vumeter.override_symbolic_color('bg_color', color)
+##        self.vumeter.override_symbolic_color('theme_bg_color', color)
+        
         self.baseinfo_label = Gtk.Label('Base info: ')
         self.baseinfo_entry_label = Gtk.Label('LP_' + formatted_date)
         self.speakerinfo_label = Gtk.Label('Speaker name: ')
@@ -100,6 +114,8 @@ class Streamgui(object):
         self.streamtime_label = Gtk.Label('Time elapsed ')
         self.streamtime_value = Gtk.Label('00:00:00')
         
+        hbox_videoaudio.pack_start(self.videowidget, True, True, 0)
+        hbox_videoaudio.pack_start(self.vumeter, True, True, 0)
         vbox_labels.pack_start(self.baseinfo_label, True, True, 0)
         vbox_labels.pack_start(self.speakerinfo_label, True, True, 0)
         vbox_labels.pack_start(self.sessioninfo_label, True, True, 0)
@@ -113,7 +129,7 @@ class Streamgui(object):
         hbox.pack_start(vbox_labels, False, False, 0)
         hbox.pack_start(vbox_entries, False, False, 0)
         hbox.pack_start(vbox_streaminfo, False, False, 0)
-        vbox.pack_start(self.videowidget, True, True, 0)
+        vbox.pack_start(hbox_videoaudio, True, True, 0)
         vbox.pack_start(hbox, False, True, 0)
 
         self.win.add(vbox)
@@ -125,7 +141,9 @@ class Streamgui(object):
         self.pipel = gstconf.New_user_pipeline()
 
         bus = gstconf.get_gstreamer_bus()
-        bus.connect("sync-message::element", self.on_sync_message)
+        bus.connect('sync-message::element', self.on_sync_message)
+        bus.connect('message', self.on_level_message)
+        ## Try to use 'sync-message::element' instead of 'message''
         
     def on_sync_message(self, bus, message):
 
@@ -134,6 +152,14 @@ class Streamgui(object):
             imagesink.set_property('force-aspect-ratio', True)
             imagesink.set_window_handle(self.videowidget.get_property('window').get_xid())
 
+    def on_level_message(self, bus, message):
+        s = Gst.Message.get_structure(message)
+        if message.type == Gst.MessageType.ELEMENT:
+            if str(Gst.Structure.get_name(s)) == 'level':
+                pct = self.iec_scale(s.get_value('rms')[0])
+                ##print('Level value: ', pct, '%')
+                self.vumeter.set_fraction(pct)
+
     def on_stream_clicked(self, widget):
 
         labelname = self.stream_button.get_label()
@@ -146,8 +172,10 @@ class Streamgui(object):
         elif labelname == 'ON AIR':
             self.pipel.stream_stop()
             self.stream_button.set_label('Stream')
-            self.build_filename()
-            
+##            self.build_filename()
+
+
+## In this state, this function freeze the streaming if the fields are NOT completed            
     def build_filename(self):
         """Get text in entries, check if empty and apply formatting if needed."""
         sep = '_'
@@ -176,7 +204,29 @@ class Streamgui(object):
         self.speakerinfo_entry.set_text('')
         self.sessioninfo_entry.set_text('')
 
-## Use threading module to refresh the time elapsed sinc the begining of the stream??
+    # Returns the meter deflection percentage given a db value
+    def iec_scale(self, db):
+        pct = 0.0
+    
+        if db < -70.0:
+            pct = 0.0
+        elif db < -60.0:
+            pct = (db + 70.0) * 0.25
+        elif db < -50.0:
+            pct = (db + 60.0) * 0.5 + 2.5
+        elif db < -40.0:
+            pct = (db + 50.0) * 0.75 + 7.5
+        elif db < -30.0:
+            pct = (db + 40.0) * 1.5 + 15.0
+        elif db < -20.0:
+            pct = (db + 30.0) * 2.0 + 30.0
+        elif db < 0.0:
+            pct = (db + 20.0) * 2.5 + 50.0
+        else:
+            pct = 100.0
+        return pct / 100
+        
+    ## Use threading module to refresh the time elapsed sinc the begining of the stream??
     def time_elapsed(self, widget):
         if self.pipel.stream_get_state() == 'PLAYING':
             pass