[extractor/common] Fix initialization template (closes #11605, closes #11825)

pull/11817/merge
Sergey M․ 2017-01-29 06:57:39 +07:00
parent c58c2d63cb
commit e228616c6e
No known key found for this signature in database
GPG Key ID: 2C393E0F18A9236D
1 changed files with 34 additions and 14 deletions

View File

@ -1637,12 +1637,12 @@ class InfoExtractor(object):
segment_template = element.find(_add_ns('SegmentTemplate')) segment_template = element.find(_add_ns('SegmentTemplate'))
if segment_template is not None: if segment_template is not None:
extract_common(segment_template) extract_common(segment_template)
media_template = segment_template.get('media') media = segment_template.get('media')
if media_template: if media:
ms_info['media_template'] = media_template ms_info['media'] = media
initialization = segment_template.get('initialization') initialization = segment_template.get('initialization')
if initialization: if initialization:
ms_info['initialization_url'] = initialization ms_info['initialization'] = initialization
else: else:
extract_Initialization(segment_template) extract_Initialization(segment_template)
return ms_info return ms_info
@ -1686,6 +1686,7 @@ class InfoExtractor(object):
lang = representation_attrib.get('lang') lang = representation_attrib.get('lang')
url_el = representation.find(_add_ns('BaseURL')) url_el = representation.find(_add_ns('BaseURL'))
filesize = int_or_none(url_el.attrib.get('{http://youtube.com/yt/2012/10/10}contentLength') if url_el is not None else None) filesize = int_or_none(url_el.attrib.get('{http://youtube.com/yt/2012/10/10}contentLength') if url_el is not None else None)
bandwidth = int_or_none(representation_attrib.get('bandwidth'))
f = { f = {
'format_id': '%s-%s' % (mpd_id, representation_id) if mpd_id else representation_id, 'format_id': '%s-%s' % (mpd_id, representation_id) if mpd_id else representation_id,
'url': base_url, 'url': base_url,
@ -1693,7 +1694,7 @@ class InfoExtractor(object):
'ext': mimetype2ext(mime_type), 'ext': mimetype2ext(mime_type),
'width': int_or_none(representation_attrib.get('width')), 'width': int_or_none(representation_attrib.get('width')),
'height': int_or_none(representation_attrib.get('height')), 'height': int_or_none(representation_attrib.get('height')),
'tbr': int_or_none(representation_attrib.get('bandwidth'), 1000), 'tbr': int_or_none(bandwidth, 1000),
'asr': int_or_none(representation_attrib.get('audioSamplingRate')), 'asr': int_or_none(representation_attrib.get('audioSamplingRate')),
'fps': int_or_none(representation_attrib.get('frameRate')), 'fps': int_or_none(representation_attrib.get('frameRate')),
'language': lang if lang not in ('mul', 'und', 'zxx', 'mis') else None, 'language': lang if lang not in ('mul', 'und', 'zxx', 'mis') else None,
@ -1702,13 +1703,32 @@ class InfoExtractor(object):
} }
f.update(parse_codecs(representation_attrib.get('codecs'))) f.update(parse_codecs(representation_attrib.get('codecs')))
representation_ms_info = extract_multisegment_info(representation, adaption_set_ms_info) representation_ms_info = extract_multisegment_info(representation, adaption_set_ms_info)
if 'segment_urls' not in representation_ms_info and 'media_template' in representation_ms_info:
media_template = representation_ms_info['media_template'] def prepare_template(template_name, identifiers):
media_template = media_template.replace('$RepresentationID$', representation_id) t = representation_ms_info[template_name]
media_template = re.sub(r'\$(Number|Bandwidth|Time)\$', r'%(\1)d', media_template) t = t.replace('$RepresentationID$', representation_id)
media_template = re.sub(r'\$(Number|Bandwidth|Time)%([^$]+)\$', r'%(\1)\2', media_template) t = re.sub(r'\$(%s)\$' % '|'.join(identifiers), r'%(\1)d', t)
media_template.replace('$$', '$') t = re.sub(r'\$(%s)%%([^$]+)\$' % '|'.join(identifiers), r'%(\1)\2', t)
t.replace('$$', '$')
return t
# @initialization is a regular template like @media one
# so it should be handled just the same way (see
# https://github.com/rg3/youtube-dl/issues/11605)
if 'initialization' in representation_ms_info:
initialization_template = prepare_template(
'initialization',
# As per [1, 5.3.9.4.2, Table 15, page 54] $Number$ and
# $Time$ shall not be included for @initialization thus
# only $Bandwidth$ remains
('Bandwidth', ))
representation_ms_info['initialization_url'] = initialization_template % {
'Bandwidth': bandwidth,
}
if 'segment_urls' not in representation_ms_info and 'media' in representation_ms_info:
media_template = prepare_template('media', ('Number', 'Bandwidth', 'Time'))
# As per [1, 5.3.9.4.4, Table 16, page 55] $Number$ and $Time$ # As per [1, 5.3.9.4.4, Table 16, page 55] $Number$ and $Time$
# can't be used at the same time # can't be used at the same time
@ -1720,7 +1740,7 @@ class InfoExtractor(object):
representation_ms_info['fragments'] = [{ representation_ms_info['fragments'] = [{
'url': media_template % { 'url': media_template % {
'Number': segment_number, 'Number': segment_number,
'Bandwidth': int_or_none(representation_attrib.get('bandwidth')), 'Bandwidth': bandwidth,
}, },
'duration': segment_duration, 'duration': segment_duration,
} for segment_number in range( } for segment_number in range(
@ -1738,7 +1758,7 @@ class InfoExtractor(object):
def add_segment_url(): def add_segment_url():
segment_url = media_template % { segment_url = media_template % {
'Time': segment_time, 'Time': segment_time,
'Bandwidth': int_or_none(representation_attrib.get('bandwidth')), 'Bandwidth': bandwidth,
'Number': segment_number, 'Number': segment_number,
} }
representation_ms_info['fragments'].append({ representation_ms_info['fragments'].append({
@ -1780,7 +1800,7 @@ class InfoExtractor(object):
'protocol': 'http_dash_segments', 'protocol': 'http_dash_segments',
}) })
if 'initialization_url' in representation_ms_info: if 'initialization_url' in representation_ms_info:
initialization_url = representation_ms_info['initialization_url'].replace('$RepresentationID$', representation_id) initialization_url = representation_ms_info['initialization_url']
if not f.get('url'): if not f.get('url'):
f['url'] = initialization_url f['url'] = initialization_url
f['fragments'].append({'url': initialization_url}) f['fragments'].append({'url': initialization_url})