lexicalspace commited on
Commit
1c74eed
·
verified ·
1 Parent(s): 37ea118

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +43 -51
app.py CHANGED
@@ -1,25 +1,9 @@
1
- import socket
2
  import streamlit as st
3
-
4
- # ==========================================
5
- # 🛑 CRITICAL NETWORK FIX (Must be at top)
6
- # ==========================================
7
- # This hack forces the server to ignore IPv6 completely.
8
- # It fixes the "[Errno -5] No address associated with hostname" error.
9
- try:
10
- _old_getaddrinfo = socket.getaddrinfo
11
- def _new_getaddrinfo(*args, **kwargs):
12
- responses = _old_getaddrinfo(*args, **kwargs)
13
- # Filter out IPv6 (AF_INET6) and keep only IPv4 (AF_INET)
14
- return [r for r in responses if r[0] == socket.AF_INET]
15
- socket.getaddrinfo = _new_getaddrinfo
16
- except Exception as e:
17
- pass
18
- # ==========================================
19
-
20
- import yt_dlp
21
  import os
22
  import time
 
 
 
23
  from PIL import Image
24
  import io
25
  import re
@@ -46,11 +30,11 @@ app_mode = st.sidebar.radio(
46
  )
47
 
48
  # ==========================================
49
- # VIEW 1: YOUTUBE DOWNLOADER
50
  # ==========================================
51
  if app_mode == "YouTube Downloader":
52
  st.title("🎥 YouTube Media Extractor")
53
- st.info("Download Video (1080p) or Audio (MP3) instantly.")
54
 
55
  url = st.text_input("Paste YouTube URL", placeholder="https://youtube.com/watch?v=...")
56
 
@@ -60,53 +44,61 @@ if app_mode == "YouTube Downloader":
60
 
61
  if url and st.button("🚀 Process Media"):
62
  status_area = st.empty()
63
- status_area.info("⏳ Fetching metadata... (This may take 10-20s)")
64
 
65
  try:
66
- timestamp = int(time.time())
67
- out_tmpl = f"{timestamp}_%(title)s.%(ext)s"
68
 
69
- # UPDATED OPTIONS: Using built-in cookies and aggressive timeouts
70
- ydl_opts = {
71
- 'outtmpl': out_tmpl,
72
- 'format': 'bestvideo[ext=mp4]+bestaudio[ext=m4a]/best[ext=mp4]/best' if format_type == "Video (MP4)" else 'bestaudio/best',
73
- 'postprocessors': [{
74
- 'key': 'FFmpegExtractAudio',
75
- 'preferredcodec': 'mp3',
76
- 'preferredquality': '192',
77
- }] if "Audio" in format_type else [],
78
- 'quiet': True,
79
- 'no_warnings': True,
80
- 'noplaylist': True,
81
- 'socket_timeout': 10, # Prevent hanging
82
- }
83
 
84
- with yt_dlp.YoutubeDL(ydl_opts) as ydl:
85
- info = ydl.extract_info(url, download=True)
86
- downloaded_file = ydl.prepare_filename(info)
 
 
 
 
 
 
 
 
87
 
88
- if "Audio" in format_type:
89
- base, ext = os.path.splitext(downloaded_file)
90
- downloaded_file = base + ".mp3"
 
91
 
92
- if os.path.exists(downloaded_file):
93
- status_area.success("✅ Done!")
 
94
 
95
- with open(downloaded_file, "rb") as f:
96
  file_bytes = f.read()
97
  st.download_button(
98
  label=f"⬇️ Download {format_type}",
99
  data=file_bytes,
100
- file_name=os.path.basename(downloaded_file),
101
  mime="video/mp4" if "Video" in format_type else "audio/mpeg"
102
  )
103
 
104
  # Cleanup
105
- os.remove(downloaded_file)
106
  else:
107
- st.error("File not found. Please try again.")
108
-
 
 
 
 
109
  except Exception as e:
 
110
  st.error(f"Error: {str(e)}")
111
 
112
  # ==========================================
 
 
1
  import streamlit as st
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2
  import os
3
  import time
4
+ from pytube import YouTube
5
+ from pytube.exceptions import RegexMatchError, VideoUnavailable
6
+ import ffmpeg
7
  from PIL import Image
8
  import io
9
  import re
 
30
  )
31
 
32
  # ==========================================
33
+ # VIEW 1: YOUTUBE DOWNLOADER (Pytube Version)
34
  # ==========================================
35
  if app_mode == "YouTube Downloader":
36
  st.title("🎥 YouTube Media Extractor")
37
+ st.info("Download Video (720p/1080p) or Audio (MP3).")
38
 
39
  url = st.text_input("Paste YouTube URL", placeholder="https://youtube.com/watch?v=...")
40
 
 
44
 
45
  if url and st.button("🚀 Process Media"):
46
  status_area = st.empty()
47
+ status_area.info("⏳ Connecting to YouTube...")
48
 
49
  try:
50
+ # 1. Initialize Pytube Object
51
+ yt = YouTube(url)
52
 
53
+ # This triggers the network call - if it fails here, the IP is blocked.
54
+ video_title = yt.title
55
+ status_area.info(f"✅ Found: {video_title}")
56
+
57
+ timestamp = int(time.time())
58
+ filename = f"{timestamp}_{re.sub(r'[^a-zA-Z0-9]', '', video_title)}"
59
+ final_path = ""
 
 
 
 
 
 
 
60
 
61
+ # 2. Download Logic
62
+ if format_type == "Video (MP4)":
63
+ # Get highest resolution progressive stream (audio+video combined)
64
+ # Pytube progressive streams are usually max 720p but safest/most stable
65
+ stream = yt.streams.filter(progressive=True, file_extension='mp4').order_by('resolution').desc().first()
66
+ final_path = stream.download(filename=filename + ".mp4")
67
+
68
+ else: # Audio Only
69
+ # Get audio only stream
70
+ stream = yt.streams.filter(only_audio=True).first()
71
+ downloaded_file = stream.download(filename=filename + ".mp4")
72
 
73
+ # Rename to mp3 (Pytube downloads audio as mp4/webm container)
74
+ base, ext = os.path.splitext(downloaded_file)
75
+ final_path = base + ".mp3"
76
+ os.rename(downloaded_file, final_path)
77
 
78
+ # 3. Serve File
79
+ if os.path.exists(final_path):
80
+ status_area.success("✅ Download Ready!")
81
 
82
+ with open(final_path, "rb") as f:
83
  file_bytes = f.read()
84
  st.download_button(
85
  label=f"⬇️ Download {format_type}",
86
  data=file_bytes,
87
+ file_name=os.path.basename(final_path),
88
  mime="video/mp4" if "Video" in format_type else "audio/mpeg"
89
  )
90
 
91
  # Cleanup
92
+ os.remove(final_path)
93
  else:
94
+ st.error("Processing failed during save.")
95
+
96
+ except RegexMatchError:
97
+ st.error("Invalid URL. Please check the link.")
98
+ except VideoUnavailable:
99
+ st.error("Video is unavailable (Private or Region Blocked).")
100
  except Exception as e:
101
+ # If this prints a network error again, the server IP is definitely banned.
102
  st.error(f"Error: {str(e)}")
103
 
104
  # ==========================================