From 089e90b36adf57bdee921c67522c368c184e9ec2 Mon Sep 17 00:00:00 2001 From: smolkik-code Date: Wed, 18 Feb 2026 23:30:11 +0700 Subject: [PATCH] bug vix4 --- .DS_Store | Bin 16388 -> 16388 bytes bot/downloader.py | 68 +++++++++++++++++++++++++--------------------- 2 files changed, 37 insertions(+), 31 deletions(-) diff --git a/.DS_Store b/.DS_Store index 46d352977d5e59d2ac7753f36f05111047a7ce12..db8bed2fe30eb4d47ef8fdf0a5153583ed2296a4 100644 GIT binary patch delta 155 zcmZo^U~Fk%+^|-jTcWz!(!^Lt!Pwk*@@{$Q$?K(6c$pcJ81flPa*E5GlX5n*D44TP g4%aJVM^m=>mpU)UWL+Ef&D;iy*oiU7VkHsE0M;%n-T(jq delta 274 zcmZo^U~Fk%+^|+&OS-z+(A>yGM?u%nz`&wbN1@u%$UsNI(!j8`mXkwNS>HM+K07Bj zFTZ#425EV|J_ZH`W`-n&e1?*o;H-{-4QyC8a~mvT OCs8|wJ1kaGXaoS)lSz31 diff --git a/bot/downloader.py b/bot/downloader.py index 3a2f3e2..f08127a 100644 --- a/bot/downloader.py +++ b/bot/downloader.py @@ -5,6 +5,7 @@ import os import logging import subprocess import shutil +import asyncio from typing import List from config import ( @@ -28,11 +29,7 @@ def _progress_hook(cancel_event, progress_cb): def optimize_for_telegram(input_path: str, output_path: str) -> None: """ - Конвертирует видео в Telegram-safe формат: - - mp4 + h264 + aac - - четные размеры - - crf: 23 (или 28 >50MB) - - faststart + Синхронная функция: конвертирует видео в Telegram-safe mp4 """ file_size_mb = os.path.getsize(input_path) / (1024 * 1024) crf = 28 if file_size_mb > 50 else 23 @@ -66,10 +63,9 @@ def download_video( cancel_event: threading.Event, progress_cb, ): - # 1. Скачиваем в любой формат ydl_opts = { "format": f"best[height<={quality}]/best", - "outtmpl": out_path, # ← без .mp4! + "outtmpl": out_path, "cookiefile": cookies if cookies and os.path.exists(cookies) else None, "progress_hooks": [_progress_hook(cancel_event, progress_cb)], "quiet": True, @@ -81,7 +77,7 @@ def download_video( with yt_dlp.YoutubeDL(ydl_opts) as ydl: ydl.download([url]) - # 2. Ищем реальный файл (без расширения, .mp4, .mov, .webm) + # Ищем реальный файл base = out_path.rsplit('.', 1)[0] actual_video = None for ext in ['', '.mp4', '.mov', '.webm', '.mkv']: @@ -93,11 +89,11 @@ def download_video( if not actual_video: raise Exception(f"Video file not created for {url}") - # 3. Конвертируем в Telegram-safe mp4 + # Конвертируем в Telegram-safe mp4 (синхронно) optimized_path = base + "_telegram.mp4" - await asyncio.to_thread(optimize_for_telegram, actual_video, optimized_path) + optimize_for_telegram(actual_video, optimized_path) # ← без await! - # 4. Удаляем оригинальный файл и ставим конвертированный + # Удаляем старый файл и ставим конвертированный for path in [out_path, actual_video]: if os.path.exists(path): os.remove(path) os.rename(optimized_path, out_path) @@ -113,7 +109,7 @@ def download_audio( ): ydl_opts = { "format": "bestaudio/best", - "outtmpl": out_path.replace('.mp3', ''), # ← без .mp3! + "outtmpl": out_path.replace('.mp3', ''), "cookiefile": cookies if cookies and os.path.exists(cookies) else None, "progress_hooks": [_progress_hook(cancel_event, progress_cb)], "postprocessors": [{ @@ -130,7 +126,7 @@ def download_audio( with yt_dlp.YoutubeDL(ydl_opts) as ydl: ydl.download([url]) - # Ищем файл (может быть .m4a, .opus, .weba) + # Ищем файл base = out_path.rsplit('.', 1)[0] actual_audio = None for ext in ['', '.mp3', '.m4a', '.opus', '.weba']: @@ -142,18 +138,15 @@ def download_audio( if not actual_audio: raise Exception(f"Audio file not created for {url}") - # Конвертируем в mp3 (если нужно) + # Конвертируем в mp3 if actual_audio != out_path: optimized = base + "_telegram.mp3" - subprocess.run([ - 'ffmpeg', '-i', actual_audio, '-c:a', 'aac', '-b:a', '192k', - '-loglevel', 'error', '-y', optimized - ]) + optimize_for_telegram_audio(actual_audio, optimized) # ← отдельная функция if os.path.exists(out_path): os.remove(out_path) os.rename(optimized, out_path) -# ---------------- TIKTOK: Video + Audio (автоматически) ------ +# ---------------- TikTok: Video + Audio (автоматически) ------ def download_tiktok_video_and_audio( url: str, video_path: str, @@ -162,10 +155,10 @@ def download_tiktok_video_and_audio( cancel_event: threading.Event, progress_cb, ): - # 1. Скачиваем видео + # Скачиваем видео video_opts = { "format": f"bestvideo[height<={DEFAULT_TIKTOK_VIDEO_QUALITY}]+bestaudio/best", - "outtmpl": video_path, # ← без .mp4! + "outtmpl": video_path, "cookiefile": cookies if cookies and os.path.exists(cookies) else None, "progress_hooks": [_progress_hook(cancel_event, progress_cb)], "quiet": True, @@ -177,6 +170,7 @@ def download_tiktok_video_and_audio( with yt_dlp.YoutubeDL(video_opts) as ydl: ydl.download([url]) + # Ищем видеофайл base_video = video_path.rsplit('.', 1)[0] actual_video = None for ext in ['', '.mp4', '.mov', '.webm']: @@ -187,14 +181,14 @@ def download_tiktok_video_and_audio( if not actual_video: raise Exception("TikTok video file not created") - # Конвертируем в Telegram-safe + # Конвертируем в Telegram-safe mp4 optimized_video = base_video + "_telegram.mp4" - await asyncio.to_thread(optimize_for_telegram, actual_video, optimized_video) + optimize_for_telegram(actual_video, optimized_video) for path in [video_path, actual_video]: if os.path.exists(path): os.remove(path) os.rename(optimized_video, video_path) - # 2. Аудио + # Аудио audio_opts = { "format": "bestaudio/best", "outtmpl": audio_path.replace('.mp3', ''), @@ -225,15 +219,12 @@ def download_tiktok_video_and_audio( if actual_audio != audio_path: optimized_audio = base_audio + "_telegram.mp3" - subprocess.run([ - 'ffmpeg', '-i', actual_audio, '-c:a', 'aac', '-b:a', '192k', - '-loglevel', 'error', '-y', optimized_audio - ]) + optimize_for_telegram_audio(actual_audio, optimized_audio) if os.path.exists(audio_path): os.remove(audio_path) os.rename(optimized_audio, audio_path) -# ---------------- INSTAGRAM: Video (1080p) ------ +# ---------------- Instagram: Video (1080p) ------ def download_instagram_video( url: str, out_path: str, @@ -266,12 +257,27 @@ def download_instagram_video( raise Exception("Instagram video not created") optimized = base + "_telegram.mp4" - await asyncio.to_thread(optimize_for_telegram, actual, optimized) + optimize_for_telegram(actual, optimized) if os.path.exists(out_path): os.remove(out_path) os.rename(optimized, out_path) -# ---------------- PLAYLIST ------ +# ---------------- Audio helper (синхронная) ------ +def optimize_for_telegram_audio(input_path: str, output_path: str) -> None: + """Конвертирует аудио в Telegram-safe mp3""" + cmd = [ + 'ffmpeg', + '-i', input_path, + '-c:a', 'aac', + '-b:a', '192k', + '-loglevel', 'error', + '-y', + output_path + ] + subprocess.run(cmd, capture_output=True, text=True, timeout=600) + + +# ---------------- Playlist ------ def download_playlist_videos( playlist_info: dict, output_dir: str,