From 8d80719f6bf28bada10762e2e1559dfc672100b1 Mon Sep 17 00:00:00 2001 From: KDalu <71458929+KDalu@users.noreply.github.com> Date: Tue, 21 Jan 2025 21:34:05 -0500 Subject: [PATCH] Added download real time feature back. --- zotify/app.py | 2 +- zotify/playable.py | 34 ++++++++++++++++++++++++++++++++++ 2 files changed, 35 insertions(+), 1 deletion(-) diff --git a/zotify/app.py b/zotify/app.py index d91fda1..3ef8e2d 100644 --- a/zotify/app.py +++ b/zotify/app.py @@ -283,7 +283,7 @@ class App: desc=f"({count}/{total}) {track.name}", total=track.input_stream.size, ) as p_bar: - file = track.write_audio_stream(output, p_bar) + file = track.write_audio_stream(output, p_bar, self.__config.download_real_time) # Download lyrics if playable.type == PlayableType.TRACK and self.__config.lyrics_file: diff --git a/zotify/playable.py b/zotify/playable.py index e2b5687..425baa3 100644 --- a/zotify/playable.py +++ b/zotify/playable.py @@ -1,5 +1,6 @@ from math import floor from pathlib import Path +from time import time, sleep from librespot.core import PlayableContentFeeder from librespot.metadata import AlbumId @@ -197,6 +198,39 @@ class Track(PlayableContentFeeder.LoadedStream, Playable): ) return self.__lyrics + def write_audio_stream( + self, + output: Path | str, + p_bar: tqdm = tqdm(disable=True), + real_time: bool = False, + ) -> LocalFile: + """ + Writes audio stream to file + Args: + output: File path of saved audio stream + p_bar: tqdm progress bar + real_time: Enable delay to emulate real time streaming + Returns: + LocalFile object + """ + if not isinstance(output, Path): + output = Path(output).expanduser() + file = f"{output}.ogg" + time_start = time() + downloaded = 0 + with open(file, "wb") as f, p_bar as p_bar: + chunk = None + while chunk != b"": + chunk = self.input_stream.stream().read(1024) + p_bar.update(f.write(chunk)) + if real_time: + downloaded += len(chunk) + delta_current = time() - time_start + delta_required = (downloaded / self.input_stream.size) * (self.duration/1000) + if delta_required > delta_current: + sleep(delta_required - delta_current) + return LocalFile(Path(file), AudioFormat.VORBIS) + class Episode(PlayableContentFeeder.LoadedStream, Playable): def __init__(self, episode: PlayableContentFeeder.LoadedStream, api):