diff --git a/modules/communication/liquidsoap/initthread.py b/modules/communication/liquidsoap/initthread.py deleted file mode 100644 index 466481ba5e5ed7a3f2f0d8aaba70441d3641f3e4..0000000000000000000000000000000000000000 --- a/modules/communication/liquidsoap/initthread.py +++ /dev/null @@ -1,150 +0,0 @@ -# -# engine -# -# Playout Daemon for autoradio project -# -# -# Copyright (C) 2017-2018 Gottfried Gaisbauer <gottfried.gaisbauer@servus.at> -# -# This file is part of engine. -# -# engine 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 -# any later version. -# -# engine 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 engine. If not, see <http://www.gnu.org/licenses/>. -# - -import time -import logging -import datetime -import threading - -from libraries.enum.auraenumerations import ScheduleEntryType, TerminalColors - - -""" -LiquidSoapInitThread class. - -Starts the LiquidSoap player including the current show. -""" - -class LiquidSoapInitThread(threading.Thread): - - logger = None - active_entry = None - liquidsoapcommunicator = None - - - def __init__(self, liquidsoapcommunicator, active_entry): - """ - Initialize the thread. - """ - threading.Thread.__init__(self) - self.logger = logging.getLogger("AuraEngine") - self.liquidsoapcommunicator = liquidsoapcommunicator - self.active_entry = active_entry - - - - def run(self): - """ - Starts the LiquidSoap player including the current show. - """ - try: - # Sleep needed, because the socket is created too slow by liquidsoap - time.sleep(1) - self.logger.info("Waited 1s for liquidsoap. Jez soit a si gspian") - - self.liquidsoapcommunicator.enable_transaction() - - # Wait another second. lqs really starts slow.. be prepared you liquidsoap you! - time.sleep(1) - self.set_start_parameters() - self.set_active_show() - - self.liquidsoapcommunicator.disable_transaction() - # The rest of the system now can use liquidsoap connection - self.liquidsoapcommunicator.is_liquidsoap_running = True - - except Exception as e: - self.logger.critical(TerminalColors.RED.value+"Liquidsoap connection ERROR! Restart LQ Server! Reason: "+str(e)+TerminalColors.ENDC.value) - - - - def set_active_show(self): - """ - Sets and resumes the show which should be playing at the time of starting - the LiquidSoap player. - """ - if self.active_entry is not None: - channel = self.active_entry.type - self.logger.info("LiquidSoapInitThread sets activechannel '%s' for entry '%s'" % (channel, str(self.active_entry))) - - if channel == ScheduleEntryType.FILESYSTEM: - - # TODO For some reason LiquidSoap cue-points don't work. Actually, - # this would be the ideal approach to seek. Investigate some solution! - # if seconds_to_seek < 0: - # seconds_to_seek = 0 - # self.liquidsoapcommunicator.activate(self.active_entry, seconds_to_seek) - - self.liquidsoapcommunicator.activate(self.active_entry) - # rest_of_playlist = self.active_entry.get_next_entries() - # for entry in rest_of_playlist: - # self.logger.info("ACTIVATING NEXT ENTRY: %s" %entry) - # self.liquidsoapcommunicator.activate(entry) - - # Have to seek? Calc how many seconds were missed - now_unix = time.mktime(datetime.datetime.now().timetuple()) - seconds_to_seek = now_unix - self.active_entry.start_unix - - # And seek these seconds forward - if seconds_to_seek > 0: - # Without plenty of timeout (10s) the seek doesn't work - seconds_to_seek += 10 - time.sleep(10) - response = self.liquidsoapcommunicator.playlist_seek(seconds_to_seek) - self.logger.info("LiquidSoap seek response: " + response) - - - # Finally make something hearable :-) - if channel: - # Activate HTTP stream if needed - self.liquidsoapcommunicator.http_start_stop(channel == ScheduleEntryType.STREAM) - # Finally set the volume up - self.liquidsoapcommunicator.channel_volume(channel.value, self.active_entry.volume) - else: - self.logger.error("Channel is NULL or empty! Cannot set ") - - else: - self.logger.warning("No active entry in the scheduler! Is a programme loaded?") - - - - def set_start_parameters(self): - """ - Set initial parameters for the LiquidSoap player startup. - """ - # Reset channels and reload them - channels = self.liquidsoapcommunicator.reload_channels() - - # For all available channels - for c in channels: - # Set volume to zero - self.liquidsoapcommunicator.channel_volume(c, "0") - # And activate this channel - self.liquidsoapcommunicator.channel_activate(c, True) - - # Setting init params like a blank file.. - install_dir = self.liquidsoapcommunicator.config.get("install_dir") - self.liquidsoapcommunicator.playlist_push(install_dir + "/configuration/blank.flac") - # .. or the radio fro stream (it is overwritten as soon as one http overtake is planned) - #self.liquidsoapcommunicator.set_http_url("http://stream.fro.at/fro-128.ogg") diff --git a/modules/core/startup.py b/modules/core/startup.py new file mode 100644 index 0000000000000000000000000000000000000000..4717de0b1c88e3582956563daa6ce3b6a9f9c75d --- /dev/null +++ b/modules/core/startup.py @@ -0,0 +1,135 @@ +# +# Aura Engine +# +# Copyright (C) 2017-2020 +# David Trattnig <david.trattnig@subsquare.at> +# Gottfried Gaisbauer <gottfried.gaisbauer@servus.at> + +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU Affero General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. + +# This program 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 Affero General Public License for more details. + +# You should have received a copy of the GNU Affero General Public License +# along with this program. If not, see <http://www.gnu.org/licenses/>. + +import time +import logging +import datetime +import threading +import meta + +from modules.base.enum import Channel, ChannelType +from modules.base.utils import TerminalColors, SimpleUtil, EngineUtil + + +class StartupThread(threading.Thread): + """ + StartupThread class. + + Boots the mixer and starts playing the current schedule. + """ + logger = None + active_entry = None + liquidsoapcommunicator = None + + + + def __init__(self, liquidsoapcommunicator, active_entry): + """ + Initialize the thread. + """ + threading.Thread.__init__(self) + self.logger = logging.getLogger("AuraEngine") + self.liquidsoapcommunicator = liquidsoapcommunicator + self.active_entry = active_entry + + + + def run(self): + """ + Starts the LiquidSoap player including the current show. + """ + try: + # Sleep needed, because the socket is created too slow by liquidsoap + time.sleep(1) + self.logger.info("Waited 1s for liquidsoap. Jez soit a si gspian") + + self.liquidsoapcommunicator.enable_transaction() + + # Wait another second. lqs really starts slow.. be prepared you liquidsoap you! + time.sleep(1) + self.logger.info(SimpleUtil.green("Engine Core ------[ connected ]-------- Liquidsoap")) + + self.set_start_parameters() + self.logger.info(EngineUtil.engine_info("Engine Core", meta.__version__)) + + # Display the current programme + programme = self.liquidsoapcommunicator.scheduler.get_ascii_programme() + self.logger.info(programme) + + # Start playing + self.set_active_show() + self.liquidsoapcommunicator.disable_transaction() + + # The rest of the system now can use liquidsoap connection + self.liquidsoapcommunicator.is_liquidsoap_running = True + + + except Exception as e: + self.logger.critical(TerminalColors.RED.value+"Liquidsoap connection ERROR! Restart LQ Server! Reason: "+str(e)+TerminalColors.ENDC.value) + + + + def set_active_show(self): + """ + Sets and resumes the show which should be playing at the time of starting + the LiquidSoap player. + """ + if self.active_entry is not None: + channel_type = self.active_entry.type + self.logger.info("Engine Startup: Play '%s' via channel type '%s'" % (str(self.active_entry), channel_type)) + + # TODO Skip active entry if not enough time left; wait and play next one instead + self.liquidsoapcommunicator.play(self.active_entry, False) + + if channel_type == ChannelType.FILESYSTEM: + + + + # Have to seek? Calc how many seconds were missed + now_unix = time.mktime(datetime.datetime.now().timetuple()) + seconds_to_seek = now_unix - self.active_entry.start_unix + + # And seek these seconds forward + if seconds_to_seek > 0: + # Without plenty of timeout (10s) the seek doesn't work + seconds_to_seek += 10 + time.sleep(10) + channel = self.liquidsoapcommunicator.active_channel[ChannelType.FILESYSTEM] + response = self.liquidsoapcommunicator.playlist_seek(channel, seconds_to_seek) + self.logger.info("LiquidSoap seek response: " + response) + + else: + self.logger.warning("No active entry in the scheduler! Is a programme loaded?") + + + + + def set_start_parameters(self): + """ + Set initial parameters for the LiquidSoap player startup. + """ + self.liquidsoapcommunicator.mixer_start() + + # Setting init params like a blank file.. + install_dir = self.liquidsoapcommunicator.config.get("install_dir") + channel = self.liquidsoapcommunicator.active_channel[ChannelType.FILESYSTEM] + self.liquidsoapcommunicator.playlist_push(channel, install_dir + "/configuration/blank.flac") + # .. or the radio fro stream (it is overwritten as soon as one http overtake is planned) + #self.liquidsoapcommunicator.set_http_url("http://stream.fro.at/fro-128.ogg")