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

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +237 -132
app.py CHANGED
@@ -1,3 +1,202 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
  import streamlit as st
2
  import yt_dlp
3
  import os
@@ -16,77 +215,24 @@ output_dir.mkdir(exist_ok=True)
16
  # Input field for YouTube video URL
17
  video_url = st.text_input("Enter YouTube Video URL:", placeholder="https://www.youtube.com/watch?v=...")
18
 
19
- # Format selection
20
- format_option = st.selectbox(
21
- "Select Format:",
22
- options=[
23
- "Best Quality (Video + Audio)",
24
- "Audio Only (Best Quality)",
25
- "720p",
26
- "480p",
27
- "360p"
28
- ]
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',
42
- 'postprocessors': [{
43
- 'key': 'FFmpegExtractAudio',
44
- 'preferredcodec': 'mp3',
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
-
72
  ydl_opts = {
 
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,36 +250,13 @@ def download_video(url, format_selection):
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
@@ -141,55 +264,37 @@ if st.button("Download"):
141
  if video_url:
142
  try:
143
  with st.spinner("Preparing download..."):
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
 
169
- # Add help section
170
- with st.expander("ℹ️ Help"):
171
  st.markdown("""
172
- **How to use:**
173
- 1. Paste a YouTube video URL in the input field
174
- 2. Select your preferred format
175
- 3. Click the Download button
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()
 
1
+ # import streamlit as st
2
+ # import yt_dlp
3
+ # import os
4
+ # from pathlib import Path
5
+
6
+ # # Set page config
7
+ # st.set_page_config(page_title="YouTube Video Downloader", page_icon="📺")
8
+
9
+ # # Set the title of the app
10
+ # st.title("YouTube Video Downloader 📺")
11
+
12
+ # # Create output directory if it doesn't exist
13
+ # output_dir = Path("downloads")
14
+ # output_dir.mkdir(exist_ok=True)
15
+
16
+ # # Input field for YouTube video URL
17
+ # video_url = st.text_input("Enter YouTube Video URL:", placeholder="https://www.youtube.com/watch?v=...")
18
+
19
+ # # Format selection
20
+ # format_option = st.selectbox(
21
+ # "Select Format:",
22
+ # options=[
23
+ # "Best Quality (Video + Audio)",
24
+ # "Audio Only (Best Quality)",
25
+ # "720p",
26
+ # "480p",
27
+ # "360p"
28
+ # ]
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',
42
+ # 'postprocessors': [{
43
+ # 'key': 'FFmpegExtractAudio',
44
+ # 'preferredcodec': 'mp3',
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
+
72
+ # ydl_opts = {
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
+
93
+ # def progress_hook(d):
94
+ # if d['status'] == 'downloading':
95
+ # try:
96
+ # progress = d['downloaded_bytes'] / d['total_bytes']
97
+ # progress_bar.progress(progress)
98
+ # status_text.text(f"Downloading: {progress:.1%}")
99
+ # except:
100
+ # status_text.text("Downloading... (size unknown)")
101
+ # elif d['status'] == 'finished':
102
+ # progress_bar.progress(1.0)
103
+ # status_text.text("Processing...")
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
140
+ # if st.button("Download"):
141
+ # if video_url:
142
+ # try:
143
+ # with st.spinner("Preparing download..."):
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
+
169
+ # # Add help section
170
+ # with st.expander("ℹ️ Help"):
171
+ # st.markdown("""
172
+ # **How to use:**
173
+ # 1. Paste a YouTube video URL in the input field
174
+ # 2. Select your preferred format
175
+ # 3. Click the Download button
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()
196
+
197
+
198
+
199
+
200
  import streamlit as st
201
  import yt_dlp
202
  import os
 
215
  # Input field for YouTube video URL
216
  video_url = st.text_input("Enter YouTube Video URL:", placeholder="https://www.youtube.com/watch?v=...")
217
 
218
+ # Function to download video
219
+ def download_video(url):
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
220
  try:
 
 
221
  ydl_opts = {
222
+ 'format': 'bestvideo+bestaudio/best',
223
  'outtmpl': str(output_dir / '%(title)s.%(ext)s'),
224
+ 'merge_output_format': 'webm',
225
+ # Add these options to mimic browser behavior
226
  'quiet': True,
227
  'no_warnings': True,
 
 
 
 
228
  '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',
229
  'referer': 'https://www.youtube.com/',
230
+ 'cookiefile': 'youtube.com_cookies.txt', # 쿠키 파일 사용
231
+ 'socket_timeout': 30,
232
+ 'http_chunk_size': 10485760, # 10MB
233
  }
 
 
 
234
 
235
+ # Progress placeholder
236
  progress_bar = st.progress(0)
237
  status_text = st.empty()
238
 
 
250
 
251
  ydl_opts['progress_hooks'] = [progress_hook]
252
 
 
253
  with yt_dlp.YoutubeDL(ydl_opts) as ydl:
254
+ info = ydl.extract_info(url, download=True)
255
+ filename = ydl.prepare_filename(info)
256
+ return filename
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
257
 
258
  except Exception as e:
259
+ st.error(f"An error occurred: {str(e)}")
260
  return None
261
 
262
  # Download button
 
264
  if video_url:
265
  try:
266
  with st.spinner("Preparing download..."):
267
+ downloaded_file_path = download_video(video_url)
268
 
269
  if downloaded_file_path and os.path.exists(downloaded_file_path):
270
+ with open(downloaded_file_path, 'rb') as file:
271
+ st.download_button(
272
+ label="Click here to download",
273
+ data=file,
274
+ file_name=os.path.basename(downloaded_file_path),
275
+ mime="application/octet-stream"
276
+ )
277
+ st.success("✅ Download ready!")
 
 
 
 
 
 
 
278
  else:
279
+ st.error("❌ Download failed. Please try again.")
280
  except Exception as e:
281
+ st.error(f"❌ An error occurred: {str(e)}")
282
  else:
283
  st.warning("⚠️ Please enter a valid YouTube URL.")
284
 
285
+ # Help section
286
+ with st.expander("ℹ️ Help & Troubleshooting"):
287
  st.markdown("""
288
+ **If you're experiencing download issues:**
 
 
 
 
 
289
 
290
+ 1. Cookie Authentication Method:
291
+ - Install a browser extension like "Get cookies.txt"
292
+ - Visit YouTube and ensure you're logged in
293
+ - Export cookies to 'youtube.com_cookies.txt'
294
+ - Place the file in the same directory as this app
295
+
296
+ 2. Alternative Solutions:
297
+ - Try different videos
298
+ - Check if the video is public/not age-restricted
299
+ - Try again later if YouTube is blocking requests
300
+ """)