jpjp9292 commited on
Commit
e89cd34
·
verified ·
1 Parent(s): 1c1e1f4

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +166 -80
app.py CHANGED
@@ -113,9 +113,12 @@ import streamlit as st
113
  import yt_dlp
114
  import os
115
  from pathlib import Path
 
 
 
116
 
117
  # Set page config
118
- st.set_page_config(page_title="YouTube Video Downloader", page_icon="📺")
119
 
120
  # Set the title of the app
121
  st.title("YouTube Video Downloader 📺")
@@ -124,98 +127,181 @@ st.title("YouTube Video Downloader 📺")
124
  output_dir = Path("downloads")
125
  output_dir.mkdir(exist_ok=True)
126
 
127
- # Check if cookies file exists
128
- COOKIES_FILE = 'youtube.com_cookies.txt'
129
- has_cookies = os.path.exists(COOKIES_FILE)
 
 
130
 
131
- if has_cookies:
132
- st.success("✅ Cookie file detected")
133
- else:
134
- st.warning("⚠️ No cookie file found - Some videos might be restricted")
135
-
136
- # Input field for YouTube video URL
137
- video_url = st.text_input("Enter YouTube Video URL:", placeholder="https://www.youtube.com/watch?v=...")
138
-
139
- def download_video(url):
140
  try:
141
- ydl_opts = {
142
- 'format': 'bestvideo+bestaudio/best',
143
- 'outtmpl': str(output_dir / '%(title)s.%(ext)s'),
144
- 'merge_output_format': 'webm',
145
- 'quiet': True,
146
- 'no_warnings': True,
147
- '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',
148
- 'referer': 'https://www.youtube.com/',
149
- 'http_chunk_size': 10485760
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
150
  }
 
 
151
 
152
- # Add cookies file if available
153
- if has_cookies:
154
- ydl_opts['cookiefile'] = COOKIES_FILE
155
-
156
- # Progress placeholder
157
- progress_bar = st.progress(0)
158
- status_text = st.empty()
159
-
160
- def progress_hook(d):
161
- if d['status'] == 'downloading':
162
- try:
163
- progress = d['downloaded_bytes'] / d['total_bytes']
164
- progress_bar.progress(progress)
165
- status_text.text(f"Downloading: {progress:.1%}")
166
- except:
167
- status_text.text("Downloading... (size unknown)")
168
- elif d['status'] == 'finished':
169
- progress_bar.progress(1.0)
170
- status_text.text("Processing...")
171
-
172
- ydl_opts['progress_hooks'] = [progress_hook]
173
-
174
- with yt_dlp.YoutubeDL(ydl_opts) as ydl:
175
- info = ydl.extract_info(url, download=True)
176
- filename = ydl.prepare_filename(info)
177
- return filename
178
-
179
- except Exception as e:
180
- st.error(f"An error occurred: {str(e)}")
181
- return None
182
-
183
- # Download button
184
- if st.button("Download"):
185
- if video_url:
186
  try:
187
- with st.spinner("Preparing download..."):
188
- downloaded_file_path = download_video(video_url)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
189
 
190
- if downloaded_file_path and os.path.exists(downloaded_file_path):
191
- with open(downloaded_file_path, 'rb') as file:
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
192
  st.download_button(
193
- label="Click here to download",
194
  data=file,
195
- file_name=os.path.basename(downloaded_file_path),
196
- mime="application/octet-stream"
197
  )
198
  st.success("✅ Download ready!")
199
  else:
