Skip to content
GitLab
Menu
Projects
Groups
Snippets
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
Menu
Open sidebar
Lars Kruse
aura-engine
Commits
f593acdd
Commit
f593acdd
authored
Jul 08, 2021
by
david
Browse files
Fix for live channel selection. #81
parent
e7ca792f
Changes
3
Hide whitespace changes
Inline
Side-by-side
src/channels.py
View file @
f593acdd
...
@@ -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
}
'"
))
...
...
src/engine.py
View file @
f593acdd
...
@@ -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
())
...
...
src/resources.py
View file @
f593acdd
...
@@ -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
Write
Preview
Supports
Markdown
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment