0
1
mirror of https://github.com/radio95-rnt/RadioPlayer.git synced 2026-02-27 06:03:52 +01:00

multiple technical changes

This commit is contained in:
Kuba
2025-11-01 22:28:06 +01:00
parent 47c78c6efe
commit 09fd00bf68
3 changed files with 25 additions and 23 deletions

View File

@@ -29,7 +29,10 @@ class PlayerModule:
pass pass
def imc_data(self, source: 'PlayerModule | ActiveModifier | PlaylistAdvisor', data: object, broadcast: bool) -> object: def imc_data(self, source: 'PlayerModule | ActiveModifier | PlaylistAdvisor', data: object, broadcast: bool) -> object:
return None return None
def progress(self, index: int, track: Track, elapsed: float, total: float): def progress(self, index: int, track: Track, elapsed: float, total: float, real_total: float):
"""
Real total and total differ in that, total is how much the track lasts, but real_total will be for how long we will play it for
"""
pass pass
class PlaylistModifierModule: class PlaylistModifierModule:
""" """
@@ -45,7 +48,7 @@ class PlaylistAdvisor:
""" """
Only one of a playlist advisor can be loaded. This module picks the playlist file to play, this can be a scheduler or just a static file Only one of a playlist advisor can be loaded. This module picks the playlist file to play, this can be a scheduler or just a static file
""" """
def advise(self, arguments: str | None) -> str: def advise(self, arguments: str | None) -> str | None:
""" """
Arguments are the arguments passed to the program on startup Arguments are the arguments passed to the program on startup
""" """

View File

@@ -49,7 +49,7 @@ class PlaylistAdvisor:
""" """
Only one of a playlist advisor can be loaded. This module picks the playlist file to play, this can be a scheduler or just a static file Only one of a playlist advisor can be loaded. This module picks the playlist file to play, this can be a scheduler or just a static file
""" """
def advise(self, arguments: str | None) -> str: def advise(self, arguments: str | None) -> str | None:
""" """
Arguments are the arguments passed to the program on startup Arguments are the arguments passed to the program on startup
""" """

View File

@@ -33,14 +33,14 @@ class ProcessManager:
def __init__(self) -> None: def __init__(self) -> None:
self.lock = threading.Lock() self.lock = threading.Lock()
self.processes: list[Process] = [] self.processes: list[Process] = []
self.duration_cache = libcache.Cache() self.duration_cache = libcache.Cache([])
def _get_audio_duration(self, file_path): def _get_audio_duration(self, file_path):
if result := self.duration_cache.getElement(file_path, False): return result if result := self.duration_cache.getElement(file_path, False): return result
result = subprocess.run(['ffprobe', '-v', 'quiet', '-show_entries', 'format=duration', '-of', 'default=noprint_wrappers=1:nokey=1', file_path], capture_output=True, text=True) result = subprocess.run(['ffprobe', '-v', 'quiet', '-show_entries', 'format=duration', '-of', 'default=noprint_wrappers=1:nokey=1', file_path], capture_output=True, text=True)
if result.returncode == 0: if result.returncode == 0:
result = float(result.stdout.strip()) result = float(result.stdout.strip())
self.duration_cache.saveElement(file_path, result, (60*60)) self.duration_cache.saveElement(file_path, result, (60*60), False, True)
return result return result
return None return None
def play(self, track_path: str, fade_in: bool=False, fade_out: bool=False, fade_time: int=5, offset: float=0.0) -> Process: def play(self, track_path: str, fade_in: bool=False, fade_out: bool=False, fade_time: int=5, offset: float=0.0) -> Process:
@@ -55,10 +55,11 @@ class ProcessManager:
if fade_in: filters.append(f"afade=t=in:st=0:d={fade_time}") if fade_in: filters.append(f"afade=t=in:st=0:d={fade_time}")
if fade_out: filters.append(f"afade=t=out:st={duration - fade_time - offset}:d={fade_time}") if fade_out: filters.append(f"afade=t=out:st={duration - fade_time - offset}:d={fade_time}")
if filters: cmd.extend(['-af', ",".join(filters)]) if filters: cmd.extend(['-af', ",".join(filters)])
cmd.append(track_path) cmd.append(track_path)
proc = subprocess.Popen(cmd, stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL, start_new_session=True) proc = subprocess.Popen(cmd, stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL, start_new_session=True)
pr = Process(proc, track_path, time.time(), duration - offset) pr = Process(proc, track_path, time.monotonic(), duration - offset)
with self.lock: self.processes.append(pr) with self.lock: self.processes.append(pr)
return pr return pr
def anything_playing(self) -> bool: def anything_playing(self) -> bool:
@@ -85,8 +86,8 @@ def handle_sigint(signum, frame):
global exit_pending, intr_time global exit_pending, intr_time
with exit_lock: with exit_lock:
logger.info("Received SIGINT") logger.info("Received SIGINT")
if (time.time() - intr_time) > 5: if (time.monotonic() - intr_time) > 5:
intr_time = time.time() intr_time = time.monotonic()
logger.info("Will quit on song end.") logger.info("Will quit on song end.")
exit_pending = True exit_pending = True
else: else:
@@ -209,17 +210,16 @@ 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
end_time = time.time() + ttw loop_start = time.monotonic()
loop_start = time.time() # Outside the loop end_time = loop_start + ttw
while end_time >= time.time(): while end_time >= time.monotonic():
start = time.time() start = time.monotonic()
total_uptime = time.time() - loop_start for module in simple_modules: module.progress(song_i, track, time.monotonic() - loop_start, pr.duration, ttw)
for module in simple_modules: module.progress(song_i, track, total_uptime, pr.duration)
elapsed = time.time() - start elapsed = time.monotonic() - start
remaining_until_end = end_time - time.time() remaining_until_end = end_time - time.monotonic()
if elapsed < 1 and remaining_until_end > 0: if elapsed < 1 and remaining_until_end > 0:
sleep_duration = min(1 - elapsed, remaining_until_end) sleep_duration = min(1 - elapsed, remaining_until_end)
@@ -296,7 +296,6 @@ def main():
play_playlist(playlist) play_playlist(playlist)
if exit_pending: exit() if exit_pending: exit()
except Exception as e: except Exception as e:
logger.error(f"Unexpected error: {e}") logger.critical_error(f"Unexpected error: {e}")
procman.stop_all()
raise raise
finally: procman.stop_all() finally: procman.stop_all()