200
- st.error("❌ Download failed. Please try again.")
201
- except Exception as e:
202
- st.error(f" An error occurred: {str(e)}")
203
- else:
204
- st.warning("⚠️ Please enter a valid YouTube URL.")
205
-
206
- # Help section
207
- with st.expander("ℹ️ Help & Information"):
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
208
  st.markdown("""
209
- **About Cookie Authentication:**
210
- - This app uses cookie authentication to bypass YouTube's bot detection
211
- - Cookies help the app behave like a logged-in browser
212
- - No personal data is stored or transmitted
 
 
 
 
 
 
 
 
 
 
 
 
 
213
 
214
- **If downloads fail:**
215
- 1. Check if the video is public
216
- 2. Verify the URL is correct
217
- 3. Try a different video
218
- 4. Try again later if YouTube is blocking requests
219
  """)
220
 
221
 
 
113
  import yt_dlp
114
  import os
115
  from pathlib import Path
116
+ import time
117
+ from datetime import datetime
118
+ import json
119
 
120
  # Set page config
121
+ st.set_page_config(page_title="YouTube Video Downloader", page_icon="📺", layout="wide")
122
 
123
  # Set the title of the app
124
  st.title("YouTube Video Downloader 📺")
 
127
  output_dir = Path("downloads")
128
  output_dir.mkdir(exist_ok=True)
129
 
130
+ # Authentication settings
131
+ AUTH_CONFIG = {
132
+ 'COOKIES_FILE': 'youtube.com_cookies.txt',
133
+ 'TOKEN_FILE': 'auth_token.json'
134
+ }
135
 
136
+ def load_auth_token():
 
 
 
 
 
 
 
 
137
  try:
138
+ if os.path.exists(AUTH_CONFIG['TOKEN_FILE']):
139
+ with open(AUTH_CONFIG['TOKEN_FILE'], 'r') as f:
140
+ data = json.load(f)
141
+ if datetime.fromisoformat(data['expires']) > datetime.now():
142
+ return data['token']
143
+ except Exception:
144
+ pass
145
+ return None
146
+
147
+ def save_auth_token(token):
148
+ with open(AUTH_CONFIG['TOKEN_FILE'], 'w') as f:
149
+ json.dump({
150
+ 'token': token,
151
+ 'expires': (datetime.now().isoformat())
152
+ }, f)
153
+
154
+ def setup_ydl_options(has_cookies):
155
+ opts = {
156
+ 'format': 'bestvideo[ext=mp4]+bestaudio[ext=m4a]/best[ext=mp4]/best',
157
+ 'outtmpl': str(output_dir / '%(title)s.%(ext)s'),
158
+ 'merge_output_format': 'mp4',
159
+ 'quiet': True,
160
+ 'no_warnings': True,
161
+ 'extract_flat': False,
162
+ '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',
163
+ 'referer': 'https://www.youtube.com/',
164
+ 'http_chunk_size': 10485760,
165
+ 'retries': 3,
166
+ 'file_access_retries': 3,
167
+ 'fragment_retries': 3,
168
+ 'skip_unavailable_fragments': True,
169
+ 'abort_on_unavailable_fragment': False,
170
+ }
171
+
172
+ # Add cookies file if available
173
+ if has_cookies:
174
+ opts['cookiefile'] = AUTH_CONFIG['COOKIES_FILE']
175
+
176
+ # Add authentication token if available
177
+ token = load_auth_token()
178
+ if token:
179
+ opts['headers'] = {
180
+ 'Authorization': f'Bearer {token}'
181
  }
182
+
183
+ return opts
184
 
185
+ def download_video(url, progress_callback):
186
+ max_retries = 3
187
+ retry_count = 0
188
+
189
+ while retry_count < max_retries:
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
190
  try:
191
+ has_cookies = os.path.exists(AUTH_CONFIG['COOKIES_FILE'])
192
+ ydl_opts = setup_ydl_options(has_cookies)
193
+
194
+ # Add progress hooks
195
+ def progress_hook(d):
196
+ if d['status'] == 'downloading':
197
+ try:
198
+ progress = d['downloaded_bytes'] / d['total_bytes']
199
+ progress_callback(progress, f"Downloading: {progress:.1%}")
200
+ except:
201
+ progress_callback(0, "Downloading... (size unknown)")
202
+ elif d['status'] == 'finished':
203
+ progress_callback(1.0, "Processing...")
204
+
205
+ ydl_opts['progress_hooks'] = [progress_hook]
206
+
207
+ with yt_dlp.YoutubeDL(ydl_opts) as ydl:
208
+ info = ydl.extract_info(url, download=True)
209
+ filename = ydl.prepare_filename(info)
210
+ return filename, None
211
 
