diff --git a/app/dl_formats.py b/app/dl_formats.py index 5640ca4..5147451 100644 --- a/app/dl_formats.py +++ b/app/dl_formats.py @@ -28,7 +28,9 @@ def get_format(format: str, quality: str) -> str: if format in AUDIO_FORMATS: # Audio quality needs to be set post-download, set in opts - return f"bestaudio[ext={format}]/bestaudio/best" + # Use a more robust format string that ensures audio-only download + # and has better fallbacks + return f"bestaudio[ext={format}]/bestaudio[ext=m4a]/bestaudio[ext=mp3]/bestaudio/best[ext!=webm]/best[ext!=webm]" if format in ("mp4", "any"): if quality == "audio": diff --git a/app/ytdl.py b/app/ytdl.py index d4955f3..c8404a9 100644 --- a/app/ytdl.py +++ b/app/ytdl.py @@ -96,7 +96,7 @@ class Download: 'outtmpl': { "default": self.output_template, "chapter": self.output_template_chapter }, 'format': self.format, 'socket_timeout': 30, - 'ignore_no_formats_error': True, + 'ignore_no_formats_error': False, # Changed to False to get better error messages 'progress_hooks': [put_status], 'postprocessor_hooks': [put_status_postprocessor], **self.ytdl_opts, @@ -235,7 +235,7 @@ class DownloadQueue: self.seq_lock = asyncio.Lock() elif self.config.DOWNLOAD_MODE == 'limited': self.semaphore = asyncio.Semaphore(int(self.config.MAX_CONCURRENT_DOWNLOADS)) - + self.done.load() async def __import_queue(self): @@ -301,6 +301,13 @@ class DownloadQueue: 'ignore_no_formats_error': True, 'noplaylist': playlist_strict_mode, 'paths': {"home": self.config.DOWNLOAD_DIR, "temp": self.config.TEMP_DIR}, + 'cookiefile': None, # Allow cookie usage if available + 'age_limit': None, # Don't restrict by age + 'geo_bypass': True, # Attempt to bypass geographic restrictions + 'geo_bypass_country': None, # Let yt-dlp choose the best bypass method + 'extractor_retries': 3, # Retry extraction up to 3 times + 'youtube_include_dash_manifest': True, # Include DASH formats for YouTube Music + 'youtube_skip_dash_manifest': False, # Don't skip DASH manifest **self.config.YTDL_OPTIONS, **({'impersonate': yt_dlp.networking.impersonate.ImpersonateTarget.from_str(self.config.YTDL_OPTIONS['impersonate'])} if 'impersonate' in self.config.YTDL_OPTIONS else {}), }).extract_info(url, download=False)