|
|
@ -31,8 +31,12 @@ from ..compat import (
|
|
|
|
from ..cookies import LenientSimpleCookie
|
|
|
|
from ..cookies import LenientSimpleCookie
|
|
|
|
from ..downloader.f4m import get_base_url, remove_encrypted_media
|
|
|
|
from ..downloader.f4m import get_base_url, remove_encrypted_media
|
|
|
|
from ..downloader.hls import HlsFD
|
|
|
|
from ..downloader.hls import HlsFD
|
|
|
|
from ..networking.common import HEADRequest, Request
|
|
|
|
from ..networking import HEADRequest, Request
|
|
|
|
from ..networking.exceptions import network_exceptions
|
|
|
|
from ..networking.exceptions import (
|
|
|
|
|
|
|
|
HTTPError,
|
|
|
|
|
|
|
|
IncompleteRead,
|
|
|
|
|
|
|
|
network_exceptions,
|
|
|
|
|
|
|
|
)
|
|
|
|
from ..utils import (
|
|
|
|
from ..utils import (
|
|
|
|
IDENTITY,
|
|
|
|
IDENTITY,
|
|
|
|
JSON_LD_RE,
|
|
|
|
JSON_LD_RE,
|
|
|
@ -729,7 +733,7 @@ class InfoExtractor:
|
|
|
|
e.ie = e.ie or self.IE_NAME,
|
|
|
|
e.ie = e.ie or self.IE_NAME,
|
|
|
|
e.traceback = e.traceback or sys.exc_info()[2]
|
|
|
|
e.traceback = e.traceback or sys.exc_info()[2]
|
|
|
|
raise
|
|
|
|
raise
|
|
|
|
except http.client.IncompleteRead as e:
|
|
|
|
except IncompleteRead as e:
|
|
|
|
raise ExtractorError('A network error has occurred.', cause=e, expected=True, video_id=self.get_temp_id(url))
|
|
|
|
raise ExtractorError('A network error has occurred.', cause=e, expected=True, video_id=self.get_temp_id(url))
|
|
|
|
except (KeyError, StopIteration) as e:
|
|
|
|
except (KeyError, StopIteration) as e:
|
|
|
|
raise ExtractorError('An extractor error has occurred.', cause=e, video_id=self.get_temp_id(url))
|
|
|
|
raise ExtractorError('An extractor error has occurred.', cause=e, video_id=self.get_temp_id(url))
|
|
|
@ -788,16 +792,19 @@ class InfoExtractor:
|
|
|
|
|
|
|
|
|
|
|
|
@staticmethod
|
|
|
|
@staticmethod
|
|
|
|
def __can_accept_status_code(err, expected_status):
|
|
|
|
def __can_accept_status_code(err, expected_status):
|
|
|
|
assert isinstance(err, urllib.error.HTTPError)
|
|
|
|
assert isinstance(err, HTTPError)
|
|
|
|
if expected_status is None:
|
|
|
|
if expected_status is None:
|
|
|
|
return False
|
|
|
|
return False
|
|
|
|
elif callable(expected_status):
|
|
|
|
elif callable(expected_status):
|
|
|
|
return expected_status(err.code) is True
|
|
|
|
return expected_status(err.status) is True
|
|
|
|
else:
|
|
|
|
else:
|
|
|
|
return err.code in variadic(expected_status)
|
|
|
|
return err.status in variadic(expected_status)
|
|
|
|
|
|
|
|
|
|
|
|
def _create_request(self, url_or_request, data=None, headers=None, query=None):
|
|
|
|
def _create_request(self, url_or_request, data=None, headers=None, query=None):
|
|
|
|
if isinstance(url_or_request, urllib.request.Request):
|
|
|
|
if isinstance(url_or_request, urllib.request.Request):
|
|
|
|
|
|
|
|
self._downloader.deprecation_warning(
|
|
|
|
|
|
|
|
'Passing a urllib.request.Request to _create_request() is deprecated. '
|
|
|
|
|
|
|
|
'Use yt_dlp.networking.common.Request instead.')
|
|
|
|
url_or_request = urllib_req_to_req(url_or_request)
|
|
|
|
url_or_request = urllib_req_to_req(url_or_request)
|
|
|
|
elif not isinstance(url_or_request, Request):
|
|
|
|
elif not isinstance(url_or_request, Request):
|
|
|
|
url_or_request = Request(url_or_request)
|
|
|
|
url_or_request = Request(url_or_request)
|
|
|
@ -839,7 +846,7 @@ class InfoExtractor:
|
|
|
|
try:
|
|
|
|
try:
|
|
|
|
return self._downloader.urlopen(self._create_request(url_or_request, data, headers, query))
|
|
|
|
return self._downloader.urlopen(self._create_request(url_or_request, data, headers, query))
|
|
|
|
except network_exceptions as err:
|
|
|
|
except network_exceptions as err:
|
|
|
|
if isinstance(err, urllib.error.HTTPError):
|
|
|
|
if isinstance(err, HTTPError):
|
|
|
|
if self.__can_accept_status_code(err, expected_status):
|
|
|
|
if self.__can_accept_status_code(err, expected_status):
|
|
|
|
return err.response
|
|
|
|
return err.response
|
|
|
|
|
|
|
|
|
|
|
@ -973,11 +980,11 @@ class InfoExtractor:
|
|
|
|
if prefix is not None:
|
|
|
|
if prefix is not None:
|
|
|
|
webpage_bytes = prefix + webpage_bytes
|
|
|
|
webpage_bytes = prefix + webpage_bytes
|
|
|
|
if self.get_param('dump_intermediate_pages', False):
|
|
|
|
if self.get_param('dump_intermediate_pages', False):
|
|
|
|
self.to_screen('Dumping request to ' + urlh.geturl())
|
|
|
|
self.to_screen('Dumping request to ' + urlh.url)
|
|
|
|
dump = base64.b64encode(webpage_bytes).decode('ascii')
|
|
|
|
dump = base64.b64encode(webpage_bytes).decode('ascii')
|
|
|
|
self._downloader.to_screen(dump)
|
|
|
|
self._downloader.to_screen(dump)
|
|
|
|
if self.get_param('write_pages'):
|
|
|
|
if self.get_param('write_pages'):
|
|
|
|
filename = self._request_dump_filename(urlh.geturl(), video_id)
|
|
|
|
filename = self._request_dump_filename(urlh.url, video_id)
|
|
|
|
self.to_screen(f'Saving request to {filename}')
|
|
|
|
self.to_screen(f'Saving request to {filename}')
|
|
|
|
with open(filename, 'wb') as outf:
|
|
|
|
with open(filename, 'wb') as outf:
|
|
|
|
outf.write(webpage_bytes)
|
|
|
|
outf.write(webpage_bytes)
|
|
|
@ -1109,7 +1116,7 @@ class InfoExtractor:
|
|
|
|
while True:
|
|
|
|
while True:
|
|
|
|
try:
|
|
|
|
try:
|
|
|
|
return self.__download_webpage(url_or_request, video_id, note, errnote, None, fatal, *args, **kwargs)
|
|
|
|
return self.__download_webpage(url_or_request, video_id, note, errnote, None, fatal, *args, **kwargs)
|
|
|
|
except http.client.IncompleteRead as e:
|
|
|
|
except IncompleteRead as e:
|
|
|
|
try_count += 1
|
|
|
|
try_count += 1
|
|
|
|
if try_count >= tries:
|
|
|
|
if try_count >= tries:
|
|
|
|
raise e
|
|
|
|
raise e
|
|
|
@ -1806,7 +1813,7 @@ class InfoExtractor:
|
|
|
|
return []
|
|
|
|
return []
|
|
|
|
|
|
|
|
|
|
|
|
manifest, urlh = res
|
|
|
|
manifest, urlh = res
|
|
|
|
manifest_url = urlh.geturl()
|
|
|
|
manifest_url = urlh.url
|
|
|
|
|
|
|
|
|
|
|
|
return self._parse_f4m_formats(
|
|
|
|
return self._parse_f4m_formats(
|
|
|
|
manifest, manifest_url, video_id, preference=preference, quality=quality, f4m_id=f4m_id,
|
|
|
|
manifest, manifest_url, video_id, preference=preference, quality=quality, f4m_id=f4m_id,
|
|
|
@ -1965,7 +1972,7 @@ class InfoExtractor:
|
|
|
|
return [], {}
|
|
|
|
return [], {}
|
|
|
|
|
|
|
|
|
|
|
|
m3u8_doc, urlh = res
|
|
|
|
m3u8_doc, urlh = res
|
|
|
|
m3u8_url = urlh.geturl()
|
|
|
|
m3u8_url = urlh.url
|
|
|
|
|
|
|
|
|
|
|
|
return self._parse_m3u8_formats_and_subtitles(
|
|
|
|
return self._parse_m3u8_formats_and_subtitles(
|
|
|
|
m3u8_doc, m3u8_url, ext=ext, entry_protocol=entry_protocol,
|
|
|
|
m3u8_doc, m3u8_url, ext=ext, entry_protocol=entry_protocol,
|
|
|
@ -2243,7 +2250,7 @@ class InfoExtractor:
|
|
|
|
return [], {}
|
|
|
|
return [], {}
|
|
|
|
|
|
|
|
|
|
|
|
smil, urlh = res
|
|
|
|
smil, urlh = res
|
|
|
|
smil_url = urlh.geturl()
|
|
|
|
smil_url = urlh.url
|
|
|
|
|
|
|
|
|
|
|
|
namespace = self._parse_smil_namespace(smil)
|
|
|
|
namespace = self._parse_smil_namespace(smil)
|
|
|
|
|
|
|
|
|
|
|
@ -2266,7 +2273,7 @@ class InfoExtractor:
|
|
|
|
return {}
|
|
|
|
return {}
|
|
|
|
|
|
|
|
|
|
|
|
smil, urlh = res
|
|
|
|
smil, urlh = res
|
|
|
|
smil_url = urlh.geturl()
|
|
|
|
smil_url = urlh.url
|
|
|
|
|
|
|
|
|
|
|
|
return self._parse_smil(smil, smil_url, video_id, f4m_params=f4m_params)
|
|
|
|
return self._parse_smil(smil, smil_url, video_id, f4m_params=f4m_params)
|
|
|
|
|
|
|
|
|
|
|
@ -2458,7 +2465,7 @@ class InfoExtractor:
|
|
|
|
return []
|
|
|
|
return []
|
|
|
|
|
|
|
|
|
|
|
|
xspf, urlh = res
|
|
|
|
xspf, urlh = res
|
|
|
|
xspf_url = urlh.geturl()
|
|
|
|
xspf_url = urlh.url
|
|
|
|
|
|
|
|
|
|
|
|
return self._parse_xspf(
|
|
|
|
return self._parse_xspf(
|
|
|
|
xspf, playlist_id, xspf_url=xspf_url,
|
|
|
|
xspf, playlist_id, xspf_url=xspf_url,
|
|
|
@ -2529,7 +2536,7 @@ class InfoExtractor:
|
|
|
|
return [], {}
|
|
|
|
return [], {}
|
|
|
|
|
|
|
|
|
|
|
|
# We could have been redirected to a new url when we retrieved our mpd file.
|
|
|
|
# We could have been redirected to a new url when we retrieved our mpd file.
|
|
|
|
mpd_url = urlh.geturl()
|
|
|
|
mpd_url = urlh.url
|
|
|
|
mpd_base_url = base_url(mpd_url)
|
|
|
|
mpd_base_url = base_url(mpd_url)
|
|
|
|
|
|
|
|
|
|
|
|
return self._parse_mpd_formats_and_subtitles(
|
|
|
|
return self._parse_mpd_formats_and_subtitles(
|
|
|
@ -2900,7 +2907,7 @@ class InfoExtractor:
|
|
|
|
if ism_doc is None:
|
|
|
|
if ism_doc is None:
|
|
|
|
return [], {}
|
|
|
|
return [], {}
|
|
|
|
|
|
|
|
|
|
|
|
return self._parse_ism_formats_and_subtitles(ism_doc, urlh.geturl(), ism_id)
|
|
|
|
return self._parse_ism_formats_and_subtitles(ism_doc, urlh.url, ism_id)
|
|
|
|
|
|
|
|
|
|
|
|
def _parse_ism_formats_and_subtitles(self, ism_doc, ism_url, ism_id=None):
|
|
|
|
def _parse_ism_formats_and_subtitles(self, ism_doc, ism_url, ism_id=None):
|
|
|
|
"""
|
|
|
|
"""
|
|
|
|