212
+ except yt_dlp.utils.ExtractorError as e:
213
+ if "Sign in to confirm you're not a bot" in str(e):
214
+ retry_count += 1
215
+ if retry_count < max_retries:
216
+ time.sleep(5) # Wait before retry
217
+ continue
218
+ return None, "Bot detection triggered. Please try again later or use authentication."
219
+ return None, f"Video extraction failed: {str(e)}"
220
+
221
+ except Exception as e:
222
+ return None, f"Download failed: {str(e)}"
223
+
224
+ return None, "Maximum retries reached. Please try again later."
225
+
226
+ # Main UI
227
+ col1, col2 = st.columns([2, 1])
228
+
229
+ with col1:
230
+ video_url = st.text_input("Enter YouTube Video URL:", placeholder="https://www.youtube.com/watch?v=...")
231
+
232
+ if st.button("Download", type="primary"):
233
+ if video_url:
234
+ progress_bar = st.progress(0)
235
+ status_text = st.empty()
236
+
237
+ def update_progress(progress, status):
238
+ progress_bar.progress(progress)
239
+ status_text.text(status)
240
+
241
+ downloaded_file, error = download_video(video_url, update_progress)
242
+
243
+ if downloaded_file and os.path.exists(downloaded_file):
244
+ with open(downloaded_file, 'rb') as file:
245
  st.download_button(
246
+ label="⬇️ Download Video",
247
  data=file,
248
+ file_name=os.path.basename(downloaded_file),
249
+ mime="video/mp4"
250
  )
251
  st.success("✅ Download ready!")
252
  else:
253
+ st.error(f"❌ {error}")
254
+ else:
255
+ st.warning("⚠️ Please enter a valid YouTube URL.")
256
+
257
+ with col2:
258
+ with st.expander("⚙️ Settings & Information"):
259
+ st.markdown("""
260
+ **Authentication Status:**
261
+ """)
262
+
263
+ if os.path.exists(AUTH_CONFIG['COOKIES_FILE']):
264
+ st.success("✅ Cookie authentication available")
265
+ else:
266
+ st.warning("""
267
+ ⚠️ No cookie authentication configured
268
+
269
+ To enable cookie authentication:
270
+ 1. Export cookies from your browser
271
+ 2. Save as 'youtube.com_cookies.txt' in the app directory
272
+ """)
273
+
274
+ st.markdown("""
275
+ **Download Options:**
276
+ - Videos are downloaded in best available quality
277
+ - Format: MP4 (when available)
278
+ - Automatic quality selection
279
+ """)
280
+
281
+ with st.expander("❓ Help & Troubleshooting"):
282
  st.markdown("""
283
+ **Common Issues & Solutions:**
284
+
285
+ 1. **Bot Detection:**
286
+ - The app implements automatic retries
287
+ - Use cookie authentication for better success rate
288
+ - Wait a few minutes between attempts
289
+
290
+ 2. **Download Fails:**
291
+ - Verify the video is public
292
+ - Check your internet connection
293
+ - Try a different video
294
+ - Clear browser cache and cookies
295
+
296
+ 3. **Quality Issues:**
297
+ - The app automatically selects the best available quality
298
+ - Some videos may have quality restrictions
299
+ - Premium content may require authentication
300
 
301
+ **Need More Help?**
302
+ - Check if the video is available in your region
303
+ - Verify YouTube's terms of service
304
+ - Consider using cookie authentication
 
305
  """)
306
 
307