mirror of
				https://github.com/yt-dlp/yt-dlp.git
				synced 2025-11-04 08:35:12 +00:00 
			
		
		
		
	[utils] imporove parse_duration to handle more formats
This commit is contained in:
		@@ -405,6 +405,7 @@ class TestUtil(unittest.TestCase):
 | 
				
			|||||||
        self.assertEqual(parse_duration('01:02:03:04'), 93784)
 | 
					        self.assertEqual(parse_duration('01:02:03:04'), 93784)
 | 
				
			||||||
        self.assertEqual(parse_duration('1 hour 3 minutes'), 3780)
 | 
					        self.assertEqual(parse_duration('1 hour 3 minutes'), 3780)
 | 
				
			||||||
        self.assertEqual(parse_duration('87 Min.'), 5220)
 | 
					        self.assertEqual(parse_duration('87 Min.'), 5220)
 | 
				
			||||||
 | 
					        self.assertEqual(parse_duration('PT1H0.040S'), 3600.04)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def test_fix_xml_ampersands(self):
 | 
					    def test_fix_xml_ampersands(self):
 | 
				
			||||||
        self.assertEqual(
 | 
					        self.assertEqual(
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1540,44 +1540,46 @@ def parse_duration(s):
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    s = s.strip()
 | 
					    s = s.strip()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    days, hours, mins, secs, ms = [None] * 5
 | 
				
			||||||
 | 
					    m = re.match(r'(?:(?:(?:(?P<days>[0-9]+):)?(?P<hours>[0-9]+):)?(?P<mins>[0-9]+):)?(?P<secs>[0-9]+)(?P<ms>\.[0-9]+)?$', s)
 | 
				
			||||||
 | 
					    if m:
 | 
				
			||||||
 | 
					        days, hours, mins, secs, ms = m.groups()
 | 
				
			||||||
 | 
					    else:
 | 
				
			||||||
        m = re.match(
 | 
					        m = re.match(
 | 
				
			||||||
            r'''(?ix)(?:P?T)?
 | 
					            r'''(?ix)(?:P?T)?
 | 
				
			||||||
                (?:
 | 
					                (?:
 | 
				
			||||||
            (?P<only_mins>[0-9.]+)\s*(?:mins?\.?|minutes?)\s*|
 | 
					                    (?P<days>[0-9]+)\s*d(?:ays?)?\s*
 | 
				
			||||||
            (?P<only_hours>[0-9.]+)\s*(?:hours?)|
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            \s*(?P<hours_reversed>[0-9]+)\s*(?:[:h]|hours?)\s*(?P<mins_reversed>[0-9]+)\s*(?:[:m]|mins?\.?|minutes?)\s*|
 | 
					 | 
				
			||||||
            (?:
 | 
					 | 
				
			||||||
                (?:
 | 
					 | 
				
			||||||
                    (?:(?P<days>[0-9]+)\s*(?:[:d]|days?)\s*)?
 | 
					 | 
				
			||||||
                    (?P<hours>[0-9]+)\s*(?:[:h]|hours?)\s*
 | 
					 | 
				
			||||||
                )?
 | 
					                )?
 | 
				
			||||||
                (?P<mins>[0-9]+)\s*(?:[:m]|mins?|minutes?)\s*
 | 
					                (?:
 | 
				
			||||||
 | 
					                    (?P<hours>[0-9]+)\s*h(?:ours?)?\s*
 | 
				
			||||||
                )?
 | 
					                )?
 | 
				
			||||||
            (?P<secs>[0-9]+)(?P<ms>\.[0-9]+)?\s*(?:s|secs?|seconds?)?
 | 
					                (?:
 | 
				
			||||||
        )$''', s)
 | 
					                    (?P<mins>[0-9]+)\s*m(?:in(?:ute)?s?)?\s*
 | 
				
			||||||
    if not m:
 | 
					                )?
 | 
				
			||||||
 | 
					                (?:
 | 
				
			||||||
 | 
					                    (?P<secs>[0-9]+)(?P<ms>\.[0-9]+)?\s*s(?:ec(?:ond)?s?)?\s*
 | 
				
			||||||
 | 
					                )?$''', s)
 | 
				
			||||||
 | 
					        if m:
 | 
				
			||||||
 | 
					            days, hours, mins, secs, ms = m.groups()
 | 
				
			||||||
 | 
					        else:
 | 
				
			||||||
 | 
					            m = re.match(r'(?i)(?:(?P<hours>[0-9.]+)\s*(?:hours?)|(?P<mins>[0-9.]+)\s*(?:mins?\.?|minutes?)\s*)$', s)
 | 
				
			||||||
 | 
					            if m:
 | 
				
			||||||
 | 
					                hours, mins = m.groups()
 | 
				
			||||||
 | 
					            else:
 | 
				
			||||||
                return None
 | 
					                return None
 | 
				
			||||||
    res = 0
 | 
					
 | 
				
			||||||
    if m.group('only_mins'):
 | 
					    duration = 0
 | 
				
			||||||
        return float_or_none(m.group('only_mins'), invscale=60)
 | 
					    if secs:
 | 
				
			||||||
    if m.group('only_hours'):
 | 
					        duration += float(secs)
 | 
				
			||||||
        return float_or_none(m.group('only_hours'), invscale=60 * 60)
 | 
					    if mins:
 | 
				
			||||||
    if m.group('secs'):
 | 
					        duration += float(mins) * 60
 | 
				
			||||||
        res += int(m.group('secs'))
 | 
					    if hours:
 | 
				
			||||||
    if m.group('mins_reversed'):
 | 
					        duration += float(hours) * 60 * 60
 | 
				
			||||||
        res += int(m.group('mins_reversed')) * 60
 | 
					    if days:
 | 
				
			||||||
    if m.group('mins'):
 | 
					        duration += float(days) * 24 * 60 * 60
 | 
				
			||||||
        res += int(m.group('mins')) * 60
 | 
					    if ms:
 | 
				
			||||||
    if m.group('hours'):
 | 
					        duration += float(ms)
 | 
				
			||||||
        res += int(m.group('hours')) * 60 * 60
 | 
					    return duration
 | 
				
			||||||
    if m.group('hours_reversed'):
 | 
					 | 
				
			||||||
        res += int(m.group('hours_reversed')) * 60 * 60
 | 
					 | 
				
			||||||
    if m.group('days'):
 | 
					 | 
				
			||||||
        res += int(m.group('days')) * 24 * 60 * 60
 | 
					 | 
				
			||||||
    if m.group('ms'):
 | 
					 | 
				
			||||||
        res += float(m.group('ms'))
 | 
					 | 
				
			||||||
    return res
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
def prepend_extension(filename, ext, expected_real_ext=None):
 | 
					def prepend_extension(filename, ext, expected_real_ext=None):
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user