|
|
@ -92,6 +92,8 @@ class AbemaLicenseHandler(urllib.request.BaseHandler):
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class AbemaTVBaseIE(InfoExtractor):
|
|
|
|
class AbemaTVBaseIE(InfoExtractor):
|
|
|
|
|
|
|
|
_NETRC_MACHINE = 'abematv'
|
|
|
|
|
|
|
|
|
|
|
|
_USERTOKEN = None
|
|
|
|
_USERTOKEN = None
|
|
|
|
_DEVICE_ID = None
|
|
|
|
_DEVICE_ID = None
|
|
|
|
_MEDIATOKEN = None
|
|
|
|
_MEDIATOKEN = None
|
|
|
@ -184,6 +186,37 @@ class AbemaTVBaseIE(InfoExtractor):
|
|
|
|
|
|
|
|
|
|
|
|
return self._MEDIATOKEN
|
|
|
|
return self._MEDIATOKEN
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def _perform_login(self, username, password):
|
|
|
|
|
|
|
|
self._get_device_token()
|
|
|
|
|
|
|
|
if self.cache.load(self._NETRC_MACHINE, username, min_ver='2024.01.19') and self._get_media_token():
|
|
|
|
|
|
|
|
self.write_debug('Skipping logging in')
|
|
|
|
|
|
|
|
return
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if '@' in username: # don't strictly check if it's email address or not
|
|
|
|
|
|
|
|
ep, method = 'user/email', 'email'
|
|
|
|
|
|
|
|
else:
|
|
|
|
|
|
|
|
ep, method = 'oneTimePassword', 'userId'
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
login_response = self._download_json(
|
|
|
|
|
|
|
|
f'https://api.abema.io/v1/auth/{ep}', None, note='Logging in',
|
|
|
|
|
|
|
|
data=json.dumps({
|
|
|
|
|
|
|
|
method: username,
|
|
|
|
|
|
|
|
'password': password
|
|
|
|
|
|
|
|
}).encode('utf-8'), headers={
|
|
|
|
|
|
|
|
'Authorization': f'bearer {self._get_device_token()}',
|
|
|
|
|
|
|
|
'Origin': 'https://abema.tv',
|
|
|
|
|
|
|
|
'Referer': 'https://abema.tv/',
|
|
|
|
|
|
|
|
'Content-Type': 'application/json',
|
|
|
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
AbemaTVBaseIE._USERTOKEN = login_response['token']
|
|
|
|
|
|
|
|
self._get_media_token(True)
|
|
|
|
|
|
|
|
auth_cache = {
|
|
|
|
|
|
|
|
'device_id': AbemaTVBaseIE._DEVICE_ID,
|
|
|
|
|
|
|
|
'usertoken': AbemaTVBaseIE._USERTOKEN,
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
self.cache.store(self._NETRC_MACHINE, username, auth_cache)
|
|
|
|
|
|
|
|
|
|
|
|
def _call_api(self, endpoint, video_id, query=None, note='Downloading JSON metadata'):
|
|
|
|
def _call_api(self, endpoint, video_id, query=None, note='Downloading JSON metadata'):
|
|
|
|
return self._download_json(
|
|
|
|
return self._download_json(
|
|
|
|
f'https://api.abema.io/{endpoint}', video_id, query=query or {},
|
|
|
|
f'https://api.abema.io/{endpoint}', video_id, query=query or {},
|
|
|
@ -207,7 +240,6 @@ class AbemaTVBaseIE(InfoExtractor):
|
|
|
|
|
|
|
|
|
|
|
|
class AbemaTVIE(AbemaTVBaseIE):
|
|
|
|
class AbemaTVIE(AbemaTVBaseIE):
|
|
|
|
_VALID_URL = r'https?://abema\.tv/(?P<type>now-on-air|video/episode|channels/.+?/slots)/(?P<id>[^?/]+)'
|
|
|
|
_VALID_URL = r'https?://abema\.tv/(?P<type>now-on-air|video/episode|channels/.+?/slots)/(?P<id>[^?/]+)'
|
|
|
|
_NETRC_MACHINE = 'abematv'
|
|
|
|
|
|
|
|
_TESTS = [{
|
|
|
|
_TESTS = [{
|
|
|
|
'url': 'https://abema.tv/video/episode/194-25_s2_p1',
|
|
|
|
'url': 'https://abema.tv/video/episode/194-25_s2_p1',
|
|
|
|
'info_dict': {
|
|
|
|
'info_dict': {
|
|
|
@ -256,37 +288,6 @@ class AbemaTVIE(AbemaTVBaseIE):
|
|
|
|
}]
|
|
|
|
}]
|
|
|
|
_TIMETABLE = None
|
|
|
|
_TIMETABLE = None
|
|
|
|
|
|
|
|
|
|
|
|
def _perform_login(self, username, password):
|
|
|
|
|
|
|
|
self._get_device_token()
|
|
|
|
|
|
|
|
if self.cache.load(self._NETRC_MACHINE, username, min_ver='2024.01.19') and self._get_media_token():
|
|
|
|
|
|
|
|
self.write_debug('Skipping logging in')
|
|
|
|
|
|
|
|
return
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if '@' in username: # don't strictly check if it's email address or not
|
|
|
|
|
|
|
|
ep, method = 'user/email', 'email'
|
|
|
|
|
|
|
|
else:
|
|
|
|
|
|
|
|
ep, method = 'oneTimePassword', 'userId'
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
login_response = self._download_json(
|
|
|
|
|
|
|
|
f'https://api.abema.io/v1/auth/{ep}', None, note='Logging in',
|
|
|
|
|
|
|
|
data=json.dumps({
|
|
|
|
|
|
|
|
method: username,
|
|
|
|
|
|
|
|
'password': password
|
|
|
|
|
|
|
|
}).encode('utf-8'), headers={
|
|
|
|
|
|
|
|
'Authorization': f'bearer {self._get_device_token()}',
|
|
|
|
|
|
|
|
'Origin': 'https://abema.tv',
|
|
|
|
|
|
|
|
'Referer': 'https://abema.tv/',
|
|
|
|
|
|
|
|
'Content-Type': 'application/json',
|
|
|
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
AbemaTVBaseIE._USERTOKEN = login_response['token']
|
|
|
|
|
|
|
|
self._get_media_token(True)
|
|
|
|
|
|
|
|
auth_cache = {
|
|
|
|
|
|
|
|
'device_id': AbemaTVBaseIE._DEVICE_ID,
|
|
|
|
|
|
|
|
'usertoken': AbemaTVBaseIE._USERTOKEN,
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
self.cache.store(self._NETRC_MACHINE, username, auth_cache)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def _real_extract(self, url):
|
|
|
|
def _real_extract(self, url):
|
|
|
|
# starting download using infojson from this extractor is undefined behavior,
|
|
|
|
# starting download using infojson from this extractor is undefined behavior,
|
|
|
|
# and never be fixed in the future; you must trigger downloads by directly specifying URL.
|
|
|
|
# and never be fixed in the future; you must trigger downloads by directly specifying URL.
|
|
|
|