Opera8 commited on
Commit
5360b57
·
verified ·
1 Parent(s): 80922a7

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +39 -60
app.py CHANGED
@@ -2,38 +2,10 @@ import os
2
  import time
3
  import uuid
4
  import threading
5
- import socket
6
- import json
7
- import urllib.request
8
  from flask import Flask, request, jsonify, send_file, render_template_string
9
  from flask_cors import CORS
10
  import yt_dlp
11
-
12
- # ==========================================
13
- # دور زدن محدودیت و قطعی DNS در هاگینگ‌فیس
14
- # ==========================================
15
- _orig_getaddrinfo = socket.getaddrinfo
16
-
17
- def patched_getaddrinfo(host, port, family=0, type=0, proto=0, flags=0):
18
- blocked_domains = ['youtube', 'youtu.be', 'googlevideo', 'instagram', 'cdninstagram']
19
- if host and any(d in host.lower() for d in blocked_domains):
20
- try:
21
- url = f"https://dns.google/resolve?name={host}&type=A"
22
- req = urllib.request.Request(url, headers={'User-Agent': 'Mozilla/5.0'})
23
- with urllib.request.urlopen(req, timeout=5) as response:
24
- data = json.loads(response.read().decode('utf-8'))
25
- if 'Answer' in data:
26
- for ans in data['Answer']:
27
- if ans['type'] == 1:
28
- ip = ans['data']
29
- return [(socket.AF_INET, type or socket.SOCK_STREAM, proto or 6, '', (ip, port))]
30
- except Exception as e:
31
- print(f"DoH fallback failed for {host}: {e}")
32
-
33
- return _orig_getaddrinfo(host, port, family, type, proto, flags)
34
-
35
- socket.getaddrinfo = patched_getaddrinfo
36
- # ==========================================
37
 
38
  app = Flask(__name__)
39
  CORS(app)
