CC-1469: Crossfading support (non-equal power)

-fix restarting airtime playout not resyncing to schedule correctly
This commit is contained in:
Martin Konecny 2013-04-22 17:33:56 -04:00
parent 96579b7ef4
commit 07f0ae6c28
5 changed files with 46 additions and 15 deletions

View File

@ -23,6 +23,7 @@ from pypofile import PypoFile
from recorder import Recorder from recorder import Recorder
from listenerstat import ListenerStat from listenerstat import ListenerStat
from pypomessagehandler import PypoMessageHandler from pypomessagehandler import PypoMessageHandler
from pypoliquidsoap import PypoLiquidsoap
from media.update.replaygainupdater import ReplayGainUpdater from media.update.replaygainupdater import ReplayGainUpdater
from media.update.silananalyzer import SilanAnalyzer from media.update.silananalyzer import SilanAnalyzer
@ -194,7 +195,8 @@ if __name__ == '__main__':
recorder_q = Queue() recorder_q = Queue()
pypoPush_q = Queue() pypoPush_q = Queue()
pypo_liquidsoap = PypoLiquidsoap(logger, telnet_lock,\
ls_host, ls_port)
""" """
This queue is shared between pypo-fetch and pypo-file, where pypo-file This queue is shared between pypo-fetch and pypo-file, where pypo-file
@ -212,11 +214,11 @@ if __name__ == '__main__':
pfile.daemon = True pfile.daemon = True
pfile.start() pfile.start()
pf = PypoFetch(pypoFetch_q, pypoPush_q, media_q, telnet_lock) pf = PypoFetch(pypoFetch_q, pypoPush_q, media_q, telnet_lock, pypo_liquidsoap)
pf.daemon = True pf.daemon = True
pf.start() pf.start()
pp = PypoPush(pypoPush_q, telnet_lock) pp = PypoPush(pypoPush_q, telnet_lock, pypo_liquidsoap)
pp.daemon = True pp.daemon = True
pp.start() pp.start()

View File

@ -47,7 +47,7 @@ except Exception, e:
sys.exit() sys.exit()
class PypoFetch(Thread): class PypoFetch(Thread):
def __init__(self, pypoFetch_q, pypoPush_q, media_q, telnet_lock): def __init__(self, pypoFetch_q, pypoPush_q, media_q, telnet_lock, pypo_liquidsoap):
Thread.__init__(self) Thread.__init__(self)
self.api_client = api_client.AirtimeApiClient() self.api_client = api_client.AirtimeApiClient()
self.fetch_queue = pypoFetch_q self.fetch_queue = pypoFetch_q
@ -58,7 +58,9 @@ class PypoFetch(Thread):
self.telnet_lock = telnet_lock self.telnet_lock = telnet_lock
self.logger = logging.getLogger(); self.logger = logging.getLogger()
self.pypo_liquidsoap = pypo_liquidsoap
self.cache_dir = os.path.join(config["cache_dir"], "scheduler") self.cache_dir = os.path.join(config["cache_dir"], "scheduler")
self.logger.debug("Cache dir %s", self.cache_dir) self.logger.debug("Cache dir %s", self.cache_dir)
@ -574,6 +576,14 @@ class PypoFetch(Thread):
# Bootstrap: since we are just starting up, we need to grab the # Bootstrap: since we are just starting up, we need to grab the
# most recent schedule. After that we can just wait for updates. # most recent schedule. After that we can just wait for updates.
success = self.persistent_manual_schedule_fetch(max_attempts=5) success = self.persistent_manual_schedule_fetch(max_attempts=5)
#Make sure all Liquidsoap queues are empty. This is important in the
#case where we've just restarted the pypo scheduler, but Liquidsoap still
#is playing tracks. In this case let's just restart everything from scratch
#so that we can repopulate our dictionary that keeps track of what
#Liquidsoap is playing much more easily.
self.pypo_liquidsoap.clear_all_queues()
if success: if success:
self.logger.info("Bootstrap schedule received: %s", self.schedule_data) self.logger.info("Bootstrap schedule received: %s", self.schedule_data)
self.set_bootstrap_variables() self.set_bootstrap_variables()

