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()