@@ -105,7 +77,7 @@ HTML_TEMPLATE = """
105
  if (!url) return alert('لطفا لینک را وارد کنید');
106
 
107
  btn.disabled = true;
108
- status.innerHTML = "⏳ در حال استخراج و دانلود ویدیو از سرور اصلی...";
109
  videoContainer.style.display = 'none';
110
 
111
  try {
@@ -153,50 +125,57 @@ def download_video():
153
 
154
  url = data['url']
155
  file_id = str(uuid.uuid4())
156
- output_template = os.path.join(DOWNLOAD_FOLDER, f"{file_id}.%(ext)s")
 
157
 
158
- # استفاده از کلاینت TV برای دور زدن محدودیت لاگین
159
- ydl_opts = {
160
- 'format': 'bestvideo[ext=mp4]+bestaudio[ext=m4a]/best[ext=mp4]/best',
161
- 'outtmpl': output_template,
162
- 'quiet': True,
163
- 'no_warnings': True,
164
- 'merge_output_format': 'mp4',
165
- 'force_ipv4': True,
166
- 'nocheckcertificate': True,
167
- # هدرهای شبیه‌سازی مرورگر
168
- 'http_headers': {
169
- 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36',
170
- },
171
- # استراتژی جدید: استفاده از کلاینت TV که معمولاً نیاز به لاگین ندارد
172
- 'extractor_args': {
173
- 'youtube': {
174
- 'player_client': ['tv', 'android_creator', 'ios'],
175
- 'player_skip': ['webpage']
176
- }
177
- },
178
- }
179
 
180
  try:
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
181
  with yt_dlp.YoutubeDL(ydl_opts) as ydl:
182
  info_dict = ydl.extract_info(url, download=True)
183
  downloaded_ext = info_dict.get('ext', 'mp4')
184
- final_filename = f"{file_id}.{downloaded_ext}"
185
 
186
- if not os.path.exists(os.path.join(DOWNLOAD_FOLDER, final_filename)):
187
- final_filename = f"{file_id}.mp4"
188
 
189
- final_path = os.path.join(DOWNLOAD_FOLDER, final_filename)
190
 
191
- if os.path.exists(final_path):
192
- return send_file(final_path, as_attachment=True, download_name=f"video_{int(time.time())}.mp4")
193
  else:
194
- return jsonify({'error': 'File not found after download'}), 500
195
 
196
  except Exception as e:
197
  error_msg = str(e)
198
  if "Sign in to confirm" in error_msg or "Private video" in error_msg:
199
- return jsonify({'error': 'متاسفانه یوتیوب آی‌پی سرور را محدود کرده است (Sign-in required).'}), 403
200
  return jsonify({'error': error_msg}), 500
201
 
202
  if __name__ == '__main__':
 
2
  import time
3
  import uuid
4
  import threading
 
 
 
5
  from flask import Flask, request, jsonify, send_file, render_template_string
6
  from flask_cors import CORS
7
  import yt_dlp
8
+ from pytubefix import YouTube
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
9
 
10
  app = Flask(__name__)
11
  CORS(app)
 
77
  if (!url) return alert('لطفا لینک را وارد کنید');
78
 
79
  btn.disabled = true;
80
+ status.innerHTML = "⏳ در حال استخراج و دانلود ویدیو از سرور... (این فرآیند ممکن است کمی طول بکشد)";
81
  videoContainer.style.display = 'none';
82
 
83
  try {
 
125
 
126
  url = data['url']
127
  file_id = str(uuid.uuid4())
128
+ final_filename = f"{file_id}.mp4"
129
+ final_path = os.path.join(DOWNLOAD_FOLDER, final_filename)
130
 
131
+ # تشخیص یوتیوب بودن لینک
132
+ is_youtube = 'youtube.com' in url.lower() or 'youtu.be' in url.lower()
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
133
 
134
  try:
135
+ # 🟢 روش اول: استفاده از pytubefix مخصوص دور زدن ربات یوتیوب
136
+ if is_youtube:
137
+ try:
138
+ # گزینه use_po_token باعث فرار از خطای ربات (Sign in to confirm) می‌شود
139
+ yt = YouTube(url, use_po_token=True)
140
+ ys = yt.streams.get_highest_resolution()
141
+ ys.download(output_path=DOWNLOAD_FOLDER, filename=final_filename)
142
+
143
+ if os.path.exists(final_path):
144
+ return send_file(final_path, as_attachment=True, download_name=f"youtube_{int(time.time())}.mp4")
145
+ except Exception as yt_err:
146
+ print(f"Pytubefix method failed, switching to yt-dlp... Error: {yt_err}")
147
+ # در صورت شکست، به روش دوم (yt-dlp) هدایت می‌شود
148
+ pass
149
+
150
+ # 🟡 روش دوم: استفاده از yt-dlp برای اینستاگرام و سایت‌های دیگر
151
+ ydl_opts = {
152
+ 'format': 'bestvideo[ext=mp4]+bestaudio[ext=m4a]/best[ext=mp4]/best',
153
+ 'outtmpl': os.path.join(DOWNLOAD_FOLDER, f"{file_id}.%(ext)s"),
154
+ 'quiet': True,
155
+ 'no_warnings': True,
156
+ 'merge_output_format': 'mp4',
157
+ 'nocheckcertificate': True,
158
+ }
159
+
160
  with yt_dlp.YoutubeDL(ydl_opts) as ydl:
161
  info_dict = ydl.extract_info(url, download=True)
162
  downloaded_ext = info_dict.get('ext', 'mp4')
163
+ dl_filename = f"{file_id}.{downloaded_ext}"
164
 
165
+ if not os.path.exists(os.path.join(DOWNLOAD_FOLDER, dl_filename)):
166
+ dl_filename = final_filename
167
 
168
+ dl_path = os.path.join(DOWNLOAD_FOLDER, dl_filename)
169
 
170
+ if os.path.exists(dl_path):
171
+ return send_file(dl_path, as_attachment=True, download_name=f"video_{int(time.time())}.mp4")
172
  else:
173
+ return jsonify({'error': 'خطا در ذخیره فایل نهایی.'}), 500
174
 
175
  except Exception as e:
176
  error_msg = str(e)
177
  if "Sign in to confirm" in error_msg or "Private video" in error_msg:
178
+ return jsonify({'error': 'یوتیوب دسترسی به این ویدیو را در سرورهای ابری مسدود کرده است.'}), 403
179
  return jsonify({'error': error_msg}), 500
180
 
181
  if __name__ == '__main__':