Ejemplo n.º 1
0
    def __init__(self, dispatcher, repo, worker, conf, logger, autorecover=False, recorderklass=Recorder):
        """
        Initialize the recorder service.

        :param dispacher service.
        :param repo service.
        :param worker service.
        :param conf service.
        :param logger service.
        :param recorderklass (only to test)
        """
        self.repo = repo
        self.dispatcher = dispatcher
        self.worker = worker
        self.logger = logger
        self.conf = conf
        self.overlap = conf.get_permission("overlap")
        self.mute = True

        self.__set_status(INIT_STATUS)

        self.current_mediapackage = None
        self.last_mediapackage = None
        self.error_msg = None
        self.recorder = None
        self.__recorderklass = recorderklass
        self.__create_drawing_areas_func = None
        self.__handle_recover_id = None
        self.autorecover = autorecover

        self.logger.info("Autorecover mode: {}".format(self.autorecover))

        self.dispatcher.connect("init", WeakMethod(self, '_handle_init'))
        self.dispatcher.connect_ui("action-reload-profile", WeakMethod(self, '_handle_reload_profile'))
        self.dispatcher.connect("recorder-error", WeakMethod(self, '_handle_error'))
Ejemplo n.º 2
0
    def __init__(self, bins, players={}):
        """
        Initialize the recorder.
        This class is event-based and needs a mainloop to work properly.

        :param bins: a ``list`` of ``dict`` with name, klass, device and file to record
        :param players: a ``dict`` a gtk.DrawingArea list to use as player.
        """
        #FIXME check the values are dict with the next keys: name, klass/type, dev* and filesink.
        if not isinstance(bins, list):
            raise TypeError('%s: need a %r; got a %r: %r' %
                            ('bins', list, type(bins), bins))
        #FIXME check the values are gtk.DrawingArea
        if not isinstance(players, dict):
            raise TypeError('%s: need a %r; got a %r: %r' %
                            ('players', dict, type(players), players))

        self.dispatcher = context.get_dispatcher()
        self.players = players
        self.restart = False
        self.mute = False
        self.error = False
        self.__on_start_only_preview = True
        self.__start_record_time = 0
        self.__duration = 0

        self.pipeline = gst.Pipeline("galicaster_recorder")
        self.bus = self.pipeline.get_bus()

        self.bins = dict()
        self.callback = None

        self.bus.add_signal_watch()
        self.bus.enable_sync_message_emission()
        #self.bus.connect('message', WeakMethod(self, '_debug')) # TO DEBUG
        self.bus.connect('message::eos', WeakMethod(self, '_on_eos'))
        self.bus.connect('message::error', WeakMethod(self, '_on_error'))
        self.bus.connect('message::element',
                         WeakMethod(self, '_on_message_element'))
        self.bus.connect('message::state-changed',
                         WeakMethod(self, '_on_state_changed'))
        self.bus.connect('sync-message::element',
                         WeakMethod(self, '_on_sync_message'))

        for bin in bins:
            name = bin['name']

            try:
                mod_name = 'galicaster.recorder.bins.' + bin['device']
                __import__(mod_name)
                mod = sys.modules[mod_name]
                Klass = getattr(mod, "GC" + bin['device'])
            except:
                raise NameError('Invalid track type %s for %s track' %
                                (mod_name, name))

            logger.debug("Init bin %s %s", name, mod_name)
            self.bins[name] = Klass(bin)
            self.pipeline.add(self.bins[name])
Ejemplo n.º 3
0
    def create_pipeline(self):
        self.pipeline = Gst.Pipeline.new("galicaster_player")
        bus = self.pipeline.get_bus()
        # Create bus and connect several handlers
        bus.add_signal_watch()
        bus.enable_sync_message_emission()
        bus.connect('message::eos', WeakMethod(self, '_on_eos'))
        bus.connect('message::error', WeakMethod(self, '_on_error'))
        bus.connect('message::element', WeakMethod(self, '_on_message_element'))
        bus.connect('message::state-changed', WeakMethod(self, '_on_state_changed'))
        bus.connect('sync-message::element', WeakMethod(self, '_on_sync_message'))

        # Create elements
        for name, location in self.files.iteritems():
            logger.info('playing %r', location)
            src = Gst.ElementFactory.make('filesrc', 'src-' + name)
            src.set_property('location', location)
            dec = Gst.ElementFactory.make('decodebin', 'decode-' + name)

            # Connect handler for 'pad-added' signal
            dec.connect('pad-added', WeakMethod(self, '_on_new_decoded_pad'))

            # Link elements
            self.pipeline.add(src)
            self.pipeline.add(dec)
            src.link(dec)

        self.error = None
        return None
Ejemplo n.º 4
0
    def _handle_error(self, origin, error_msg):
        self.logger.error("Handle error ({})". format(error_msg))
        # self.current_mediapackage = None
        if self.recorder:
            self.recorder.stop(True)
            if self.status == RECORDING_STATUS:
                self.repo.recover_recording()
                self.current_mediapackage = None

        self.error_msg = error_msg
        self.__set_status(ERROR_STATUS)

        if self.autorecover and not self.__handle_recover_id:
            self.logger.info("Connecting recover recorder callback")
            self.__handle_recover_id = self.dispatcher.connect("timer-long",
                                                             WeakMethod(self, '_handle_recover'))
Ejemplo n.º 5
0
    def __init__(self, bins, players={}):
        """
        Initialize the recorder.

        :param bins: ``list`` of ``dict`` with bin name, device, path, and optional parameters.
        :param players: (optional) ```Gtk.DrawingArea``` ```list``` to use as player.
        """
        if not isinstance(bins, list) or len(bins) == 0:
            raise TypeError('{}: need a {}; got a {}: {}'.format(
                'bins', list, type(bins), bins))

        if not isinstance(players, dict):
            raise TypeError('{}: need a {}; got a {}: {}'.format(
                'players', dict, type(players), players))

        self.dispatcher = context.get_dispatcher()
        self.players = players
        self.restart = False
        #        self.mute = False
        self.mute_status = {"input": {}, "preview": {}}
        self.error = False
        self.is_recording = False
        self.__start_record_time = -1
        self.__pause_timestamp = 0
        self.__paused_time = 0
        self.__valves_status = False
        self.__duration = 0

        self.pipeline = Gst.Pipeline.new("galicaster_recorder")
        self.bus = self.pipeline.get_bus()

        self.bins = dict()
        self.callback = None

        self.bus.add_signal_watch()
        #        self.bus.connect('message', WeakMethod(self, '_debug')) # TO DEBUG
        self.bus.connect('message::error', WeakMethod(self, '_on_error'))
        self.bus.connect('message::element',
                         WeakMethod(self, '_on_message_element'))

        try:
            for bin in bins:
                name = bin['name']

                mod_name = 'galicaster.recorder.bins.' + bin['device']
                __import__(mod_name)
                mod = sys.modules[mod_name]
                Klass = getattr(mod, "GC" + bin['device'])

                logger.debug("Init bin {} {}".format(name, mod_name))
                self.bins[name] = Klass(bin)
                self.pipeline.add(self.bins[name])
                self.bins[name].prepare(self.bus)

#            self.enable_input()
            self.enable_preview()

        except Exception as exc:
            logger.info("Removing loaded bins due to an error...")
            for bin_name in self.bins:
                self.pipeline.remove(self.bins[bin_name])
            self.bins.clear()

            self.error = str(exc)
            name = name if 'name' in locals() else 'Unknown'
            message = 'Invalid track type "{}" for "{}" track: {}'.format(
                bin.get('device'), name, exc)
            raise NameError(message)