Spaces:
Runtime error
Runtime error
Update app.py
Browse files
app.py
CHANGED
@@ -378,7 +378,7 @@ class SessionManager:
|
|
378 |
return session
|
379 |
|
380 |
def get_download_options(session_headers=None):
|
381 |
-
"""Enhanced download options with anti-bot measures"""
|
382 |
options = {
|
383 |
'format': 'bestvideo[ext=mp4]+bestaudio[ext=m4a]/best[ext=mp4]/best',
|
384 |
'outtmpl': str(Config.OUTPUT_DIR / '%(title)s.%(ext)s'),
|
@@ -387,16 +387,24 @@ def get_download_options(session_headers=None):
|
|
387 |
'no_warnings': True,
|
388 |
'extract_flat': False,
|
389 |
'nocheckcertificate': True,
|
390 |
-
'http_chunk_size': random.randint(10000000, 15000000),
|
391 |
'retries': Config.MAX_RETRIES,
|
392 |
'file_access_retries': 3,
|
393 |
'fragment_retries': 3,
|
394 |
'skip_unavailable_fragments': True,
|
395 |
'abort_on_unavailable_fragment': False,
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
396 |
}
|
397 |
|
398 |
if os.path.exists(Config.COOKIES_FILE):
|
399 |
options['cookiefile'] = Config.COOKIES_FILE
|
|
|
400 |
|
401 |
if session_headers:
|
402 |
options['headers'] = session_headers
|
@@ -404,10 +412,15 @@ def get_download_options(session_headers=None):
|
|
404 |
return options
|
405 |
|
406 |
def download_with_retry(url, progress_callback):
|
407 |
-
"""Enhanced download function with
|
|
|
408 |
for attempt in range(Config.MAX_RETRIES):
|
409 |
try:
|
410 |
-
|
|
|
|
|
|
|
|
|
411 |
ydl_opts = get_download_options(session.headers)
|
412 |
|
413 |
def progress_hook(d):
|
@@ -422,30 +435,41 @@ def download_with_retry(url, progress_callback):
|
|
422 |
|
423 |
ydl_opts['progress_hooks'] = [progress_hook]
|
424 |
|
425 |
-
#
|
426 |
with yt_dlp.YoutubeDL(ydl_opts) as ydl:
|
427 |
-
|
428 |
-
|
429 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
430 |
|
431 |
-
except yt_dlp.utils.ExtractorError as e:
|
432 |
-
error_msg = str(e)
|
433 |
-
if "Sign in to confirm you're not a bot" in error_msg:
|
434 |
-
delay = Config.RETRY_DELAYS[min(attempt, len(Config.RETRY_DELAYS)-1)]
|
435 |
-
progress_callback(-1, f"Bot detection encountered. Waiting {delay}s before retry...")
|
436 |
-
time.sleep(delay)
|
437 |
-
continue
|
438 |
-
|
439 |
-
if "Video unavailable" in error_msg:
|
440 |
-
return None, "The video is unavailable or may be region-locked."
|
441 |
-
|
442 |
-
return None, f"Video extraction failed: {error_msg}"
|
443 |
-
|
444 |
except Exception as e:
|
445 |
error_msg = str(e)
|
446 |
if attempt < Config.MAX_RETRIES - 1:
|
447 |
delay = Config.RETRY_DELAYS[attempt]
|
448 |
-
progress_callback(-1, f"
|
449 |
time.sleep(delay)
|
450 |
continue
|
451 |
return None, f"Download failed after {Config.MAX_RETRIES} attempts: {error_msg}"
|
|
|
378 |
return session
|
379 |
|
380 |
def get_download_options(session_headers=None):
|
381 |
+
"""Enhanced download options with stronger anti-bot measures"""
|
382 |
options = {
|
383 |
'format': 'bestvideo[ext=mp4]+bestaudio[ext=m4a]/best[ext=mp4]/best',
|
384 |
'outtmpl': str(Config.OUTPUT_DIR / '%(title)s.%(ext)s'),
|
|
|
387 |
'no_warnings': True,
|
388 |
'extract_flat': False,
|
389 |
'nocheckcertificate': True,
|
390 |
+
'http_chunk_size': random.randint(10000000, 15000000),
|
391 |
'retries': Config.MAX_RETRIES,
|
392 |
'file_access_retries': 3,
|
393 |
'fragment_retries': 3,
|
394 |
'skip_unavailable_fragments': True,
|
395 |
'abort_on_unavailable_fragment': False,
|
396 |
+
# ์ถ๊ฐ๋ ์ต์
๋ค
|
397 |
+
'sleep_interval': random.randint(1, 3), # ์์ฒญ ์ฌ์ด์ ๋๋ค ๋๊ธฐ ์๊ฐ
|
398 |
+
'max_sleep_interval': 5,
|
399 |
+
'sleep_interval_requests': 1,
|
400 |
+
'socket_timeout': 30,
|
401 |
+
'geo_bypass': True, # ์ง์ญ ์ ํ ์ฐํ ์๋
|
402 |
+
'geo_bypass_country': 'US', # ๋ฏธ๊ตญ ์๋ฒ ์ฌ์ฉ
|
403 |
}
|
404 |
|
405 |
if os.path.exists(Config.COOKIES_FILE):
|
406 |
options['cookiefile'] = Config.COOKIES_FILE
|
407 |
+
options['cookiesfrombrowser'] = ('chrome',) # ํฌ๋กฌ ๋ธ๋ผ์ฐ์ ์ฟ ํค ์ฌ์ฉ
|
408 |
|
409 |
if session_headers:
|
410 |
options['headers'] = session_headers
|
|
|
412 |
return options
|
413 |
|
414 |
def download_with_retry(url, progress_callback):
|
415 |
+
"""Enhanced download function with improved retry logic"""
|
416 |
+
session = None
|
417 |
for attempt in range(Config.MAX_RETRIES):
|
418 |
try:
|
419 |
+
if not session:
|
420 |
+
session = SessionManager.get_session()
|
421 |
+
|
422 |
+
# ๋งค ์๋๋ง๋ค ์๋ก์ด ํค๋ ์ฌ์ฉ
|
423 |
+
session.headers.update(SessionManager.get_random_headers())
|
424 |
ydl_opts = get_download_options(session.headers)
|
425 |
|
426 |
def progress_hook(d):
|
|
|
435 |
|
436 |
ydl_opts['progress_hooks'] = [progress_hook]
|
437 |
|
438 |
+
# ๋น๋์ค ์ ๋ณด ๋จผ์ ํ์ธ
|
439 |
with yt_dlp.YoutubeDL(ydl_opts) as ydl:
|
440 |
+
try:
|
441 |
+
info = ydl.extract_info(url, download=False)
|
442 |
+
if not info:
|
443 |
+
return None, "Failed to extract video information"
|
444 |
+
|
445 |
+
# ์ค์ ๋ค์ด๋ก๋ ์งํ
|
446 |
+
info = ydl.extract_info(url, download=True)
|
447 |
+
filename = ydl.prepare_filename(info)
|
448 |
+
return filename, None
|
449 |
+
|
450 |
+
except yt_dlp.utils.ExtractorError as e:
|
451 |
+
if "Sign in to confirm you're not a bot" in str(e):
|
452 |
+
# ๋ด ๊ฐ์ง์ ๋ ๊ธด ๋๊ธฐ ์๊ฐ ์ ์ฉ
|
453 |
+
delay = Config.RETRY_DELAYS[min(attempt, len(Config.RETRY_DELAYS)-1)] * 2
|
454 |
+
progress_callback(-1, f"Bot detection... Waiting {delay}s (Attempt {attempt + 1}/{Config.MAX_RETRIES})")
|
455 |
+
time.sleep(delay)
|
456 |
+
|
457 |
+
# ์ธ์
๋ฆฌ์
|
458 |
+
session = None
|
459 |
+
continue
|
460 |
+
|
461 |
+
if "Video unavailable" in str(e):
|
462 |
+
# ๋ค๋ฅธ ์ง์ญ์์ ์๋
|
463 |
+
ydl_opts['geo_bypass_country'] = random.choice(['US', 'GB', 'JP', 'KR', 'DE'])
|
464 |
+
continue
|
465 |
+
|
466 |
+
raise e
|
467 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
468 |
except Exception as e:
|
469 |
error_msg = str(e)
|
470 |
if attempt < Config.MAX_RETRIES - 1:
|
471 |
delay = Config.RETRY_DELAYS[attempt]
|
472 |
+
progress_callback(-1, f"Error: {error_msg}\nRetrying in {delay}s... ({attempt + 1}/{Config.MAX_RETRIES})")
|
473 |
time.sleep(delay)
|
474 |
continue
|
475 |
return None, f"Download failed after {Config.MAX_RETRIES} attempts: {error_msg}"
|