diff --git a/youtube-downloader/app.py b/youtube-downloader/app.py index 87223b9..d1f243f 100644 --- a/youtube-downloader/app.py +++ b/youtube-downloader/app.py @@ -150,6 +150,8 @@ def _make_base_ydl_opts(user_agent: str, cookies_file_path: Path | None = None) 'user_agent': user_agent, 'socket_timeout': 60, 'extractor_retries': 3, + # Предпочитаем русскую озвучку — YouTube иногда подсовывает авто-дубляж на английском + 'format_sort': ['lang:ru'], 'http_headers': { 'User-Agent': user_agent, 'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8', @@ -285,9 +287,9 @@ def download_youtube_video(url: str, max_retries: int = 3, format_id: str | None # Это важно, т.к. format_id из get_youtube_formats() может не совпадать # с format_id при повторном extract_info() в download_youtube_video(). default_format_options = [ - 'bestvideo[ext=mp4]+bestaudio[ext=m4a]/best[ext=mp4]/best', + 'bestvideo[ext=mp4]+bestaudio[language=ru][ext=m4a]/bestvideo[ext=mp4]+bestaudio[ext=m4a]/best[ext=mp4]/best', 'best[ext=mp4]/best', - 'bestvideo+bestaudio/best', + 'bestvideo+bestaudio[language=ru]/bestvideo+bestaudio/best', 'best', ] @@ -335,6 +337,8 @@ def download_youtube_video(url: str, max_retries: int = 3, format_id: str | None 'format': format_option, 'outtmpl': _safe_filename(video_title), 'fragment_retries': 3, + # Явно включаем фикс растянутого/сплющенного aspect ratio + 'postprocessors': [{'key': 'FFmpegFixupStretched'}], }) use_cookies_this_attempt = cookies_valid @@ -650,17 +654,28 @@ def get_youtube_formats(url: str) -> list[dict]: logger.info(f"[FORMATS] {display_label} (height={best_video_height}): video_size={video_size}, has_audio={has_audio}, total={total_size}, format_id={video_format_id}") - # format_selector без /best в конце — чтобы yt-dlp не молча скатывался на другой размер + # format_selector: предпочитаем русскую озвучку (YouTube Shorts часто авто-дублирует) if has_audio: - format_selector = f"{video_format_id}/bestvideo[height<={best_video_height}]+bestaudio/best[height<={best_video_height}]" + format_selector = ( + f"{video_format_id}/" + f"bestvideo[height<={best_video_height}]+bestaudio[language=ru]/" + f"bestvideo[height<={best_video_height}]+bestaudio/" + f"best[height<={best_video_height}]" + ) elif best_audio_info['format_id']: format_selector = ( f"{video_format_id}+{best_audio_info['format_id']}/" + f"bestvideo[height<={best_video_height}]+bestaudio[language=ru]/" f"bestvideo[height<={best_video_height}]+bestaudio/" f"best[height<={best_video_height}]" ) else: - format_selector = f"{video_format_id}+bestaudio/bestvideo[height<={best_video_height}]+bestaudio/best[height<={best_video_height}]" + format_selector = ( + f"{video_format_id}+bestaudio[language=ru]/" + f"bestvideo[height<={best_video_height}]+bestaudio[language=ru]/" + f"bestvideo[height<={best_video_height}]+bestaudio/" + f"best[height<={best_video_height}]" + ) result.append({ 'format_id': format_selector, @@ -673,7 +688,7 @@ def get_youtube_formats(url: str) -> list[dict]: # Добавляем аудиодорожку (M4A в приоритете — Telegram поддерживает только MP3/M4A для reply_audio) if best_audio_info['size']: result.append({ - 'format_id': 'bestaudio[ext=m4a]/bestaudio[ext=mp3]/bestaudio/best', + 'format_id': 'bestaudio[language=ru][ext=m4a]/bestaudio[language=ru][ext=mp3]/bestaudio[language=ru]/bestaudio/best', 'label': f"Audio only ({best_audio_info['ext']})", 'quality': 'audio', 'ext': best_audio_info['ext'], diff --git a/youtube-downloader/youtube_cookies.txt b/youtube-downloader/youtube_cookies.txt index 393ef26..1994e10 100644 --- a/youtube-downloader/youtube_cookies.txt +++ b/youtube-downloader/youtube_cookies.txt @@ -27,14 +27,14 @@ .youtube.com TRUE / FALSE 1776287761000 ST-yve142 session_logininfo=AFmmF2swRQIgZPfEOdmfC8u5sHvE1aOagKEvp5rRUe5hRUeLiYmxLDwCIQDqFIR59yZ_aBb5BLYSpK7LGdJ6YZqnh32USuOyMZTC5g%3AQUQ3MjNmd0ZzX01fTjViQ2kzMDJEWG5Ed09zMGF1TlhJcm81YWt3WWdKS2RCZkY3Z2NmMVhudUF4MFVZdFlHd0YtaEU0R3VHNHQ3VmFSZHdfR1RIcnBJNUtXeWhKWVVScE1ZcXNJdzRfdkFGVi1lZzY2dWxCcVVGZ0FPSjNzVmFjTVg1YTBYS0xBajEzU1REM3dnbUc5U3E3NHVtLVRLLXRn .youtube.com TRUE / TRUE 1807824503515 __Secure-1PSIDTS sidts-CjUBWhotCSAL5EMsgNfc0JD8UVvU5vyCYbx9ZFc0Nnry9Qc7YHRzl6a7o8Zm6bPYHoFyKALKlBAA .youtube.com TRUE / TRUE 1807824503517 __Secure-3PSIDTS sidts-CjUBWhotCSAL5EMsgNfc0JD8UVvU5vyCYbx9ZFc0Nnry9Qc7YHRzl6a7o8Zm6bPYHoFyKALKlBAA -.youtube.com TRUE / TRUE 1793314544 VISITOR_INFO1_LIVE vFr43YvHJaE -.youtube.com TRUE / TRUE 1793314544 VISITOR_PRIVACY_METADATA CgJSVRIEGgAgMg%3D%3D +.youtube.com TRUE / TRUE 1793319671 VISITOR_INFO1_LIVE vFr43YvHJaE +.youtube.com TRUE / TRUE 1793319671 VISITOR_PRIVACY_METADATA CgJSVRIEGgAgMg%3D%3D .youtube.com TRUE / FALSE 1776288519000 ST-tladcw session_logininfo=AFmmF2swRQIgZPfEOdmfC8u5sHvE1aOagKEvp5rRUe5hRUeLiYmxLDwCIQDqFIR59yZ_aBb5BLYSpK7LGdJ6YZqnh32USuOyMZTC5g%3AQUQ3MjNmd0ZzX01fTjViQ2kzMDJEWG5Ed09zMGF1TlhJcm81YWt3WWdKS2RCZkY3Z2NmMVhudUF4MFVZdFlHd0YtaEU0R3VHNHQ3VmFSZHdfR1RIcnBJNUtXeWhKWVVScE1ZcXNJdzRfdkFGVi1lZzY2dWxCcVVGZ0FPSjNzVmFjTVg1YTBYS0xBajEzU1REM3dnbUc5U3E3NHVtLVRLLXRn .youtube.com TRUE / FALSE 0 PREF tz=UTC&f7=100&f6=40000000&hl=en .youtube.com TRUE / FALSE 1776288527000 ST-xuwub9 session_logininfo=AFmmF2swRQIgZPfEOdmfC8u5sHvE1aOagKEvp5rRUe5hRUeLiYmxLDwCIQDqFIR59yZ_aBb5BLYSpK7LGdJ6YZqnh32USuOyMZTC5g%3AQUQ3MjNmd0ZzX01fTjViQ2kzMDJEWG5Ed09zMGF1TlhJcm81YWt3WWdKS2RCZkY3Z2NmMVhudUF4MFVZdFlHd0YtaEU0R3VHNHQ3VmFSZHdfR1RIcnBJNUtXeWhKWVVScE1ZcXNJdzRfdkFGVi1lZzY2dWxCcVVGZ0FPSjNzVmFjTVg1YTBYS0xBajEzU1REM3dnbUc5U3E3NHVtLVRLLXRn -.youtube.com TRUE / FALSE 1809298544 SIDCC AKEyXzVa7lSTdOSv8wBZg33qEiiwbNCETtCNC9xssuu_BPPxNep2Lc2negI0NHWARFHb_MwD8V_c -.youtube.com TRUE / TRUE 1809298544 __Secure-1PSIDCC AKEyXzX8DfBF1L6BIhnm19j-ZBSyE16TpQVvn6vIBB_zA5dma1mjRuTuWTlS3ut3feYm1YMhme8q -.youtube.com TRUE / TRUE 1809298544 __Secure-3PSIDCC AKEyXzUfC0IlqutC5s9_cf3HrI_S4F8ui7NJPayGnr2TMOS5u0EuoUVZaKgJm6vklINRtl0oO9hR +.youtube.com TRUE / FALSE 1809303671 SIDCC AKEyXzUEfCEbgyGrH1tNORzoWjcQ4T0V72l_bkp7S12EcJE1BUmxvYDz5rhspZYtTtFg7hzpWkbN +.youtube.com TRUE / TRUE 1809303671 __Secure-1PSIDCC AKEyXzWZMgqSjtmJ_uHCIE-o8z-H3jLbJznGybAMvRcbKNzCej_YDlmQ-ScNrcaJ58mYfK6iaOei +.youtube.com TRUE / TRUE 1809303671 __Secure-3PSIDCC AKEyXzU4244NG2Eo-friqIol4JdiWYR7Ew-fg1o9TggXgU7NJqk_X_6o7WvvME6so9LxwmuM3lmj .youtube.com TRUE / FALSE 1776288585000 ST-3opvp5 session_logininfo=AFmmF2swRQIgZPfEOdmfC8u5sHvE1aOagKEvp5rRUe5hRUeLiYmxLDwCIQDqFIR59yZ_aBb5BLYSpK7LGdJ6YZqnh32USuOyMZTC5g%3AQUQ3MjNmd0ZzX01fTjViQ2kzMDJEWG5Ed09zMGF1TlhJcm81YWt3WWdKS2RCZkY3Z2NmMVhudUF4MFVZdFlHd0YtaEU0R3VHNHQ3VmFSZHdfR1RIcnBJNUtXeWhKWVVScE1ZcXNJdzRfdkFGVi1lZzY2dWxCcVVGZ0FPSjNzVmFjTVg1YTBYS0xBajEzU1REM3dnbUc5U3E3NHVtLVRLLXRn .youtube.com TRUE / TRUE 0 YSC KTvrS45hA30 .instagram.com TRUE / TRUE 1801240452128 datr hGdNaS-QqakSYV8X2eqVTIyA