From 2495c77d3ccd7653ab8d46df9fde6059a2ba7bd4 Mon Sep 17 00:00:00 2001 From: oop7 <110548351+oop7@users.noreply.github.com> Date: Thu, 9 Apr 2026 18:27:14 +0200 Subject: [PATCH] Support concurrent fragments and emit finished Add a concurrent_fragments parameter to DownloadThread (default 1) and store it as an instance attribute. When building the yt-dlp command, include a -N option and log the concurrent connections. Also emit finished_signal upon cancellation and on error paths to ensure the UI is notified of thread completion. Minor comment/logging clarifications added around command construction. --- ytsage/core/ytsage_downloader.py | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/ytsage/core/ytsage_downloader.py b/ytsage/core/ytsage_downloader.py index a66d9a0..ed545b2 100644 --- a/ytsage/core/ytsage_downloader.py +++ b/ytsage/core/ytsage_downloader.py @@ -74,6 +74,7 @@ class DownloadThread(QThread): preferred_audio_format="best", audio_normalization=False, filename_format=None, + concurrent_fragments=1, ) -> None: super().__init__() self.url = url @@ -103,6 +104,7 @@ class DownloadThread(QThread): self.preferred_audio_format = preferred_audio_format self.audio_normalization = audio_normalization self.filename_format = filename_format + self.concurrent_fragments = concurrent_fragments self.paused: bool = False self.cancelled: bool = False self.process: Optional[subprocess.Popen] = None @@ -229,11 +231,16 @@ class DownloadThread(QThread): def _build_yt_dlp_command(self) -> List[str]: """Build the yt-dlp command line with all options for direct execution.""" - # Use the new yt-dlp path function from ytsage_yt_dlp module yt_dlp_path: str = get_yt_dlp_path() + # Build the command line array cmd: List[str] = [yt_dlp_path] logger.debug(f"Using yt-dlp from: {yt_dlp_path}") + # Add concurrent fragments setting + if self.concurrent_fragments: + cmd.extend(["-N", str(self.concurrent_fragments)]) + logger.debug(f"Using {self.concurrent_fragments} concurrent connections") + # Format selection strategy - use format ID if provided or fallback to resolution if self.format_id: clean_format_id: str = self.format_id.split("-drc")[0] if "-drc" in self.format_id else self.format_id @@ -447,6 +454,7 @@ class DownloadThread(QThread): time.sleep(2) self.cleanup_partial_files() self.status_signal.emit(_("download.cancelled")) + self.finished_signal.emit() return # Wait if paused @@ -532,6 +540,7 @@ class DownloadThread(QThread): # Check if it was cancelled if self.cancelled: self.status_signal.emit(_("download.cancelled")) + self.finished_signal.emit() else: # Provide informative error message based on captured output if self.error_lines: