main
  1#!/usr/bin/env python3
  2"""
  3YouTube Video Downloader
  4Downloads videos from YouTube with customizable quality and format options.
  5"""
  6
  7import argparse
  8import sys
  9import subprocess
 10import json
 11
 12
 13def check_yt_dlp():
 14    """Check if yt-dlp is installed, install if not."""
 15    try:
 16        subprocess.run(["yt-dlp", "--version"], capture_output=True, check=True)
 17    except (subprocess.CalledProcessError, FileNotFoundError):
 18        print("yt-dlp not found. Installing...")
 19        subprocess.run([sys.executable, "-m", "pip", "install", "--break-system-packages", "yt-dlp"], check=True)
 20
 21
 22def get_video_info(url):
 23    """Get information about the video without downloading."""
 24    result = subprocess.run(
 25        ["yt-dlp", "--dump-json", "--no-playlist", url],
 26        capture_output=True,
 27        text=True,
 28        check=True
 29    )
 30    return json.loads(result.stdout)
 31
 32
 33def download_video(url, output_path="/mnt/user-data/outputs", quality="best", format_type="mp4", audio_only=False):
 34    """
 35    Download a YouTube video.
 36    
 37    Args:
 38        url: YouTube video URL
 39        output_path: Directory to save the video
 40        quality: Quality setting (best, 1080p, 720p, 480p, 360p, worst)
 41        format_type: Output format (mp4, webm, mkv, etc.)
 42        audio_only: Download only audio (mp3)
 43    """
 44    check_yt_dlp()
 45    
 46    # Build command
 47    cmd = ["yt-dlp"]
 48    
 49    if audio_only:
 50        cmd.extend([
 51            "-x",  # Extract audio
 52            "--audio-format", "mp3",
 53            "--audio-quality", "0",  # Best quality
 54        ])
 55    else:
 56        # Video quality settings
 57        if quality == "best":
 58            format_string = "bestvideo+bestaudio/best"
 59        elif quality == "worst":
 60            format_string = "worstvideo+worstaudio/worst"
 61        else:
 62            # Specific resolution (e.g., 1080p, 720p)
 63            height = quality.replace("p", "")
 64            format_string = f"bestvideo[height<={height}]+bestaudio/best[height<={height}]"
 65        
 66        cmd.extend([
 67            "-f", format_string,
 68            "--merge-output-format", format_type,
 69        ])
 70    
 71    # Output template
 72    cmd.extend([
 73        "-o", f"{output_path}/%(title)s.%(ext)s",
 74        "--no-playlist",  # Don't download playlists by default
 75    ])
 76    
 77    cmd.append(url)
 78    
 79    print(f"Downloading from: {url}")
 80    print(f"Quality: {quality}")
 81    print(f"Format: {'mp3 (audio only)' if audio_only else format_type}")
 82    print(f"Output: {output_path}\n")
 83    
 84    try:
 85        # Get video info first
 86        info = get_video_info(url)
 87        print(f"Title: {info.get('title', 'Unknown')}")
 88        print(f"Duration: {info.get('duration', 0) // 60}:{info.get('duration', 0) % 60:02d}")
 89        print(f"Uploader: {info.get('uploader', 'Unknown')}\n")
 90        
 91        # Download the video
 92        subprocess.run(cmd, check=True)
 93        print(f"\n✅ Download complete!")
 94        return True
 95    except subprocess.CalledProcessError as e:
 96        print(f"\n❌ Error downloading video: {e}")
 97        return False
 98    except Exception as e:
 99        print(f"\n❌ Error: {e}")
100        return False
101
102
103def main():
104    parser = argparse.ArgumentParser(
105        description="Download YouTube videos with customizable quality and format"
106    )
107    parser.add_argument("url", help="YouTube video URL")
108    parser.add_argument(
109        "-o", "--output",
110        default="/mnt/user-data/outputs",
111        help="Output directory (default: /mnt/user-data/outputs)"
112    )
113    parser.add_argument(
114        "-q", "--quality",
115        default="best",
116        choices=["best", "1080p", "720p", "480p", "360p", "worst"],
117        help="Video quality (default: best)"
118    )
119    parser.add_argument(
120        "-f", "--format",
121        default="mp4",
122        choices=["mp4", "webm", "mkv"],
123        help="Video format (default: mp4)"
124    )
125    parser.add_argument(
126        "-a", "--audio-only",
127        action="store_true",
128        help="Download only audio as MP3"
129    )
130    
131    args = parser.parse_args()
132    
133    success = download_video(
134        url=args.url,
135        output_path=args.output,
136        quality=args.quality,
137        format_type=args.format,
138        audio_only=args.audio_only
139    )
140    
141    sys.exit(0 if success else 1)
142
143
144if __name__ == "__main__":
145    main()