You've already forked RadioPlayer
mirror of
https://github.com/radio95-rnt/RadioPlayer.git
synced 2026-02-26 21:53:54 +01:00
module callbacks in the future?
This commit is contained in:
@@ -26,7 +26,7 @@ class PlayerModule:
|
|||||||
Receive an IMC object
|
Receive an IMC object
|
||||||
"""
|
"""
|
||||||
pass
|
pass
|
||||||
def imc_data(self, source: 'PlayerModule | ActiveModifier | PlaylistAdvisor', data: object) -> object:
|
def imc_data(self, source: 'PlayerModule | ActiveModifier | PlaylistAdvisor', data: object, broadcast: bool) -> object:
|
||||||
pass
|
pass
|
||||||
class PlaylistModifierModule:
|
class PlaylistModifierModule:
|
||||||
"""
|
"""
|
||||||
@@ -57,7 +57,7 @@ class PlaylistAdvisor:
|
|||||||
Receive an IMC object
|
Receive an IMC object
|
||||||
"""
|
"""
|
||||||
pass
|
pass
|
||||||
def imc_data(self, source: 'PlayerModule | ActiveModifier | PlaylistAdvisor', data: object) -> object:
|
def imc_data(self, source: 'PlayerModule | ActiveModifier | PlaylistAdvisor', data: object, broadcast: bool) -> object:
|
||||||
pass
|
pass
|
||||||
class ActiveModifier:
|
class ActiveModifier:
|
||||||
"""
|
"""
|
||||||
@@ -84,7 +84,7 @@ class ActiveModifier:
|
|||||||
Receive an IMC object
|
Receive an IMC object
|
||||||
"""
|
"""
|
||||||
pass
|
pass
|
||||||
def imc_data(self, source: 'PlayerModule | ActiveModifier | PlaylistAdvisor', data: object) -> object:
|
def imc_data(self, source: 'PlayerModule | ActiveModifier | PlaylistAdvisor', data: object, broadcast: bool) -> object:
|
||||||
pass
|
pass
|
||||||
class InterModuleCommunication:
|
class InterModuleCommunication:
|
||||||
def __init__(self, advisor: PlaylistAdvisor, active_modifier: ActiveModifier | None, simple_modules: list[PlayerModule]) -> None:
|
def __init__(self, advisor: PlaylistAdvisor, active_modifier: ActiveModifier | None, simple_modules: list[PlayerModule]) -> None:
|
||||||
@@ -94,15 +94,15 @@ class InterModuleCommunication:
|
|||||||
self.names_modules: dict[str, PlaylistAdvisor | ActiveModifier | PlayerModule] = {}
|
self.names_modules: dict[str, PlaylistAdvisor | ActiveModifier | PlayerModule] = {}
|
||||||
def broadcast(self, source: PlaylistAdvisor | ActiveModifier | PlayerModule, data: object) -> None:
|
def broadcast(self, source: PlaylistAdvisor | ActiveModifier | PlayerModule, data: object) -> None:
|
||||||
"""
|
"""
|
||||||
Send data to all modules
|
Send data to all modules, other than ourself
|
||||||
"""
|
"""
|
||||||
self.advisor.imc_data(source, data)
|
if source is not self.advisor: self.advisor.imc_data(source, data, True)
|
||||||
if self.active_modifier: self.active_modifier.imc_data(source, data)
|
if self.active_modifier and source is not self.active_modifier: self.active_modifier.imc_data(source, data, True)
|
||||||
for module in self.simple_modules: module.imc_data(source, data)
|
for module in [f for f in self.simple_modules if f is not source]: module.imc_data(source, data, True)
|
||||||
def register(self, module: PlaylistAdvisor | ActiveModifier | PlayerModule, name: str):
|
def register(self, module: PlaylistAdvisor | ActiveModifier | PlayerModule, name: str):
|
||||||
if name in self.names_modules.keys(): return False
|
if name in self.names_modules.keys(): return False
|
||||||
self.names_modules[name] = module
|
self.names_modules[name] = module
|
||||||
return True
|
return True
|
||||||
def send(self, source: PlaylistAdvisor | ActiveModifier | PlayerModule, name: str, data: object) -> object:
|
def send(self, source: PlaylistAdvisor | ActiveModifier | PlayerModule, name: str, data: object) -> object:
|
||||||
if not name in self.names_modules.keys(): raise Exception
|
if not name in self.names_modules.keys(): raise Exception
|
||||||
return self.names_modules[name].imc_data(source, data)
|
return self.names_modules[name].imc_data(source, data, False)
|
||||||
@@ -110,7 +110,7 @@ class Module(PlaylistAdvisor):
|
|||||||
def imc(self, imc: InterModuleCommunication):
|
def imc(self, imc: InterModuleCommunication):
|
||||||
self.class_imc = imc
|
self.class_imc = imc
|
||||||
imc.register(self, "advisor")
|
imc.register(self, "advisor")
|
||||||
def imc_data(self, source: PlayerModule | ActiveModifier | PlaylistAdvisor, data: object):
|
def imc_data(self, source: PlayerModule | ActiveModifier | PlaylistAdvisor, data: object, broadcast: bool):
|
||||||
return self.custom_playlist
|
return self.custom_playlist
|
||||||
|
|
||||||
advisor = Module()
|
advisor = Module()
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
Modules in the radio95 radio player are quite simple.
|
Modules in the radioPlayer are quite simple.
|
||||||
|
|
||||||
First of all, ther are in total only 4 modules:
|
First of all, ther are in total only 4 modules:
|
||||||
- Observer (PlayerModule), this module is a passive observer, you can use this as a status api or to send the song metadata to your RDS encoder
|
- Observer (PlayerModule), this module is a passive observer, you can use this as a status api or to send the song metadata to your RDS encoder
|
||||||
@@ -32,7 +32,7 @@ class PlayerModule:
|
|||||||
Receive an IMC object
|
Receive an IMC object
|
||||||
"""
|
"""
|
||||||
pass
|
pass
|
||||||
def imc_data(self, source: 'PlayerModule | ActiveModifier | PlaylistAdvisor', data: object) -> object:
|
def imc_data(self, source: 'PlayerModule | ActiveModifier | PlaylistAdvisor', data: object, broadcast: bool) -> object:
|
||||||
pass
|
pass
|
||||||
class PlaylistModifierModule:
|
class PlaylistModifierModule:
|
||||||
"""
|
"""
|
||||||
@@ -63,7 +63,7 @@ class PlaylistAdvisor:
|
|||||||
Receive an IMC object
|
Receive an IMC object
|
||||||
"""
|
"""
|
||||||
pass
|
pass
|
||||||
def imc_data(self, source: 'PlayerModule | ActiveModifier | PlaylistAdvisor', data: object) -> object:
|
def imc_data(self, source: 'PlayerModule | ActiveModifier | PlaylistAdvisor', data: object, broadcast: bool) -> object:
|
||||||
pass
|
pass
|
||||||
class ActiveModifier:
|
class ActiveModifier:
|
||||||
"""
|
"""
|
||||||
@@ -90,7 +90,7 @@ class ActiveModifier:
|
|||||||
Receive an IMC object
|
Receive an IMC object
|
||||||
"""
|
"""
|
||||||
pass
|
pass
|
||||||
def imc_data(self, source: 'PlayerModule | ActiveModifier | PlaylistAdvisor', data: object) -> object:
|
def imc_data(self, source: 'PlayerModule | ActiveModifier | PlaylistAdvisor', data: object, broadcast: bool) -> object:
|
||||||
pass
|
pass
|
||||||
class InterModuleCommunication:
|
class InterModuleCommunication:
|
||||||
def __init__(self, advisor: PlaylistAdvisor, active_modifier: ActiveModifier | None, simple_modules: list[PlayerModule]) -> None:
|
def __init__(self, advisor: PlaylistAdvisor, active_modifier: ActiveModifier | None, simple_modules: list[PlayerModule]) -> None:
|
||||||
@@ -100,18 +100,18 @@ class InterModuleCommunication:
|
|||||||
self.names_modules: dict[str, PlaylistAdvisor | ActiveModifier | PlayerModule] = {}
|
self.names_modules: dict[str, PlaylistAdvisor | ActiveModifier | PlayerModule] = {}
|
||||||
def broadcast(self, source: PlaylistAdvisor | ActiveModifier | PlayerModule, data: object) -> None:
|
def broadcast(self, source: PlaylistAdvisor | ActiveModifier | PlayerModule, data: object) -> None:
|
||||||
"""
|
"""
|
||||||
Send data to all modules
|
Send data to all modules, other than ourself
|
||||||
"""
|
"""
|
||||||
self.advisor.imc_data(source, data)
|
if source is not self.advisor: self.advisor.imc_data(source, data, True)
|
||||||
if self.active_modifier: self.active_modifier.imc_data(source, data)
|
if self.active_modifier and source is not self.active_modifier: self.active_modifier.imc_data(source, data, True)
|
||||||
for module in self.simple_modules: module.imc_data(source, data)
|
for module in [f for f in self.simple_modules if f is not source]: module.imc_data(source, data, True)
|
||||||
def register(self, module: PlaylistAdvisor | ActiveModifier | PlayerModule, name: str):
|
def register(self, module: PlaylistAdvisor | ActiveModifier | PlayerModule, name: str):
|
||||||
if name in self.names_modules.keys(): return False
|
if name in self.names_modules.keys(): return False
|
||||||
self.names_modules[name] = module
|
self.names_modules[name] = module
|
||||||
return True
|
return True
|
||||||
def send(self, source: PlaylistAdvisor | ActiveModifier | PlayerModule, name: str, data: object) -> object:
|
def send(self, source: PlaylistAdvisor | ActiveModifier | PlayerModule, name: str, data: object) -> object:
|
||||||
if not name in self.names_modules.keys(): raise Exception
|
if not name in self.names_modules.keys(): raise Exception
|
||||||
return self.names_modules[name].imc_data(source, data)
|
return self.names_modules[name].imc_data(source, data, False)
|
||||||
```
|
```
|
||||||
|
|
||||||
Each module shall have a python script in the modules directory. Each of the modules need to define one or more global variables in order to be seen by the core:
|
Each module shall have a python script in the modules directory. Each of the modules need to define one or more global variables in order to be seen by the core:
|
||||||
|
|||||||
@@ -15,28 +15,6 @@ active_modifier: ActiveModifier | None = None
|
|||||||
MODULES_PACKAGE = "modules"
|
MODULES_PACKAGE = "modules"
|
||||||
MODULES_DIR = (Path(__file__).resolve().parent / MODULES_PACKAGE).resolve()
|
MODULES_DIR = (Path(__file__).resolve().parent / MODULES_PACKAGE).resolve()
|
||||||
|
|
||||||
def print_wait(ttw: float, frequency: float, duration: float=-1, prefix: str="", bias: float = 0):
|
|
||||||
interval = 1.0 / frequency
|
|
||||||
elapsed = 0.0
|
|
||||||
if duration == -1: duration = ttw
|
|
||||||
|
|
||||||
def format_time(seconds):
|
|
||||||
hours = int(seconds // 3600)
|
|
||||||
minutes = int((seconds % 3600) // 60)
|
|
||||||
secs = int(seconds % 60)
|
|
||||||
return f"{hours:02d}:{minutes:02d}:{secs:02d}"
|
|
||||||
|
|
||||||
try:
|
|
||||||
while elapsed < ttw:
|
|
||||||
print(f"{prefix}{format_time(elapsed+bias)} / {format_time(duration)}", end="\r", flush=True)
|
|
||||||
time.sleep(interval)
|
|
||||||
elapsed += interval
|
|
||||||
except Exception:
|
|
||||||
print()
|
|
||||||
raise
|
|
||||||
|
|
||||||
print(f"{prefix}{format_time(ttw+bias)} / {format_time(duration)}")
|
|
||||||
|
|
||||||
logger_level = log95.log95Levels.DEBUG if DEBUG else log95.log95Levels.CRITICAL_ERROR
|
logger_level = log95.log95Levels.DEBUG if DEBUG else log95.log95Levels.CRITICAL_ERROR
|
||||||
logger = log95.log95("radioPlayer", logger_level)
|
logger = log95.log95("radioPlayer", logger_level)
|
||||||
|
|
||||||
@@ -228,8 +206,28 @@ def play_playlist(playlist_path):
|
|||||||
ttw = pr.duration
|
ttw = pr.duration
|
||||||
if track.fade_out: ttw -= cross_fade
|
if track.fade_out: ttw -= cross_fade
|
||||||
|
|
||||||
if track.official: print_wait(ttw, 1, pr.duration, f"{track_name}: ")
|
end_time = time.time() + ttw
|
||||||
else: time.sleep(ttw)
|
loop_start = time.time() # Outside the loop
|
||||||
|
|
||||||
|
def format_time(seconds):
|
||||||
|
hours = int(seconds // 3600)
|
||||||
|
minutes = int((seconds % 3600) // 60)
|
||||||
|
secs = int(seconds % 60)
|
||||||
|
return f"{hours:02d}:{minutes:02d}:{secs:02d}"
|
||||||
|
|
||||||
|
while end_time >= time.time():
|
||||||
|
start = time.time()
|
||||||
|
# do some module callback
|
||||||
|
|
||||||
|
elapsed = time.time() - start
|
||||||
|
remaining_until_end = end_time - time.time()
|
||||||
|
total_uptime = time.time() - loop_start
|
||||||
|
|
||||||
|
if track.official: print(f"{track_name}: {format_time(total_uptime)} / {format_time(pr.duration)}")
|
||||||
|
|
||||||
|
if elapsed < 1 and remaining_until_end > 0:
|
||||||
|
sleep_duration = min(1 - elapsed, remaining_until_end)
|
||||||
|
time.sleep(sleep_duration)
|
||||||
|
|
||||||
i += 1
|
i += 1
|
||||||
if not extend: song_i += 1
|
if not extend: song_i += 1
|
||||||
|
|||||||
Reference in New Issue
Block a user