Add option --throttled-rate below which video data is re-extracted
Currently only for HTTP downloads Closes #430, workaround for https://github.com/ytdl-org/youtube-dl/issues/29326
This commit is contained in:
parent
4c7853de14
commit
51d9739f80
6 changed files with 41 additions and 6 deletions
|
|
@ -14,6 +14,7 @@ from ..utils import (
|
|||
format_bytes,
|
||||
shell_quote,
|
||||
timeconvert,
|
||||
ThrottledDownload,
|
||||
)
|
||||
|
||||
|
||||
|
|
@ -32,6 +33,7 @@ class FileDownloader(object):
|
|||
verbose: Print additional info to stdout.
|
||||
quiet: Do not print messages to stdout.
|
||||
ratelimit: Download speed limit, in bytes/sec.
|
||||
throttledratelimit: Assume the download is being throttled below this speed (bytes/sec)
|
||||
retries: Number of times to retry for HTTP error 5xx
|
||||
buffersize: Size of download buffer in bytes.
|
||||
noresizebuffer: Do not automatically resize the download buffer.
|
||||
|
|
@ -170,7 +172,7 @@ class FileDownloader(object):
|
|||
def slow_down(self, start_time, now, byte_counter):
|
||||
"""Sleep if the download speed is over the rate limit."""
|
||||
rate_limit = self.params.get('ratelimit')
|
||||
if rate_limit is None or byte_counter == 0:
|
||||
if byte_counter == 0:
|
||||
return
|
||||
if now is None:
|
||||
now = time.time()
|
||||
|
|
@ -178,7 +180,7 @@ class FileDownloader(object):
|
|||
if elapsed <= 0.0:
|
||||
return
|
||||
speed = float(byte_counter) / elapsed
|
||||
if speed > rate_limit:
|
||||
if rate_limit is not None and speed > rate_limit:
|
||||
sleep_time = float(byte_counter) / rate_limit - elapsed
|
||||
if sleep_time > 0:
|
||||
time.sleep(sleep_time)
|
||||
|
|
|
|||
|
|
@ -18,6 +18,7 @@ from ..utils import (
|
|||
int_or_none,
|
||||
sanitize_open,
|
||||
sanitized_Request,
|
||||
ThrottledDownload,
|
||||
write_xattr,
|
||||
XAttrMetadataError,
|
||||
XAttrUnavailableError,
|
||||
|
|
@ -223,6 +224,7 @@ class HttpFD(FileDownloader):
|
|||
# measure time over whole while-loop, so slow_down() and best_block_size() work together properly
|
||||
now = None # needed for slow_down() in the first loop run
|
||||
before = start # start measuring
|
||||
throttle_start = None
|
||||
|
||||
def retry(e):
|
||||
to_stdout = ctx.tmpfilename == '-'
|
||||
|
|
@ -313,6 +315,18 @@ class HttpFD(FileDownloader):
|
|||
if data_len is not None and byte_counter == data_len:
|
||||
break
|
||||
|
||||
if speed and speed < (self.params.get('throttledratelimit') or 0):
|
||||
# The speed must stay below the limit for 3 seconds
|
||||
# This prevents raising error when the speed temporarily goes down
|
||||
if throttle_start is None:
|
||||
throttle_start = now
|
||||
elif now - throttle_start > 3:
|
||||
if ctx.stream is not None and ctx.tmpfilename != '-':
|
||||
ctx.stream.close()
|
||||
raise ThrottledDownload()
|
||||
else:
|
||||
throttle_start = None
|
||||
|
||||
if not is_test and ctx.chunk_size and ctx.data_len is not None and byte_counter < ctx.data_len:
|
||||
ctx.resume_len = byte_counter
|
||||
# ctx.block_size = block_size
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue