diff --git a/yt_dlp/__init__.py b/yt_dlp/__init__.py index 81c970b72..4aa9dca8e 100644 --- a/yt_dlp/__init__.py +++ b/yt_dlp/__init__.py @@ -321,25 +321,12 @@ def validate_outtmpl(tmpl, msg): del opts.outtmpl['default'] 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 = [], [] + parse_timestamp = lambda x: float('inf') if x in ('inf', 'infinite') else parse_duration(x) for regex in value or []: if regex.startswith('*'): 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')) if None in (dur or [None]): raise ValueError(f'invalid {name} time range "{regex}". Must be of the form "*start-end"') diff --git a/yt_dlp/extractor/youtube.py b/yt_dlp/extractor/youtube.py index cc0b5401d..a0f93b2a8 100644 --- a/yt_dlp/extractor/youtube.py +++ b/yt_dlp/extractor/youtube.py @@ -2764,8 +2764,9 @@ def _live_dash_fragments(self, video_id, format_id, live_start_time, mpd_feed, m begin_index = 0 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 if lack_early_segments: diff --git a/yt_dlp/utils.py b/yt_dlp/utils.py index ed7516967..07bc3f5a0 100644 --- a/yt_dlp/utils.py +++ b/yt_dlp/utils.py @@ -2667,16 +2667,19 @@ def parse_duration(s): days, hours, mins, secs, ms = [None] * 5 m = re.match(r'''(?x) + (?P[+-])? (?P (?:(?:(?P[0-9]+):)?(?P[0-9]+):)?(?P[0-9]+):)? (?P(?(before_secs)[0-9]{1,2}|[0-9]+)) (?P[.:][0-9]+)?Z?$ ''', s) 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: m = re.match( - r'''(?ix)(?:P? + r'''(?ix)(?: + (?P[+-])? + P? (?: [0-9]+\s*y(?:ears?)?,?\s* )? @@ -2700,17 +2703,19 @@ def parse_duration(s): (?P[0-9]+)(?P\.[0-9]+)?\s*s(?:ec(?:ond)?s?)?\s* )?Z?$''', s) if m: - days, hours, mins, secs, ms = m.groups() + sign, days, hours, mins, secs, ms = m.groups() else: - m = re.match(r'(?i)(?:(?P[0-9.]+)\s*(?:hours?)|(?P[0-9.]+)\s*(?:mins?\.?|minutes?)\s*)Z?$', s) + m = re.match(r'(?i)(?P[+-])?(?:(?P[0-9.]+)\s*(?:hours?)|(?P[0-9.]+)\s*(?:mins?\.?|minutes?)\s*)Z?$', s) if m: - hours, mins = m.groups() + sign, hours, mins = m.groups() else: return None + sign = -1 if sign == '-' else 1 + if ms: 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)))