jpjp9292 commited on
Commit
10f7537
·
verified ·
1 Parent(s): cc12822

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +88 -38
app.py CHANGED
@@ -29,11 +29,13 @@ format_option = st.selectbox(
29
  )
30
 
31
  def get_format_options(selection):
 
 
 
 
 
32
  if selection == "Best Quality (Video + Audio)":
33
- return {
34
- 'format': 'best', # Changed from bestvideo+bestaudio to best
35
- 'merge_output_format': 'mp4'
36
- }
37
  elif selection == "Audio Only (Best Quality)":
38
  return {
39
  'format': 'bestaudio/best',
@@ -43,22 +45,27 @@ def get_format_options(selection):
43
  }]
44
  }
45
  elif selection == "720p":
46
- return {
47
- 'format': 'best[height<=720]', # Simplified format selection
48
- 'merge_output_format': 'mp4'
49
- }
50
  elif selection == "480p":
51
- return {
52
- 'format': 'best[height<=480]',
53
- 'merge_output_format': 'mp4'
54
- }
55
  elif selection == "360p":
56
- return {
57
- 'format': 'best[height<=360]',
58
- 'merge_output_format': 'mp4'
59
- }
 
 
 
 
 
60
 
61
  def download_video(url, format_selection):
 
 
 
 
62
  try:
63
  format_opts = get_format_options(format_selection)
64
 
@@ -66,20 +73,20 @@ def download_video(url, format_selection):
66
  'outtmpl': str(output_dir / '%(title)s.%(ext)s'),
67
  'quiet': True,
68
  'no_warnings': True,
69
- # Enhanced options to bypass restrictions
70
  'nocheckcertificate': True,
71
- 'ignoreerrors': True,
72
  'no_color': True,
73
  'noprogress': True,
74
  'user_agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36',
75
  'referer': 'https://www.youtube.com/',
76
- 'http-chunk-size': '10485760', # 10MB chunks for better reliability
 
77
  }
78
 
79
  # Update options with format-specific settings
80
  ydl_opts.update(format_opts)
81
 
82
- # Progress placeholder
83
  progress_bar = st.progress(0)
84
  status_text = st.empty()
85
 
@@ -97,15 +104,36 @@ def download_video(url, format_selection):
97
 
98
  ydl_opts['progress_hooks'] = [progress_hook]
99
 
 
100
  with yt_dlp.YoutubeDL(ydl_opts) as ydl:
101
- info = ydl.extract_info(url, download=False)
102
- filename = ydl.prepare_filename(info)
103
- ydl.download([url])
104
-
105
- return filename
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
106
 
107
  except Exception as e:
108
- st.error(f"An error occurred: {str(e)}")
109
  return None
110
 
111
  # Download button
@@ -116,18 +144,25 @@ if st.button("Download"):
116
  downloaded_file_path = download_video(video_url, format_option)
117
 
118
  if downloaded_file_path and os.path.exists(downloaded_file_path):
119
- with open(downloaded_file_path, 'rb') as file:
120
- st.download_button(
121
- label="Click here to download",
122
- data=file,
123
- file_name=os.path.basename(downloaded_file_path),
124
- mime="application/octet-stream"
125
- )
126
- st.success("✅ Download ready!")
 
 
 
 
 
 
 
127
  else:
128
- st.error("❌ Download failed. Please try again.")
129
  except Exception as e:
130
- st.error(f"❌ An error occurred: {str(e)}")
131
  else:
132
  st.warning("⚠️ Please enter a valid YouTube URL.")
133
 
@@ -141,5 +176,20 @@ with st.expander("ℹ️ Help"):
141
  4. Wait for the download to complete
142
  5. Click the download button that appears
143
 
