import yt_dlp import os import sys import tempfile def download_video(url, output_dir=None): """Downloads a video from the given URL to a temporary location or specified output directory. Args: url (str): The URL of the video to download. output_dir (str, optional): Directory to save the downloaded file. If None, uses a temporary directory. Returns: str: The absolute path to the downloaded video file, or None if download fails. """ if output_dir and not os.path.isdir(output_dir): print(f"Error: Output directory '{output_dir}' for download does not exist or is not a directory.", file=sys.stderr) return None temp_dir = None if not output_dir: temp_dir = tempfile.TemporaryDirectory() # Create a temporary directory output_dir = temp_dir.name ydl_opts = { 'format': 'bestvideo[ext!=webm]+bestaudio[ext!=webm]/best[ext!=webm]', # Prioritize non-webm formats 'outtmpl': os.path.join(output_dir, '%(title)s.%(ext)s'), 'noplaylist': True, # Only download single video, not entire playlist 'progress_hooks': [lambda d: sys.stdout.write(f"Downloading: {d['filename']} - {d['status']}" + '\r') if d['status'] == 'downloading' else None], 'postprocessors': [{ 'key': 'FFmpegVideoConvertor', 'preferedformat': 'mp4', }], 'quiet': True, # Suppress yt-dlp output unless error 'no_warnings': True, } downloaded_file_path = None try: with yt_dlp.YoutubeDL(ydl_opts) as ydl: info_dict = ydl.extract_info(url, download=True) downloaded_file_path = ydl.prepare_filename(info_dict) # yt-dlp might return a path with a different extension if format conversion happened # We need to find the actual downloaded file base, ext = os.path.splitext(downloaded_file_path) if not os.path.exists(downloaded_file_path): # Try common extensions if the exact path isn't found for common_ext in ['.mp4', '.mkv', '.webm', '.flv']: if os.path.exists(base + common_ext): downloaded_file_path = base + common_ext break if not os.path.exists(downloaded_file_path): print(f"Error: Downloaded file not found at expected path: {downloaded_file_path}", file=sys.stderr) return None except yt_dlp.utils.DownloadError as e: print(f"Error downloading video: {e}", file=sys.stderr) return None except Exception as e: print(f"An unexpected error occurred during download: {e}", file=sys.stderr) return None finally: if temp_dir: # Clean up temporary directory if it was created # The file might have been moved by yt-dlp, so we only clean up if it's empty if not os.listdir(temp_dir.name): temp_dir.cleanup() else: print(f"Warning: Temporary directory {temp_dir.name} not empty, not cleaning up automatically.", file=sys.stderr) return downloaded_file_path