You've already forked RadioPlayer
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:
@@ -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
|
||||||
"""
|
"""
|
||||||
|
|||||||
@@ -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
|
||||||
"""
|
"""
|
||||||
|
|||||||
@@ -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()
|
||||||
|
|||||||
Reference in New Issue
Block a user