Opera8 commited on
Commit
4937cf2
·
verified ·
1 Parent(s): 5360b57

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +58 -6
app.py CHANGED
@@ -2,11 +2,58 @@ import os
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)
12
 
@@ -128,14 +175,12 @@ def download_video():
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)
@@ -144,17 +189,24 @@ def download_video():
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:
@@ -175,7 +227,7 @@ def download_video():
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__':
 
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
  from pytubefix import YouTube
12
 
13
+ # ==========================================
14
+ # دور زدن محدودیت و قطعی DNS در هاگینگ‌فیس
15
+ # استفاده همزمان از Cloudflare DoH و Google DoH
16
+ # ==========================================
17
+ _orig_getaddrinfo = socket.getaddrinfo
18
+
19
+ def patched_getaddrinfo(host, port, family=0, type=0, proto=0, flags=0):
20
+ blocked_domains =['youtube', 'youtu.be', 'googlevideo', 'instagram', 'cdninstagram']
21
+ if host and any(d in host.lower() for d in blocked_domains):
22
+ # تلاش اول: Cloudflare DNS (امن تر و سریع تر)
23
+ try:
24
+ req = urllib.request.Request(
25
+ f"https://cloudflare-dns.com/dns-query?name={host}&type=A",
26
+ headers={'Accept': 'application/dns-json', 'User-Agent': 'Mozilla/5.0'}
27
+ )
28
+ with urllib.request.urlopen(req, timeout=5) as response:
29
+ data = json.loads(response.read().decode('utf-8'))
30
+ if 'Answer' in data:
31
+ for ans in data['Answer']:
32
+ if ans['type'] == 1:
33
+ ip = ans['data']
34
+ return[(socket.AF_INET, socket.SOCK_STREAM, 6, '', (ip, port))]
35
+ except Exception as e:
36
+ print(f"Cloudflare DNS failed for {host}: {e}")
37
+
38
+ # تلاش دوم: Google DNS (در صورت قطعی کلودفلر)
39
+ try:
40
+ url = f"https://dns.google/resolve?name={host}&type=A"
41
+ req = urllib.request.Request(url, headers={'User-Agent': 'Mozilla/5.0'})
42
+ with urllib.request.urlopen(req, timeout=5) as response:
43
+ data = json.loads(response.read().decode('utf-8'))
44
+ if 'Answer' in data:
45
+ for ans in data['Answer']:
46
+ if ans['type'] == 1:
47
+ ip = ans['data']
48
+ return[(socket.AF_INET, socket.SOCK_STREAM, 6, '', (ip, port))]
49
+ except Exception as e:
50
+ print(f"Google DNS failed for {host}: {e}")
51
+
52
+ return _orig_getaddrinfo(host, port, family, type, proto, flags)
53
+
54
+ socket.getaddrinfo = patched_getaddrinfo
55
+ # ==========================================
56
+
57
  app = Flask(__name__)
58
  CORS(app)
59
 
 
175
  final_filename = f"{file_id}.mp4"
176
  final_path = os.path.join(DOWNLOAD_FOLDER, final_filename)
177
 
 
178
  is_youtube = 'youtube.com' in url.lower() or 'youtu.be' in url.lower()
179
 
180
  try:
181
+ # روش اول: استفاده از pytubefix مخصوص دور زدن ربات یوتیوب
182
  if is_youtube:
183
  try:
 
184
  yt = YouTube(url, use_po_token=True)
185
  ys = yt.streams.get_highest_resolution()
186
  ys.download(output_path=DOWNLOAD_FOLDER, filename=final_filename)
 
189
  return send_file(final_path, as_attachment=True, download_name=f"youtube_{int(time.time())}.mp4")
190
  except Exception as yt_err:
191
  print(f"Pytubefix method failed, switching to yt-dlp... Error: {yt_err}")
 
192
  pass
193
 
194
+ # روش دوم: استفاده از yt-dlp برای اینستاگرام و سایت‌های دیگر (یا در صورت خرابی روش اول)
195
  ydl_opts = {
196
  'format': 'bestvideo[ext=mp4]+bestaudio[ext=m4a]/best[ext=mp4]/best',
197
  'outtmpl': os.path.join(DOWNLOAD_FOLDER, f"{file_id}.%(ext)s"),
198
  'quiet': True,
199
  'no_warnings': True,
200
  'merge_output_format': 'mp4',
201
+ 'force_ipv4': True, # حل قطعی مشکلات DNS و IPv6
202
+ 'source_address': '0.0.0.0',# اتصال مطمئن به سوکت
203
  'nocheckcertificate': True,
204
+ 'extractor_args': {
205
+ 'youtube': {
206
+ 'player_client': ['tv', 'android', 'ios'],
207
+ 'player_skip': ['webpage']
208
+ }
209
+ },
210
  }
211
 
212
  with yt_dlp.YoutubeDL(ydl_opts) as ydl:
 
227
  except Exception as e:
228
  error_msg = str(e)
229
  if "Sign in to confirm" in error_msg or "Private video" in error_msg:
230
+ return jsonify({'error': 'یوتیوب دسترسی به این ویدیو را مسدود کرده است.'}), 403
231
  return jsonify({'error': error_msg}), 500
232
 
233
  if __name__ == '__main__':