aboutsummaryrefslogtreecommitdiffstats
path: root/yt_dlp/downloader
diff options
context:
space:
mode:
Diffstat (limited to 'yt_dlp/downloader')
-rw-r--r--yt_dlp/downloader/common.py18
-rw-r--r--yt_dlp/downloader/external.py1
-rw-r--r--yt_dlp/downloader/fragment.py5
3 files changed, 18 insertions, 6 deletions
diff --git a/yt_dlp/downloader/common.py b/yt_dlp/downloader/common.py
index 465b5ef99..0b3383071 100644
--- a/yt_dlp/downloader/common.py
+++ b/yt_dlp/downloader/common.py
@@ -19,6 +19,7 @@ from ..utils import (
encodeFilename,
error_to_compat_str,
format_bytes,
+ int_or_none,
sanitize_open,
shell_quote,
timeconvert,
@@ -64,6 +65,7 @@ class FileDownloader:
useful for bypassing bandwidth throttling imposed by
a webserver (experimental)
progress_template: See YoutubeDL.py
+ retry_sleep_functions: See YoutubeDL.py
Subclasses of this one must re-define the real_download method.
"""
@@ -98,6 +100,8 @@ class FileDownloader:
def to_screen(self, *args, **kargs):
self.ydl.to_screen(*args, quiet=self.params.get('quiet'), **kargs)
+ __to_screen = to_screen
+
@property
def FD_NAME(self):
return re.sub(r'(?<!^)(?=[A-Z])', '_', type(self).__name__[:-2]).lower()
@@ -232,7 +236,8 @@ class FileDownloader:
self.to_screen(
f'[download] Unable to {action} file due to file access error. '
f'Retrying (attempt {retry} of {self.format_retries(file_access_retries)}) ...')
- time.sleep(0.01)
+ if not self.sleep_retry('file_access', retry):
+ time.sleep(0.01)
return inner
return outer
@@ -390,14 +395,23 @@ class FileDownloader:
def report_retry(self, err, count, retries):
"""Report retry in case of HTTP error 5xx"""
- self.to_screen(
+ self.__to_screen(
'[download] Got server HTTP error: %s. Retrying (attempt %d of %s) ...'
% (error_to_compat_str(err), count, self.format_retries(retries)))
+ self.sleep_retry('http', count)
def report_unable_to_resume(self):
"""Report it was impossible to resume download."""
self.to_screen('[download] Unable to resume')
+ def sleep_retry(self, retry_type, count):
+ sleep_func = self.params.get('retry_sleep_functions', {}).get(retry_type)
+ delay = int_or_none(sleep_func(n=count - 1)) if sleep_func else None
+ if delay:
+ self.__to_screen(f'Sleeping {delay} seconds ...')
+ time.sleep(delay)
+ return sleep_func is not None
+
@staticmethod
def supports_manifest(manifest):
""" Whether the downloader can download the fragments from the manifest.
diff --git a/yt_dlp/downloader/external.py b/yt_dlp/downloader/external.py
index 85c6a6977..812eb45b4 100644
--- a/yt_dlp/downloader/external.py
+++ b/yt_dlp/downloader/external.py
@@ -142,6 +142,7 @@ class ExternalFD(FragmentFD):
self.to_screen(
'[%s] Got error. Retrying fragments (attempt %d of %s)...'
% (self.get_basename(), count, self.format_retries(fragment_retries)))
+ self.sleep_retry('fragment', count)
if count > fragment_retries:
if not skip_unavailable_fragments:
self.report_error('Giving up after %s fragment retries' % fragment_retries)
diff --git a/yt_dlp/downloader/fragment.py b/yt_dlp/downloader/fragment.py
index 4655f067f..410c8c1a4 100644
--- a/yt_dlp/downloader/fragment.py
+++ b/yt_dlp/downloader/fragment.py
@@ -25,10 +25,6 @@ class HttpQuietDownloader(HttpFD):
console_title = to_screen
- def report_retry(self, err, count, retries):
- super().to_screen(
- f'[download] Got server HTTP error: {err}. Retrying (attempt {count} of {self.format_retries(retries)}) ...')
-
class FragmentFD(FileDownloader):
"""
@@ -70,6 +66,7 @@ class FragmentFD(FileDownloader):
self.to_screen(
'\r[download] Got server HTTP error: %s. Retrying fragment %d (attempt %d of %s) ...'
% (error_to_compat_str(err), frag_index, count, self.format_retries(retries)))
+ self.sleep_retry('fragment', count)
def report_skip_fragment(self, frag_index, err=None):
err = f' {err};' if err else ''