diff --git a/app/youtube_downloader.py b/app/youtube_downloader.py index 988bbc7..8c5d251 100644 --- a/app/youtube_downloader.py +++ b/app/youtube_downloader.py @@ -112,44 +112,57 @@ async def get_video_title(url: str, config: Optional[Config] = None) -> Optional Название видео или None в случае ошибки """ try: - cmd = [ - 'yt-dlp', - '--no-download', - '--skip-download', - '--get-title', - '--no-warnings', - '--no-playlist', - url - ] - if config: - if config.ytdlp_user_agent: - cmd.extend(['--user-agent', config.ytdlp_user_agent]) - if config.ytdlp_cookies_file: - cmd.extend(['--cookies', config.ytdlp_cookies_file]) - if config.ytdlp_player_client: - cmd.extend(['--extractor-args', f'youtube:player_client={config.ytdlp_player_client}']) - if config.ytdlp_force_ipv4: - cmd.append('--force-ipv4') - - process = await asyncio.create_subprocess_exec( - *cmd, - stdout=asyncio.subprocess.PIPE, - stderr=asyncio.subprocess.PIPE - ) - - stdout, stderr = await process.communicate() - - if process.returncode == 0: - title = stdout.decode('utf-8', errors='ignore').strip() + async def _run_get_title(use_player_client: bool) -> tuple[int, str, str]: + cmd = [ + 'yt-dlp', + '--no-download', + '--skip-download', + '--get-title', + '--no-warnings', + '--no-playlist', + url + ] + if config: + if config.ytdlp_user_agent: + cmd.extend(['--user-agent', config.ytdlp_user_agent]) + if config.ytdlp_cookies_file: + cmd.extend(['--cookies', config.ytdlp_cookies_file]) + if use_player_client and config.ytdlp_player_client: + cmd.extend(['--extractor-args', f'youtube:player_client={config.ytdlp_player_client}']) + if config.ytdlp_force_ipv4: + cmd.append('--force-ipv4') + + process = await asyncio.create_subprocess_exec( + *cmd, + stdout=asyncio.subprocess.PIPE, + stderr=asyncio.subprocess.PIPE + ) + stdout, stderr = await process.communicate() + return process.returncode, stdout.decode('utf-8', errors='ignore'), stderr.decode('utf-8', errors='ignore') + + # Первый проход — как обычно (с player_client, если задан) + returncode, stdout, stderr = await _run_get_title(use_player_client=True) + if returncode == 0: + title = stdout.strip() if title: logger.info(f"Got title for {url}: {title[:50]}...") return title else: - error = stderr.decode('utf-8', errors='ignore') - logger.warning(f"Failed to get title for {url}: {error}") - + logger.warning(f"Failed to get title for {url}: {stderr}") + + # Фолбэк — без player_client + if config and config.ytdlp_player_client: + returncode, stdout, stderr = await _run_get_title(use_player_client=False) + if returncode == 0: + title = stdout.strip() + if title: + logger.info(f"Got title for {url} without player_client: {title[:50]}...") + return title + else: + logger.warning(f"Failed to get title for {url} without player_client: {stderr}") + return None - + except Exception as e: logger.error(f"Error getting video title: {e}", exc_info=True) return None @@ -192,7 +205,7 @@ async def download_and_convert( 'bestaudio/best', ] - async def _run_yt_dlp(format_selector: str): + async def _run_yt_dlp(format_selector: str, use_player_client: bool): cmd = [ 'yt-dlp', '-x', # Извлечь аудио @@ -212,7 +225,7 @@ async def download_and_convert( cmd.extend(['--user-agent', config.ytdlp_user_agent]) if config.ytdlp_cookies_file: cmd.extend(['--cookies', config.ytdlp_cookies_file]) - if config.ytdlp_player_client: + if use_player_client and config.ytdlp_player_client: cmd.extend(['--extractor-args', f'youtube:player_client={config.ytdlp_player_client}']) if config.ytdlp_force_ipv4: cmd.append('--force-ipv4') @@ -250,8 +263,15 @@ async def download_and_convert( return process.returncode, list(stderr_tail) + list(stdout_tail) last_tail: list[str] = [] + attempts = [] for fmt in formats_to_try: - returncode, tail_lines = await _run_yt_dlp(fmt) + attempts.append((fmt, True)) + if config and config.ytdlp_player_client: + for fmt in formats_to_try: + attempts.append((fmt, False)) + + for fmt, use_player_client in attempts: + returncode, tail_lines = await _run_yt_dlp(fmt, use_player_client) last_tail = tail_lines if returncode == 0: break