144
- **Note:** Some videos might be restricted due to YouTube's policies.
145
- """)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
29
  )
30
 
31
  def get_format_options(selection):
32
+ base_options = {
33
+ 'format': 'best',
34
+ 'merge_output_format': 'mp4',
35
+ }
36
+
37
  if selection == "Best Quality (Video + Audio)":
38
+ return base_options
 
 
 
39
  elif selection == "Audio Only (Best Quality)":
40
  return {
41
  'format': 'bestaudio/best',
 
45
  }]
46
  }
47
  elif selection == "720p":
48
+ base_options['format'] = 'best[height<=720]'
49
+ return base_options
 
 
50
  elif selection == "480p":
51
+ base_options['format'] = 'best[height<=480]'
52
+ return base_options
 
 
53
  elif selection == "360p":
54
+ base_options['format'] = 'best[height<=360]'
55
+ return base_options
56
+
57
+ return base_options
58
+
59
+ def validate_url(url):
60
+ if not url:
61
+ return False
62
+ return 'youtube.com' in url or 'youtu.be' in url
63
 
64
  def download_video(url, format_selection):
65
+ if not validate_url(url):
66
+ st.error("Please enter a valid YouTube URL")
67
+ return None
68
+
69
  try:
70
  format_opts = get_format_options(format_selection)
71
 
 
73
  'outtmpl': str(output_dir / '%(title)s.%(ext)s'),
74
  'quiet': True,
75
  'no_warnings': True,
 
76
  'nocheckcertificate': True,
77
+ 'ignoreerrors': False, # Changed to False to catch errors
78
  'no_color': True,
79
  'noprogress': True,
80
  'user_agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36',
81
  'referer': 'https://www.youtube.com/',
82
+ 'http-chunk-size': '10485760',
83
+ 'extract_flat': True, # Only extract video metadata first
84
  }
85
 
86
  # Update options with format-specific settings
87
  ydl_opts.update(format_opts)
88
 
89
+ # Progress elements
90
  progress_bar = st.progress(0)
91
  status_text = st.empty()
92
 
 
104
 
105
  ydl_opts['progress_hooks'] = [progress_hook]
106
 
107
+ # First, try to extract info without downloading
108
  with yt_dlp.YoutubeDL(ydl_opts) as ydl:
109
+ try:
110
+ info = ydl.extract_info(url, download=False)
111
+ if info is None:
112
+ st.error("Could not fetch video information. The video might be private or age-restricted.")
113
+ return None
114
+
115
+ # If info extraction successful, proceed with download
116
+ ydl_opts['extract_flat'] = False # Now enable full extraction
117
+ with yt_dlp.YoutubeDL(ydl_opts) as ydl_download:
118
+ filename = ydl_download.prepare_filename(info)
119
+ ydl_download.download([url])
120
+
121
+ # Check if file exists and has size > 0
122
+ if os.path.exists(filename) and os.path.getsize(filename) > 0:
123
+ return filename
124
+ else:
125
+ st.error("Download completed but file appears to be empty or missing.")
126
+ return None
127
+
128
+ except yt_dlp.utils.DownloadError as e:
129
+ st.error(f"Download Error: {str(e)}")
130
+ return None
131
+ except Exception as e:
132
+ st.error(f"An unexpected error occurred: {str(e)}")
133
+ return None
134
 
135
  except Exception as e:
136
+ st.error(f"An error occurred during setup: {str(e)}")
137
  return None
138
 
139
  # Download button
 
144
  downloaded_file_path = download_video(video_url, format_option)
145
 
146
  if downloaded_file_path and os.path.exists(downloaded_file_path):
147
+ try:
148
+ with open(downloaded_file_path, 'rb') as file:
149
+ file_data = file.read()
150
+ if len(file_data) > 0:
151
+ st.download_button(
152
+ label="Click here to download",
153
+ data=file_data,
154
+ file_name=os.path.basename(downloaded_file_path),
155
+ mime="application/octet-stream"
156
+ )
157
+ st.success("✅ Download ready!")
158
+ else:
159
+ st.error("❌ Downloaded file is empty.")
160
+ except IOError as e:
161
+ st.error(f"❌ Error reading file: {str(e)}")
162
  else:
163
+ st.error("❌ Download failed. Please try again with a different video or format.")
164
  except Exception as e:
165
+ st.error(f"❌ An unexpected error occurred: {str(e)}")
166
  else:
167
  st.warning("⚠️ Please enter a valid YouTube URL.")
168
 
 
176
  4. Wait for the download to complete
177
  5. Click the download button that appears
178
 
179
+ **Troubleshooting:**
180
+ - If download fails, try a different format
181
+ - Some videos might be restricted or private
182
+ - Make sure the URL is from YouTube
183
+ """)
184
+
185
+ # Clean up old files
186
+ def cleanup_old_files():
187
+ try:
188
+ for file in output_dir.glob('*'):
189
+ if file.is_file():
190
+ file.unlink()
191
+ except Exception as e:
192
+ st.warning(f"Could not clean up old files: {str(e)}")
193
+
194
+ # Run cleanup when the app starts
195
+ cleanup_old_files()