Deleting file: libre-streamer.py replaced by abyss.py
authorDavid Testé <soonum@gnu.org>
Mon, 14 Mar 2016 13:52:35 +0000 (14:52 +0100)
committerDavid Testé <soonum@gnu.org>
Mon, 14 Mar 2016 13:52:35 +0000 (14:52 +0100)
stream_2016/libre-streamer.py [deleted file]

diff --git a/stream_2016/libre-streamer.py b/stream_2016/libre-streamer.py
deleted file mode 100755 (executable)
index 6fae3db..0000000
+++ /dev/null
@@ -1,360 +0,0 @@
-#!/usr/bin/env python3.4
-# -*- coding: utf-8 -*-
-
-# This file is part of ABYSS.
-# ABYSS Broadcast Your Streaming Successfully 
-#
-# ABYSS is free software: you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation, either version 3 of the License, or
-# (at your option) any later version.
-#
-# ABYSS is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with ABYSS.  If not, see <http://www.gnu.org/licenses/>.
-#
-# Copyright (c) 2016 David Testé
-
-# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-# TODO list:
-# ----------
-#    - Implement a method to switch to webcam feed if Elphel cam feed is lost
-#         --> Use ping by opening Telnet connexion every 2 seconds (if it fails, then switch to webcam)
-#         --> Has to be threaded
-#    - 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)
-#         --> Taken care in FAI building
-#    - Generate a log file during runtime. (e.g. this will let you know if the network configuration
-#      and the pipeline construction went well (or not))
-#    - Add an input source choice for the user (camera on IP or webcam)
-#    - Add a time counter
-#         --> Has to be threaded
-#    - Add a 'CPU load' widget 
-#    - Add the FSF logo (need to do some pixel art) as an application icon
-#    - Add the FSF logo inside the streamer use the 'textoverlay' method in ElementFactory.make()
-# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-# !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-# INFO: run the following command in a terminal before launching libre-streamer to get a error log.
-# GST_DEBUG=4,python:5,gnl*:5 ./libre-streamer.py | tee -a log 2>&1
-# !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-
-__author__ = 'David Testé'
-__licence__ = 'GPLv3'
-__version__ = 0.1
-__maintainer__ = 'David Testé'
-__email__ = 'soonum@gnu.org'
-__status__ = 'Prototype'
-
-
-import sys
-from time import time, localtime, 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
-from gi.repository import GstVideo
-from gi.repository import GObject
-
-import gstconf
-
-# Based on 2016 FSF's ELPHEL camera configuration
-PORT = ':554'
-IP_1 = '192.168.48.2'
-IP_2 = '192.168.48.3'
-IP_3 = '192.168.48.4'
-CAM1_IP1 = 'CAM_1: ' + IP_1
-CAM2_IP2 = 'CAM_2: ' + IP_2
-CAM3_IP3 = 'CAM_3: ' + IP_3
-rtsp_address = None
-ENTRYFIELD_TEXT = 'Please fill both entry field to stop streaming.'
-CAMCHOICE_TEXT = 'Please choose a camera address.'
-TESTMODE_TEXT = 'Quit testing mode to switch to streaming mode.'
-formatted_date = strftime('%Y_%m_%d', localtime())
-metadata = {'speaker_name':'NC',
-            'session_title':'NC',
-            'organisation':'NC',}
-start_time = 0
-
-
-class Streamgui(object):
-
-
-    def __init__(self):
-
-        # Initialize a pipeline
-        self.pipel = None
-
-        # Create the GUI
-        self.win = Gtk.Window()
-        self.win.set_title("ABYSS")
-        self.win.connect("delete_event",
-                         lambda w,e: Gtk.main_quit())
-##        self.win.fullscreen()
-        vbox = Gtk.VBox(False, 0)
-        vbox_labels = Gtk.VBox(False, 0)
-        vbox_entries = Gtk.VBox(False, 0)
-        vbox_streaminfo = Gtk.VBox(True, 0)
-        vbox_tbuttongrp = Gtk.VBox(False, 0)
-        hbox = Gtk.HBox(False, 30)
-        hbox_videoaudio = Gtk.HBox(False, 0)
-        hbox_time = Gtk.HBox(False, 0)
-        hbox_cpu = Gtk.HBox(False, 0)
-        
-        self.videowidget = Gtk.DrawingArea()
-        self.videowidget.set_size_request(800, 600)
-
-
-        # True stereo feed has to be implemented:
-        self.vumeter_l = Gtk.ProgressBar()
-        self.vumeter_l.set_orientation(Gtk.Orientation.VERTICAL)
-        self.vumeter_l.set_inverted(True)
-        self.vumeter_r = Gtk.ProgressBar()
-        self.vumeter_r.set_orientation(Gtk.Orientation.VERTICAL)
-        self.vumeter_r.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: ')
-        self.speakerinfo_entry = Gtk.Entry()
-        self.sessioninfo_label = Gtk.Label('Session name: ')
-        self.sessioninfo_entry = Gtk.Entry()
-
-        self.stream_button = Gtk.Button('Stream')
-        self.stream_button.connect('clicked', self.on_stream_clicked)
-        self.streamtime_label = Gtk.Label('Time elapsed ')
-        self.streamtime_value = Gtk.Label('00:00:00')
-        self.test_button = Gtk.Button('Set-up test')
-        self.test_button.connect('clicked', self.on_test_clicked)
-
-        self.cpuload_label = Gtk.Label('CPU load: ')
-        self.cpuload_value = Gtk.Label('NC')
-
-        self.cam1_tbutton = Gtk.ToggleButton(None, label=CAM1_IP1)
-        self.cam1_tbutton.connect('toggled', self.on_tbutton_toggled, 'cam1')
-        self.cam2_tbutton = Gtk.ToggleButton(self.cam1_tbutton)
-        self.cam2_tbutton.set_label(CAM2_IP2)
-        self.cam2_tbutton.connect('toggled', self.on_tbutton_toggled, 'cam2')
-        self.cam3_tbutton = Gtk.ToggleButton(self.cam1_tbutton)
-        self.cam3_tbutton.set_label(CAM3_IP3)
-        self.cam3_tbutton.connect('toggled', self.on_tbutton_toggled, 'cam3')
-
-        self.entryfield_info = Gtk.MessageDialog(buttons=Gtk.ButtonsType.CLOSE,
-                                                 text=ENTRYFIELD_TEXT,)
-                                                 ##messagetype=Gtk.MessageType.WARNING,
-                                                 ##Gtk.MessageType.INFO,)
-        self.camchoice_info = Gtk.MessageDialog(buttons=Gtk.ButtonsType.CLOSE,
-                                                text=CAMCHOICE_TEXT,)
-        self.testmode_info = Gtk.MessageDialog(buttons=Gtk.ButtonsType.CLOSE,
-                                               text=TESTMODE_TEXT,)
-        
-        hbox_videoaudio.pack_start(self.videowidget, True, True, 0)
-        hbox_videoaudio.pack_start(self.vumeter_l, False, False, 3)
-        hbox_videoaudio.pack_start(self.vumeter_r, False, False, 3)
-        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)
-        vbox_entries.pack_start(self.baseinfo_entry_label, True, True, 0)
-        vbox_entries.pack_start(self.speakerinfo_entry, True, True, 0)
-        vbox_entries.pack_start(self.sessioninfo_entry, True, True, 0)
-        hbox_time.pack_start(self.streamtime_label, False, False, 0)
-        hbox_time.pack_start(self.streamtime_value, False, False, 0)
-        hbox_cpu.pack_start(self.cpuload_label, False, False, 0)
-        hbox_cpu.pack_start(self.cpuload_value, False, False, 0)
-        vbox_streaminfo.pack_start(hbox_time, False, True, 0)
-        vbox_streaminfo.pack_start(hbox_cpu, False, True, 0)
-        vbox_tbuttongrp.pack_start(self.cam1_tbutton, False, False, 0)
-        vbox_tbuttongrp.pack_start(self.cam2_tbutton, False, False, 0)
-        vbox_tbuttongrp.pack_start(self.cam3_tbutton, False, False, 0)
-        hbox.pack_start(vbox_labels, False, False, 0)
-        hbox.pack_start(vbox_entries, False, False, 0)
-        hbox.pack_start(vbox_tbuttongrp, False, False, 0)
-        hbox.pack_start(self.test_button, False, False, 0)
-        hbox.pack_start(self.stream_button, False , False, 0)
-        hbox.pack_start(vbox_streaminfo, False, False, 0)
-        vbox.pack_start(hbox_videoaudio, True, True, 0)
-        vbox.pack_start(hbox, False, True, 0)
-
-        self.win.add(vbox)
-        self.win.set_position(Gtk.WindowPosition.CENTER)
-        self.win.show_all()
-
-        self.xid = self.videowidget.get_property('window').get_xid()
-
-    def create_pipeline_instance(self, feed='main'):
-        """Creates pipeline instance and attaches it to GUI."""
-        if rtsp_address:
-            self.pipel = gstconf.New_user_pipeline(rtsp_address, feed,) 
-            bus = gstconf.get_gstreamer_bus()
-            bus.connect('sync-message::element', self.on_sync_message)
-            bus.connect('message', self.on_message)
-            return True
-        else:
-            self.camchoice_info.run()
-            self.camchoice_info.hide()
-            return False
-
-    def create_backup_pipeline(self):
-        labelname = self.stream_button.get_label()
-        if labelname == 'ON AIR':
-            self.create_pipeline_instance(feed='backup')
-            self.pipel.stream_play()
-
-    def on_sync_message(self, bus, message):
-
-        if message.get_structure().get_name() == 'prepare-window-handle':
-            imagesink = message.src
-            imagesink.set_property('force-aspect-ratio', True)
-            imagesink.set_window_handle(self.videowidget.get_property('window').get_xid())
-
-    def on_message(self, bus, message):
-        # Getting the RMS audio level value:
-        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, '%') # [DEBUG]
-                self.vumeter_l.set_fraction(pct)
-                self.vumeter_r.set_fraction(pct)
-        # Watching for feed loss during streaming:
-        t = message.type
-        if t == Gst.MessageType.ERROR:
-            err, debug = message.parse_error()
-            if '(651)' not in debug:
-                # The error is not a socket error.
-                self.pipel.stream_stop()
-                self.build_filename(streamfailed=True)
-                self.create_backup_pipeline()
-            
-    def on_stream_clicked(self, widget):
-        labelname1 = self.stream_button.get_label()
-        labelname2 = self.test_button.get_label()
-        if labelname1 == 'Stream':
-            if labelname2 != 'Testing ...':
-                if self.create_pipeline_instance():
-                    self.clean_entry_fields()
-                    self.pipel.stream_play()
-                    self.stream_button.set_label('ON AIR')
-                    start_time = time()
-            else:
-                self.testmode_info.run()
-                self.testmode_info.hide()
-        elif labelname1 == 'ON AIR':
-            if self.build_filename():
-                self.pipel.stream_stop()
-                self.stream_button.set_label('Stream')
-
-    def on_test_clicked(self, widget):
-        labelname = self.test_button.get_label()
-        if labelname == 'Set-up test':
-            if self.create_pipeline_instance(feed='test'):
-                self.pipel.stream_play()
-                self.test_button.set_label('Testing ...')            
-        elif labelname == 'Testing ...':
-            self.pipel.stream_stop()
-            self.test_button.set_label('Set-up test')
-
-    def on_tbutton_toggled(self, tbutton, name):
-        global rtsp_address
-        running_cond = (self.stream_button.get_label() == 'ON AIR' or
-                        self.test_button.get_label() == 'Testing ...')
-        if running_cond:
-            tbutton.set_active(False)
-##            if tbutton.active():
-##                tbutton.set_active(True)
-            return
-            
-        if tbutton.get_active():
-            if name == 'cam1':
-                self.cam2_tbutton.set_active(False)
-                self.cam3_tbutton.set_active(False)
-                rtsp_address = IP_1 + PORT
-            elif name == 'cam2':
-                self.cam1_tbutton.set_active(False)
-                self.cam3_tbutton.set_active(False)
-                rtsp_address = IP_2 + PORT
-            elif name == 'cam3':
-                self.cam1_tbutton.set_active(False)
-                self.cam2_tbutton.set_active(False)
-                rtsp_address = IP_3 + PORT
-        
-    def build_filename(self, streamfailed=False):
-        """Get text in entries, check if empty and apply formatting if needed."""
-        sep = '_'
-        base = self.baseinfo_entry_label.get_text()
-        speaker = self.speakerinfo_entry.get_text()
-        speaker = sep.join(speaker.split())
-        session = self.sessioninfo_entry.get_text()
-        session = sep.join(session.split())
-        raw_filename = base + sep + speaker + sep + session
-        maxlen = 70
-        if speaker and session:
-            if len(raw_filename) >= maxlen:
-                offset = len(raw_filename) - maxlen
-                raw_filename = raw_filename[:-offset]
-                if streamfailed:
-                    self.pipel.set_filenames(raw_filename, streamfailed=True)
-                else:
-                    self.pipel.set_filenames(raw_filename,)
-##                    print('RAWFILENAME: ', raw_filename, ' <--')  # [DEBUG]
-            elif streamfailed:
-                self.pipel.set_filenames(raw_filename, streamfailed=True)
-            return True
-        elif not streamfailed:
-            self.entryfield_info.run()
-            self.entryfield_info.hide()
-            return False
-
-                
-    def clean_entry_fields(self):
-        self.speakerinfo_entry.set_text('')
-        self.sessioninfo_entry.set_text('')
-
-    def iec_scale(self, db):
-        """Returns the meter deflection percentage given a db value."""
-        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
-            
-        
-if __name__ == "__main__":
-    Gst.init()
-    Streamgui()
-    Gtk.main()