From b5faf5261508b09de0204bb69fd7ab53ba8fb041 Mon Sep 17 00:00:00 2001 From: David Trattnig <david.trattnig@o94.at> Date: Thu, 30 Jan 2020 20:25:27 +0100 Subject: [PATCH] Added cue-in capability. --- .../communication/liquidsoap/communicator.py | 126 ++++++++++++------ 1 file changed, 83 insertions(+), 43 deletions(-) diff --git a/modules/communication/liquidsoap/communicator.py b/modules/communication/liquidsoap/communicator.py index 33869e4f..d8c4e67e 100644 --- a/modules/communication/liquidsoap/communicator.py +++ b/modules/communication/liquidsoap/communicator.py @@ -121,10 +121,12 @@ class LiquidSoapCommunicator(ExceptionLogger): # ------------------------------------------------------------------------------------------ # def get_active_channel(self): """ - gets active channel from programme - :return: + Retrieves the active channel from programme. + + Returns: + (String): The channel type, empty string if no channel is active. """ - (show, active_entry) = self.scheduler.get_active_entry() + active_entry = self.scheduler.get_active_entry() if active_entry is None: return "" return active_entry.type @@ -286,45 +288,58 @@ class LiquidSoapCommunicator(ExceptionLogger): return True # ------------------------------------------------------------------------------------------ # - def activate(self, new_entry): - # grab the actual active entry - (show, old_entry) = self.scheduler.get_active_entry() - # determine its type - # TODO Move to <get_active_entry> - # FIXME No need to switch if current type = new type - old_type = ScheduleEntryType.FILESYSTEM # Set default if no previous track is available - if old_entry: - old_type = old_entry.type + def activate(self, new_entry, cue_in=0.0): + """ + Activates a new Playlist Entry. + + Args: + new_entry (PlaylistEntry): The track to be played + + Raises: + (LQConnectionError): In case connecting to LiquidSoap isn't possible + """ + + # Grab the actual active entry + active_entry = self.scheduler.get_active_entry() + # Set default channel, if no previous track is available + current_channel = ScheduleEntryType.FILESYSTEM + if active_entry: + current_channel = active_entry.type try: - # enable transaction self.enable_transaction() - - if old_type == new_entry.type: - # push something to active channel - self.activate_same_channel(new_entry) + if current_channel == new_entry.type: + self.activate_same_channel(new_entry, cue_in) else: - # switch to another channel - self.activate_different_channel(new_entry, old_type) - - # disable conn + self.activate_different_channel(new_entry, cue_in, current_channel) self.disable_transaction() - # insert playlist entry - self.logger.critical("Trackservice entry not written here anymore") -# self.insert_track_service_entry(new_entry) + # FIXME Implement TrackService bi-directionally, log fallbacks too. + self.logger.critical("FIXME: Implement TrackService") +# self.insert_track_service_entry(new_entry) except LQConnectionError: - # we already caught and handled this error in __send_lqc_command__, but we do not want to execute this function further and pass the exception + # we already caught and handled this error in __send_lqc_command__, + # but we do not want to execute this function further and pass the exception pass - # ------------------------------------------------------------------------------------------ # - def activate_same_channel(self, entry, activate_different_channel=False): + + def activate_same_channel(self, entry, cue_in=0.0, activate_different_channel=False): + """ + Activates a playlist entry for the current channel. + + Args: + entry (PlaylistEntry): The entry to play. + cue_in (Float): A value in seconds where to cue the start of the entry. + """ if not activate_different_channel: self.logger.info(TerminalColors.PINK.value + entry.type.value + " already active!" + TerminalColors.ENDC.value) - # push to fs or stream + # Check if it needs to be pushed to a filesystem queue or stream if entry.type == ScheduleEntryType.FILESYSTEM: - self.playlist_push(entry.filename) + uri = entry.filename + if cue_in > 0.0: + uri = "annotate:liq_cue_in=\"%s\":%s" % (str(cue_in), entry.filename) + self.playlist_push(uri) self.active_channel = entry.type elif entry.type == ScheduleEntryType.STREAM: @@ -333,27 +348,36 @@ class LiquidSoapCommunicator(ExceptionLogger): self.active_channel = entry.type # else: # live - # nothing to do when we are live => just leave it as is + # Nothing to do when we are live => just leave it as is self.active_channel = entry.type - # set active channel to wanted volume + # Set active channel to wanted volume if not activate_different_channel: self.channel_volume(entry.type.value, entry.volume) - # ------------------------------------------------------------------------------------------ # - def activate_different_channel(self, entry, active_type): + + def activate_different_channel(self, entry, cue_in, active_type): + """ + Activates a playlist entry for a channel other then the currently active one. + + Args: + entry (PlaylistEntry): The entry to play. + cue_in (Float): A value in seconds where to cue the start of the entry. + active_type (ScheduleEntryType): The type of the currently active channel + """ self.logger.info(TerminalColors.PINK.value + "LiquidSoapCommunicator is activating " + entry.type.value + " & deactivating " + active_type.value + "!" + TerminalColors.ENDC.value) - # reuse of this function, because activate_same_channel and activate_different_channel are doing pretty the same except setting of the volume to zero - self.activate_same_channel(entry, True) + # Reuse of this function, because activate_same_channel and activate_different_channel + # are doing pretty the same except setting of the volume to zero + self.activate_same_channel(entry, cue_in, True) - # set other channels to zero volume + # Set other channels to zero volume others = self.all_inputs_but(entry.getChannel()) for o in others: self.channel_volume(o, 0) - # set active channel to wanted volume + # Set active channel to wanted volume self.channel_volume(entry.type.value, entry.volume) # ------------------------------------------------------------------------------------------ # @@ -399,7 +423,13 @@ class LiquidSoapCommunicator(ExceptionLogger): # ------------------------------------------------------------------------------------------ # def init_player(self): - (_, active_entry) = self.scheduler.get_active_entry() + """ + Initializes the LiquidSoap Player after startup of the engine. + + Returns: + (String): Message that the player is started. + """ + active_entry = self.scheduler.get_active_entry() t = LiquidSoapInitThread(self, active_entry) t.start() @@ -461,7 +491,7 @@ class LiquidSoapCommunicator(ExceptionLogger): # ------------------------------------------------------------------------------------------ # def liquidsoap_help(self): - data = self.__send_lqc_command__(self.client, 'help') + data = self.__send_lqc_command__(self.client, "help", "") if not data: self.logger.warning("Could not get Liquidsoap's help") else: @@ -475,15 +505,24 @@ class LiquidSoapCommunicator(ExceptionLogger): # ------------------------------------------------------------------------------------------ # def playlist_push(self, uri): """ - Eine Uri in die Playlist einfügen - @type uri: str - @param uri: Die Uri + Adds an filesystem URI to the playlist + + Args: + uri (String): The URI of the file + Returns: + LiquidSoap Response """ return self.__send_lqc_command__(self.client, "fs", "push", uri) # ------------------------------------------------------------------------------------------ # def playlist_seek(self, seconds_to_seek): - return self.__send_lqc_command__(self.client, "fs", "seek", seconds_to_seek) + """ + Forwards the player (n) seconds. + + Args: + seconds_to_seeks (Float): The seconds to skip + """ + return self.__send_lqc_command__(self.client, "fs", "seek", str(seconds_to_seek)) # ------------------------------------------------------------------------------------------ # def version(self): @@ -566,6 +605,7 @@ class LiquidSoapCommunicator(ExceptionLogger): raise e else: # also store when was last admin mail sent with which content... + # FIXME implement admin mail sending self.logger.critical("SEND ADMIN MAIL AT THIS POINT") raise e -- GitLab