diff --git a/main.py b/main.py index 4849b4f..d3e211f 100644 --- a/main.py +++ b/main.py @@ -155,41 +155,27 @@ def download_video( else: target = f"https://www.youtube.com/watch?v={videoId}" video_id = videoId - - quality_presets = { - "low": [ - "bestvideo[height<=480]+bestaudio/best[height<=480]", - "best[height<=480]", - "best" - ], - "medium": [ - "bestvideo[height<=720]+bestaudio/best[height<=720]", - "best[height<=720]", - "best" - ], - "high": [ - "bestvideo+bestaudio/best", - "best" - ] + + quality_targets = { + "low": 480, + "medium": 720, + "high": 1080 } qualidade = qualidade.lower() - if qualidade not in quality_presets: + if qualidade not in quality_targets: raise HTTPException(status_code=400, detail="Qualidade deve ser: low, medium ou high") - format_options = quality_presets[qualidade] - videos_dir = "/app/videos" os.makedirs(videos_dir, exist_ok=True) unique_id = str(uuid.uuid4()) output_template = os.path.join(videos_dir, f"{unique_id}.%(ext)s") - + ydl_opts = { 'outtmpl': output_template, 'quiet': True, 'no_warnings': True, - 'nocheckcertificate': True, 'ignoreerrors': False, 'no_color': True, 'extract_flat': 'in_playlist', @@ -197,15 +183,39 @@ def download_video( 'allow_unplayable_formats': True, } - def try_download(ydl, format_spec, attempt=1): - ydl.params['format'] = format_spec + def get_best_format(ydl, target_height): + info = ydl.extract_info(target, download=False) + if not info or 'formats' not in info: + return 'best' + + formats = info['formats'] + best_format = None + best_height = 0 - try: - return ydl.extract_info(target, download=True) - except Exception as e: - if attempt < len(format_options): - return try_download(ydl, format_options[attempt], attempt + 1) - raise + for f in formats: + if f.get('height') and f.get('acodec') != 'none': + if f['height'] <= target_height and f['height'] > best_height: + best_format = f + best_height = f['height'] + + if not best_format: + video_format = None + audio_format = None + + for f in formats: + if f.get('vcodec') != 'none' and f.get('acodec') == 'none': + if f.get('height') and f['height'] <= target_height and (not video_format or f['height'] > video_format.get('height', 0)): + video_format = f + + for f in formats: + if f.get('acodec') != 'none' and f.get('vcodec') == 'none': + if not audio_format or f.get('tbr', 0) > audio_format.get('tbr', 0): + audio_format = f + + if video_format and audio_format: + return f"{video_format['format_id']}+{audio_format['format_id']}" + + return best_format['format_id'] if best_format else 'best' try: with YoutubeDL(ydl_opts) as ydl: @@ -240,9 +250,13 @@ def download_video( "filename": filename } - print(f'Iniciando download com qualidade: {qualidade}') + print(f'Buscando melhor formato disponível para qualidade: {qualidade}') - result = try_download(ydl, format_options[0]) + best_format = get_best_format(ydl, target_height) + print(f'Melhor formato encontrado: {best_format}') + + ydl.params['format'] = best_format + result = ydl.extract_info(target, download=True) if "requested_downloads" in result and len(result["requested_downloads"]) > 0: real_file_path = result["requested_downloads"][0]["filepath"]