View File

@ -20,7 +20,8 @@ class PypoLiquidsoap():
self.telnet_liquidsoap = TelnetLiquidsoap(telnet_lock, \ self.telnet_liquidsoap = TelnetLiquidsoap(telnet_lock, \
logger,\ logger,\
host,\ host,\
port) port,\
self.liq_queue_tracker.keys())
def play(self, media_item): def play(self, media_item):
@ -90,9 +91,6 @@ class PypoLiquidsoap():
return available_queue return available_queue
def get_queues():
return self.liq_queue_tracker
def verify_correct_present_media(self, scheduled_now): def verify_correct_present_media(self, scheduled_now):
#verify whether Liquidsoap is currently playing the correct files. #verify whether Liquidsoap is currently playing the correct files.
@ -105,8 +103,6 @@ class PypoLiquidsoap():
#get liquidsoap items for each queue. Since each queue can only have one #get liquidsoap items for each queue. Since each queue can only have one
#item, we should have a max of 8 items. #item, we should have a max of 8 items.
#TODO: Verify start, end, replay_gain is the same
#2013-03-21-22-56-00_0: { #2013-03-21-22-56-00_0: {
#id: 1, #id: 1,
#type: "stream_output_start", #type: "stream_output_start",
@ -222,6 +218,9 @@ class PypoLiquidsoap():
return seconds return seconds
def clear_all_queues(self):
self.telnet_liquidsoap.queue_clear_all()
class UnknownMediaItemType(Exception): class UnknownMediaItemType(Exception):
pass pass

View File

@ -51,7 +51,7 @@ def is_file(media_item):
return media_item['type'] == 'file' return media_item['type'] == 'file'
class PypoPush(Thread): class PypoPush(Thread):
def __init__(self, q, telnet_lock): def __init__(self, q, telnet_lock, pypo_liquidsoap):
Thread.__init__(self) Thread.__init__(self)
self.api_client = api_client.AirtimeApiClient() self.api_client = api_client.AirtimeApiClient()
self.queue = q self.queue = q
@ -64,8 +64,10 @@ class PypoPush(Thread):
self.queue_id = 0 self.queue_id = 0
self.future_scheduled_queue = Queue() self.future_scheduled_queue = Queue()
self.pypo_liquidsoap = PypoLiquidsoap(self.logger, telnet_lock,\
LS_HOST, LS_PORT) #self.pypo_liquidsoap = PypoLiquidsoap(self.logger, telnet_lock,\
#LS_HOST, LS_PORT)
self.pypo_liquidsoap = pypo_liquidsoap
self.plq = PypoLiqQueue(self.future_scheduled_queue, \ self.plq = PypoLiqQueue(self.future_scheduled_queue, \
self.pypo_liquidsoap, \ self.pypo_liquidsoap, \

View File

@ -7,11 +7,12 @@ def create_liquidsoap_annotation(media):
class TelnetLiquidsoap: class TelnetLiquidsoap:
def __init__(self, telnet_lock, logger, ls_host, ls_port): def __init__(self, telnet_lock, logger, ls_host, ls_port, queues):
self.telnet_lock = telnet_lock self.telnet_lock = telnet_lock
self.ls_host = ls_host self.ls_host = ls_host
self.ls_port = ls_port self.ls_port = ls_port
self.logger = logger self.logger = logger
self.queues = queues
self.current_prebuffering_stream_id = None self.current_prebuffering_stream_id = None
def __connect(self): def __connect(self):
@ -20,6 +21,23 @@ class TelnetLiquidsoap:
def __is_empty(self, tn, queue_id): def __is_empty(self, tn, queue_id):
return True return True
def queue_clear_all(self):
try:
self.telnet_lock.acquire()
tn = self.__connect()
for i in self.queues:
msg = 'queues.%s_skip\n' % i
self.logger.debug(msg)
tn.write(msg)
tn.write("exit\n")
self.logger.debug(tn.read_all())
except Exception:
raise
finally:
self.telnet_lock.release()
def queue_remove(self, queue_id): def queue_remove(self, queue_id):
try: try:
self.telnet_lock.acquire() self.telnet_lock.acquire()