Commit f593acdd authored by david's avatar david
Browse files

Fix for live channel selection. #81

parent e7ca792f
Pipeline #1029 failed with stage
...@@ -46,7 +46,7 @@ class Channel(Enum): ...@@ -46,7 +46,7 @@ class Channel(Enum):
LIVE_3 = "linein_3" LIVE_3 = "linein_3"
LIVE_4 = "linein_4" LIVE_4 = "linein_4"
FALLBACK_QUEUE_A = "in_fallback_scheduled_0" FALLBACK_QUEUE_A = "in_fallback_scheduled_0"
FALLBACK_QUEUE_B = "in_fallback_scheduled_1" FALLBACK_QUEUE_B = "in_fallback_scheduled_1"
FALLBACK_STATION_FOLDER = "station_folder" FALLBACK_STATION_FOLDER = "station_folder"
FALLBACK_STATION_PLAYLIST = "station_playlist" FALLBACK_STATION_PLAYLIST = "station_playlist"
...@@ -54,6 +54,33 @@ class Channel(Enum): ...@@ -54,6 +54,33 @@ class Channel(Enum):
return str(self.value) return str(self.value)
class ChannelResolver():
"""
Helpers for resolving channel enumerations.
"""
@staticmethod
def live_channel_for_resource(channel: str):
"""
Returns the channel enum for a given channel string.
"""
if not channel: return None
channel = "linein_" + channel.split("line://")[1]
if channel == Channel.LIVE_0.value:
return Channel.LIVE_0
elif channel == Channel.LIVE_1.value:
return Channel.LIVE_2
elif channel == Channel.LIVE_3.value:
return Channel.LIVE_3
elif channel == Channel.LIVE_4.value:
return Channel.LIVE_4
elif channel == Channel.LIVE_5.value:
return Channel.LIVE_5
else:
return None
class ChannelType(Enum): class ChannelType(Enum):
""" """
Engine channel types mapped to `Entry` source types. Engine channel types mapped to `Entry` source types.
...@@ -77,7 +104,7 @@ class ChannelType(Enum): ...@@ -77,7 +104,7 @@ class ChannelType(Enum):
"id": "live", "id": "live",
"numeric": 3, "numeric": 3,
"channels": [ "channels": [
Channel.LIVE_0, Channel.LIVE_0,
Channel.LIVE_1, Channel.LIVE_1,
Channel.LIVE_2, Channel.LIVE_2,
Channel.LIVE_3, Channel.LIVE_3,
...@@ -88,7 +115,7 @@ class ChannelType(Enum): ...@@ -88,7 +115,7 @@ class ChannelType(Enum):
"id": "fallback_queue", "id": "fallback_queue",
"numeric": 4, "numeric": 4,
"channels": [Channel.FALLBACK_QUEUE_A, Channel.FALLBACK_QUEUE_B] "channels": [Channel.FALLBACK_QUEUE_A, Channel.FALLBACK_QUEUE_B]
} }
FALLBACK_POOL = { FALLBACK_POOL = {
"id": "fallback_pool", "id": "fallback_pool",
"numeric": 5, "numeric": 5,
...@@ -119,7 +146,7 @@ class LiquidsoapResponse(Enum): ...@@ -119,7 +146,7 @@ class LiquidsoapResponse(Enum):
STREAM_STATUS_POLLING = "polling" STREAM_STATUS_POLLING = "polling"
STREAM_STATUS_STOPPED = "stopped" STREAM_STATUS_STOPPED = "stopped"
STREAM_STATUS_CONNECTED = "connected" STREAM_STATUS_CONNECTED = "connected"
class ChannelRouter(): class ChannelRouter():
...@@ -142,7 +169,7 @@ class ChannelRouter(): ...@@ -142,7 +169,7 @@ class ChannelRouter():
""" """
self.config = config self.config = config
self.logger = logger self.logger = logger
self.resource_mapping = { self.resource_mapping = {
ResourceType.FILE: ChannelType.QUEUE, ResourceType.FILE: ChannelType.QUEUE,
ResourceType.STREAM_HTTP: ChannelType.HTTP, ResourceType.STREAM_HTTP: ChannelType.HTTP,
...@@ -159,8 +186,8 @@ class ChannelRouter(): ...@@ -159,8 +186,8 @@ class ChannelRouter():
ChannelType.HTTPS: Channel.HTTPS_A, ChannelType.HTTPS: Channel.HTTPS_A,
ChannelType.LIVE: Channel.LIVE_0 ChannelType.LIVE: Channel.LIVE_0
} }
def set_active(self, channel_type, channel): def set_active(self, channel_type, channel):
""" """
Set the channel for the given resource type active Set the channel for the given resource type active
...@@ -177,7 +204,7 @@ class ChannelRouter(): ...@@ -177,7 +204,7 @@ class ChannelRouter():
def type_of_channel(self, channel): def type_of_channel(self, channel):
""" """
Retrieves a `ChannelType` for the given `Channel`. Retrieves a `ChannelType` for the given `Channel`.
""" """
if channel in ChannelType.QUEUE.channels: if channel in ChannelType.QUEUE.channels:
return ChannelType.QUEUE return ChannelType.QUEUE
...@@ -198,7 +225,7 @@ class ChannelRouter(): ...@@ -198,7 +225,7 @@ class ChannelRouter():
Retrieves a `ChannelType` for the given `ResourceType`. Retrieves a `ChannelType` for the given `ResourceType`.
Only default mappings can be evaluatated. Custom variations Only default mappings can be evaluatated. Custom variations
like fallback channels are not respected. like fallback channels are not respected.
""" """
return self.resource_mapping.get(resource_type) return self.resource_mapping.get(resource_type)
...@@ -254,7 +281,7 @@ class ChannelRouter(): ...@@ -254,7 +281,7 @@ class ChannelRouter():
else: else:
new_channel = Channel.HTTPS_A new_channel = Channel.HTTPS_A
msg = "Swapped HTTPS Stream channel from B > A" msg = "Swapped HTTPS Stream channel from B > A"
else: else:
self.logger.warning(SU.red(f"No channel to swap - invalid entry_type '{channel_type}'")) self.logger.warning(SU.red(f"No channel to swap - invalid entry_type '{channel_type}'"))
......
...@@ -29,7 +29,7 @@ from src.base.config import AuraConfig ...@@ -29,7 +29,7 @@ from src.base.config import AuraConfig
from src.base.utils import SimpleUtil as SU from src.base.utils import SimpleUtil as SU
from src.base.exceptions import LQConnectionError, InvalidChannelException, LQStreamException, LoadSourceException from src.base.exceptions import LQConnectionError, InvalidChannelException, LQStreamException, LoadSourceException
from src.resources import ResourceClass, ResourceUtil from src.resources import ResourceClass, ResourceUtil
from src.channels import ChannelType, TransitionType, LiquidsoapResponse, EntryPlayState, ResourceType, ChannelRouter from src.channels import ChannelType, TransitionType, LiquidsoapResponse, EntryPlayState, ResourceType, ChannelRouter, ChannelResolver
from src.events import EngineEventDispatcher from src.events import EngineEventDispatcher
from src.control import EngineControlInterface from src.control import EngineControlInterface
from src.mixer import Mixer, MixerType from src.mixer import Mixer, MixerType
...@@ -229,7 +229,10 @@ class Player: ...@@ -229,7 +229,10 @@ class Player:
# LIVE # LIVE
if entry.get_content_type() in ResourceClass.LIVE.types: if entry.get_content_type() in ResourceClass.LIVE.types:
entry.channel = "linein_" + entry.source.split("line://")[1] entry.channel = ChannelResolver.live_channel_for_resource(entry.source)
if entry.channel == None:
self.logger.critical(SU.red("Invalid live channel '{entry.source}' requested!"))
entry.previous_channel = None
is_ready = True is_ready = True
else: else:
channel_type = self.channel_router.type_for_resource(entry.get_content_type()) channel_type = self.channel_router.type_for_resource(entry.get_content_type())
......
...@@ -24,7 +24,7 @@ from enum import Enum ...@@ -24,7 +24,7 @@ from enum import Enum
class ResourceType(Enum): class ResourceType(Enum):
""" """
Media content types. Media content types.
""" """
FILE = "file:" FILE = "file:"
STREAM_HTTP = "http:" STREAM_HTTP = "http:"
STREAM_HTTPS = "https:" STREAM_HTTPS = "https:"
...@@ -135,7 +135,7 @@ class ResourceUtil(Enum): ...@@ -135,7 +135,7 @@ class ResourceUtil(Enum):
file = open(target_file, "w") file = open(target_file, "w")
fb = [ "#EXTM3U" ] fb = [ "#EXTM3U" ]
for entry in entries: for entry in entries:
if ResourceUtil.get_content_type(entry.source) == ResourceType.FILE: if ResourceUtil.get_content_type(entry.source) == ResourceType.FILE:
path = ResourceUtil.source_to_filepath(audio_store_path, entry.source, entry_extension) path = ResourceUtil.source_to_filepath(audio_store_path, entry.source, entry_extension)
fb.append(f"#EXTINF:{entry.duration},{entry.meta_data.artist} - {entry.meta_data.title}") fb.append(f"#EXTINF:{entry.duration},{entry.meta_data.artist} - {entry.meta_data.title}")
...@@ -148,7 +148,7 @@ class ResourceUtil(Enum): ...@@ -148,7 +148,7 @@ class ResourceUtil(Enum):
@staticmethod @staticmethod
def source_to_filepath(base_dir, source, source_extension): def source_to_filepath(base_dir, source, source_extension):
""" """
Converts a file-system URI starting with "file://" to an actual, Converts a file-system URI starting with "file://" to an actual,
absolute path to the file, appending the extension as provided absolute path to the file, appending the extension as provided
in "source_extension". in "source_extension".
...@@ -166,7 +166,7 @@ class ResourceUtil(Enum): ...@@ -166,7 +166,7 @@ class ResourceUtil(Enum):
path = source[7:] path = source[7:]
if path.startswith("/"): if path.startswith("/"):
return path return path
else: else:
return base_dir + "/" + path + source_extension return base_dir + "/" + path + source_extension
...@@ -193,10 +193,10 @@ class ResourceUtil(Enum): ...@@ -193,10 +193,10 @@ class ResourceUtil(Enum):
Args: Args:
uri (String): The path to the audio source uri (String): The path to the audio source
cue_in (Float): The value in seconds wher the cue in should start cue_in (Float): The value in seconds wher the cue in should start
Returns: Returns:
(String): The annotated URI (String): The annotated URI
""" """
if cue_in > 0.0: if cue_in > 0.0:
uri = "annotate:liq_cue_in=\"%s\":%s" % (str(cue_in), uri) uri = "annotate:liq_cue_in=\"%s\":%s" % (str(cue_in), uri)
return uri return uri
\ No newline at end of file \ No newline at end of file
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment