return prs, player_url
def _extract_formats(self, streaming_data, video_id, player_url, is_live):
- itags, stream_ids = [], []
+ itags, stream_ids = {}, []
itag_qualities, res_qualities = {}, {}
q = qualities([
# Normally tiny is the smallest video-only formats. But
throttled = True
if itag:
- itags.append(itag)
+ itags[itag] = 'https'
stream_ids.append(stream_id)
tbr = float_or_none(
and 'dash' not in skip_manifests and self.get_param('youtube_include_dash_manifest', True))
get_hls = 'hls' not in skip_manifests and self.get_param('youtube_include_hls_manifest', True)
- def guess_quality(f):
- for val, qdict in ((f.get('format_id'), itag_qualities), (f.get('height'), res_qualities)):
- if val in qdict:
- return q(qdict[val])
- return -1
+ def process_manifest_format(f, proto, itag):
+ if itag in itags:
+ if itags[itag] == proto or f'{itag}-{proto}' in itags:
+ return False
+ itag = f'{itag}-{proto}'
+ if itag:
+ f['format_id'] = itag
+ itags[itag] = proto
+
+ f['quality'] = next((
+ q(qdict[val])
+ for val, qdict in ((f.get('format_id'), itag_qualities), (f.get('height'), res_qualities))
+ if val in qdict), -1)
+ return True
for sd in streaming_data:
hls_manifest_url = get_hls and sd.get('hlsManifestUrl')
if hls_manifest_url:
for f in self._extract_m3u8_formats(hls_manifest_url, video_id, 'mp4', fatal=False):
- itag = self._search_regex(
- r'/itag/(\d+)', f['url'], 'itag', default=None)
- if itag in itags:
- itag += '-hls'
- if itag in itags:
- continue
- if itag:
- f['format_id'] = itag
- itags.append(itag)
- f['quality'] = guess_quality(f)
- yield f
+ if process_manifest_format(f, 'hls', self._search_regex(
+ r'/itag/(\d+)', f['url'], 'itag', default=None)):
+ yield f
dash_manifest_url = get_dash and sd.get('dashManifestUrl')
if dash_manifest_url:
for f in self._extract_mpd_formats(dash_manifest_url, video_id, fatal=False):
- itag = f['format_id']
- if itag in itags:
- itag += '-dash'
- if itag in itags:
- continue
- if itag:
- f['format_id'] = itag
- itags.append(itag)
- f['quality'] = guess_quality(f)
- filesize = int_or_none(self._search_regex(
- r'/clen/(\d+)', f.get('fragment_base_url')
- or f['url'], 'file size', default=None))
- if filesize:
- f['filesize'] = filesize
- yield f
+ if process_manifest_format(f, 'dash', f['format_id']):
+ f['filesize'] = int_or_none(self._search_regex(
+ r'/clen/(\d+)', f.get('fragment_base_url') or f['url'], 'file size', default=None))
+ yield f
def _real_extract(self, url):
url, smuggled_data = unsmuggle_url(url, {})