diff --git a/app/youtube_downloader.py b/app/youtube_downloader.py index e4977f2..e7466d3 100644 --- a/app/youtube_downloader.py +++ b/app/youtube_downloader.py @@ -209,12 +209,12 @@ async def download_and_convert( 'bestaudio/best', ] - async def _run_yt_dlp(format_selector: str, use_player_client: bool): + async def _run_yt_dlp(format_selector: str, use_player_client: bool, hls_prefer_native: bool): cmd = [ 'yt-dlp', '-x', # Извлечь аудио '-f', format_selector, - '--hls-prefer-ffmpeg', + '--hls-prefer-native' if hls_prefer_native else '--hls-prefer-ffmpeg', '--audio-format', 'mp3', '--audio-quality', '0', # Лучшее качество '-o', str(temp_template), @@ -269,13 +269,13 @@ async def download_and_convert( last_tail: list[str] = [] attempts = [] for fmt in formats_to_try: - attempts.append((fmt, True)) + attempts.append((fmt, True, False)) # prefer ffmpeg for HLS by default if config and config.ytdlp_player_client: for fmt in formats_to_try: - attempts.append((fmt, False)) + attempts.append((fmt, False, False)) - for fmt, use_player_client in attempts: - returncode, tail_lines = await _run_yt_dlp(fmt, use_player_client) + for fmt, use_player_client, hls_prefer_native in attempts: + returncode, tail_lines = await _run_yt_dlp(fmt, use_player_client, hls_prefer_native) last_tail = tail_lines if returncode == 0: break @@ -283,6 +283,13 @@ async def download_and_convert( if "Requested format is not available" in tail_text: logger.warning("yt-dlp format unavailable, retrying with fallback") continue + if "Error when loading first segment" in tail_text or "m3u8" in tail_text or "ffmpeg exited with code 183" in tail_text: + logger.warning("yt-dlp HLS failed, retrying with native HLS downloader") + returncode, tail_lines = await _run_yt_dlp(fmt, use_player_client, True) + last_tail = tail_lines + if returncode == 0: + break + tail_text = "\n".join(tail_lines[-12:]) if tail_lines else "" logger.error("yt-dlp failed") if tail_text: raise Exception(f"Ошибка скачивания: yt-dlp завершился с ошибкой\n{tail_text}")