mirror of
https://github.com/yt-dlp/yt-dlp.git
synced 2024-11-19 14:49:15 +00:00
Support negative durations
This commit is contained in:
parent
9fc70f3f6d
commit
e6e2eb00f1
|
@ -321,25 +321,12 @@ def validate_outtmpl(tmpl, msg):
|
||||||
del opts.outtmpl['default']
|
del opts.outtmpl['default']
|
||||||
|
|
||||||
def parse_chapters(name, value):
|
def parse_chapters(name, value):
|
||||||
def parse_timestamp(x):
|
|
||||||
# FIXME: Maybe there's a better way to remove parenthesis
|
|
||||||
x = x.replace('(', '').replace(')', '')
|
|
||||||
|
|
||||||
# FIXME: This should be smarter, e.g. 'inf-1day'?
|
|
||||||
if x in ('inf', 'infinite'):
|
|
||||||
return float('inf')
|
|
||||||
|
|
||||||
if re.match(r'[\d:]+', x):
|
|
||||||
return parse_duration(x)
|
|
||||||
|
|
||||||
return datetime_from_str(x, precision='second', use_utc=False).timestamp()
|
|
||||||
|
|
||||||
chapters, ranges = [], []
|
chapters, ranges = [], []
|
||||||
|
parse_timestamp = lambda x: float('inf') if x in ('inf', 'infinite') else parse_duration(x)
|
||||||
for regex in value or []:
|
for regex in value or []:
|
||||||
if regex.startswith('*'):
|
if regex.startswith('*'):
|
||||||
for range_ in map(str.strip, regex[1:].split(',')):
|
for range_ in map(str.strip, regex[1:].split(',')):
|
||||||
# FIXME: This should match correctly '(now-1hour)-(now-20minutes)'
|
mobj = range_ != '-' and re.fullmatch(r'(-?[^-]+)?\s*-\s*(-?[^-]+)?', range_)
|
||||||
mobj = range_ != '-' and re.fullmatch(r'(.+)?\s*-\s*(.+)?', range_)
|
|
||||||
dur = mobj and (parse_timestamp(mobj.group(1) or '0'), parse_timestamp(mobj.group(2) or 'inf'))
|
dur = mobj and (parse_timestamp(mobj.group(1) or '0'), parse_timestamp(mobj.group(2) or 'inf'))
|
||||||
if None in (dur or [None]):
|
if None in (dur or [None]):
|
||||||
raise ValueError(f'invalid {name} time range "{regex}". Must be of the form "*start-end"')
|
raise ValueError(f'invalid {name} time range "{regex}". Must be of the form "*start-end"')
|
||||||
|
|
|
@ -2764,8 +2764,9 @@ def _live_dash_fragments(self, video_id, format_id, live_start_time, mpd_feed, m
|
||||||
|
|
||||||
begin_index = 0
|
begin_index = 0
|
||||||
download_start_time = ctx.get('start') or time.time()
|
download_start_time = ctx.get('start') or time.time()
|
||||||
section_start = ctx.get('section_start') or 0
|
|
||||||
section_end = ctx.get('section_end') or math.inf
|
section_start = 0 if ctx.get('section_start') is None else download_start_time + ctx['section_start']
|
||||||
|
section_end = math.inf if ctx.get('section_end') is None else download_start_time + ctx['section_end']
|
||||||
|
|
||||||
lack_early_segments = download_start_time - (live_start_time or download_start_time) > MAX_DURATION
|
lack_early_segments = download_start_time - (live_start_time or download_start_time) > MAX_DURATION
|
||||||
if lack_early_segments:
|
if lack_early_segments:
|
||||||
|
|
|
@ -2667,16 +2667,19 @@ def parse_duration(s):
|
||||||
|
|
||||||
days, hours, mins, secs, ms = [None] * 5
|
days, hours, mins, secs, ms = [None] * 5
|
||||||
m = re.match(r'''(?x)
|
m = re.match(r'''(?x)
|
||||||
|
(?P<sign>[+-])?
|
||||||
(?P<before_secs>
|
(?P<before_secs>
|
||||||
(?:(?:(?P<days>[0-9]+):)?(?P<hours>[0-9]+):)?(?P<mins>[0-9]+):)?
|
(?:(?:(?P<days>[0-9]+):)?(?P<hours>[0-9]+):)?(?P<mins>[0-9]+):)?
|
||||||
(?P<secs>(?(before_secs)[0-9]{1,2}|[0-9]+))
|
(?P<secs>(?(before_secs)[0-9]{1,2}|[0-9]+))
|
||||||
(?P<ms>[.:][0-9]+)?Z?$
|
(?P<ms>[.:][0-9]+)?Z?$
|
||||||
''', s)
|
''', s)
|
||||||
if m:
|
if m:
|
||||||
days, hours, mins, secs, ms = m.group('days', 'hours', 'mins', 'secs', 'ms')
|
sign, days, hours, mins, secs, ms = m.group('sign', 'days', 'hours', 'mins', 'secs', 'ms')
|
||||||
else:
|
else:
|
||||||
m = re.match(
|
m = re.match(
|
||||||
r'''(?ix)(?:P?
|
r'''(?ix)(?:
|
||||||
|
(?P<sign>[+-])?
|
||||||
|
P?
|
||||||
(?:
|
(?:
|
||||||
[0-9]+\s*y(?:ears?)?,?\s*
|
[0-9]+\s*y(?:ears?)?,?\s*
|
||||||
)?
|
)?
|
||||||
|
@ -2700,17 +2703,19 @@ def parse_duration(s):
|
||||||
(?P<secs>[0-9]+)(?P<ms>\.[0-9]+)?\s*s(?:ec(?:ond)?s?)?\s*
|
(?P<secs>[0-9]+)(?P<ms>\.[0-9]+)?\s*s(?:ec(?:ond)?s?)?\s*
|
||||||
)?Z?$''', s)
|
)?Z?$''', s)
|
||||||
if m:
|
if m:
|
||||||
days, hours, mins, secs, ms = m.groups()
|
sign, days, hours, mins, secs, ms = m.groups()
|
||||||
else:
|
else:
|
||||||
m = re.match(r'(?i)(?:(?P<hours>[0-9.]+)\s*(?:hours?)|(?P<mins>[0-9.]+)\s*(?:mins?\.?|minutes?)\s*)Z?$', s)
|
m = re.match(r'(?i)(?P<sign>[+-])?(?:(?P<hours>[0-9.]+)\s*(?:hours?)|(?P<mins>[0-9.]+)\s*(?:mins?\.?|minutes?)\s*)Z?$', s)
|
||||||
if m:
|
if m:
|
||||||
hours, mins = m.groups()
|
sign, hours, mins = m.groups()
|
||||||
else:
|
else:
|
||||||
return None
|
return None
|
||||||
|
|
||||||
|
sign = -1 if sign == '-' else 1
|
||||||
|
|
||||||
if ms:
|
if ms:
|
||||||
ms = ms.replace(':', '.')
|
ms = ms.replace(':', '.')
|
||||||
return sum(float(part or 0) * mult for part, mult in (
|
return sign * sum(float(part or 0) * mult for part, mult in (
|
||||||
(days, 86400), (hours, 3600), (mins, 60), (secs, 1), (ms, 1)))
|
(days, 86400), (hours, 3600), (mins, 60), (secs, 1), (ms, 1)))
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue