feat: add support for uliza in pia-live

This commit is contained in:
ChocoLZS 2024-08-21 11:43:45 +08:00
parent f0bb28504c
commit 9c2a6fa449
3 changed files with 144 additions and 32 deletions

View File

@ -1510,8 +1510,9 @@ from .pgatour import PGATourIE
from .philharmoniedeparis import PhilharmonieDeParisIE from .philharmoniedeparis import PhilharmonieDeParisIE
from .phoenix import PhoenixIE from .phoenix import PhoenixIE
from .photobucket import PhotobucketIE from .photobucket import PhotobucketIE
from .pialive import PiaLiveIE
from .piapro import PiaproIE from .piapro import PiaproIE
from .piaulizaportal import PIAULIZAPortalIE from .piaulizaportal import PIAULIZAPortalAPIIE, PIAULIZAPortalIE
from .picarto import ( from .picarto import (
PicartoIE, PicartoIE,
PicartoVodIE, PicartoVodIE,

View File

@ -0,0 +1,55 @@
from .common import InfoExtractor
from .piaulizaportal import PIAULIZAPortalAPIIE
from ..networking import Request
from ..utils import multipart_encode, smuggle_url
class PiaLiveIE(InfoExtractor):
PLAYER_ROOT_URL = 'https://player.pia-live.jp'
PIA_LIVE_API_URL = 'https://api.pia-live.jp'
_VALID_URL = r'https?://player\.pia-live\.jp/stream/(?P<id>[\w-]+)'
def _real_extract(self, url):
video_key = self._match_id(url)
webpage = self._download_webpage(url, video_key)
program_code = self._search_regex(r"const programCode = '(.*?)';", webpage, 'program code')
prod_configure = self._download_webpage(
self.PLAYER_ROOT_URL + self._search_regex(r'<script [^>]*\bsrc="(/statics/js/s_prod[^"]+)"', webpage, 'prod configure page'),
program_code,
headers={'Referer': self.PLAYER_ROOT_URL},
note='Fetching prod configure page', errnote='Unable to fetch prod configure page',
)
api_key = self._search_regex(r"const APIKEY = '(.*?)';", prod_configure, 'api key')
payload, content_type = multipart_encode({
'play_url': video_key,
'api_key': api_key,
})
player_tag_list = self._download_json(
Request(
url=f'{self.PIA_LIVE_API_URL}/perf/player-tag-list/{program_code}',
method='POST',
data=payload,
headers={
'Content-Type': content_type,
},
),
program_code,
)
player_data_url = self._search_regex(PIAULIZAPortalAPIIE.SCRIPT_TAG_REGEX_PATTERN,
player_tag_list['data']['movie_one_tag'], 'player data url')
return {
**self.url_result(
smuggle_url(
player_data_url,
{'video_id': program_code, 'referer': self.PLAYER_ROOT_URL, 'info_dict': {
'id': program_code,
'title': self._html_extract_title(webpage),
}},
),
ie=PIAULIZAPortalAPIIE.ie_key(),
),
}

View File

@ -1,11 +1,78 @@
from .common import InfoExtractor from .common import InfoExtractor
from ..utils import ( from ..utils import ExtractorError, int_or_none, parse_qs, smuggle_url, time_seconds, traverse_obj, unsmuggle_url
ExtractorError,
int_or_none,
parse_qs, class PIAULIZAPortalAPIIE(InfoExtractor):
time_seconds, IE_DESC = 'https://player-api.p.uliza.jp - PIA ULIZA m3u8'
traverse_obj, SCRIPT_TAG_REGEX_PATTERN = r'<script [^>]*\bsrc="(https://player-api\.p\.uliza\.jp/v1/players/[^"]+)"'
)
_VALID_URL = r'https://player-api\.p\.uliza\.jp/v1/players/(?P<id>.*)'
_TESTS = [
{
'url': 'https://player-api.p.uliza.jp/v1/players/timeshift-disabled/pia/admin?type=normal&playerobjectname=ulizaPlayer&name=livestream01_dvr&repeatable=true',
'info_dict': {
'id': 'timeshift-disabled/pia/admin?type=normal&playerobjectname=ulizaPlayer&name=livestream01_dvr&repeatable=true',
'title': 'livestream01_dvr',
'live_status': 'was_live',
},
'params': {
'skip_download': True,
'ignore_no_formats_error': True,
},
},
{
'url': 'https://player-api.p.uliza.jp/v1/players/uliza_jp_gallery_normal/promotion/admin?type=presentation&name=cookings&targetid=player1',
'info_dict': {
'id': 'uliza_jp_gallery_normal/promotion/admin?type=presentation&name=cookings&targetid=player1',
'title': 'cookings',
'live_status': 'not_live',
},
'params': {
'skip_download': True,
'ignore_no_formats_error': True,
},
},
{
'url': 'https://player-api.p.uliza.jp/v1/players/default-player/pia/admin?type=normal&name=pia_movie_uliza_fix&targetid=ulizahtml5&repeatable=true',
'info_dict': {
'id': 'default-player/pia/admin?type=normal&name=pia_movie_uliza_fix&targetid=ulizahtml5&repeatable=true',
'title': 'pia_movie_uliza_fix',
'live_status': 'not_live',
},
'params': {
'skip_download': True,
'ignore_no_formats_error': True,
},
},
]
def _real_extract(self, url):
url, smuggled_data = unsmuggle_url(url, {})
video_id = smuggled_data.get('video_id') or self._search_regex(r'&name=([^&]+)', self._match_id(url), 'video id')
player_data = self._download_webpage(
url,
video_id,
headers={'Referer': smuggled_data.get('referer') or 'https://player-api.p.uliza.jp/'},
note='Fetching player data', errnote='Unable to fetch player data',
)
formats = self._extract_m3u8_formats(
self._search_regex(
r'["\'](https://vms-api\.p\.uliza\.jp/v1/prog-index\.m3u8[^"\']+)', player_data,
'm3u8 url', default=None),
video_id, fatal=False)
m3u8_type = self._search_regex(
r'/hls/(dvr|video)/', traverse_obj(formats, (0, 'url')), 'm3u8 type', default=None)
return {
'id': video_id,
'title': smuggled_data.get('video_title') or video_id,
'formats': formats,
'live_status': {
'video': 'is_live',
'dvr': 'was_live', # short-term archives
}.get(m3u8_type, 'not_live'), # VOD or long-term archives
**smuggled_data.get('info_dict', {}),
}
class PIAULIZAPortalIE(InfoExtractor): class PIAULIZAPortalIE(InfoExtractor):
@ -44,27 +111,16 @@ class PIAULIZAPortalIE(InfoExtractor):
webpage = self._download_webpage(url, video_id) webpage = self._download_webpage(url, video_id)
player_data = self._download_webpage( player_data_url = self._search_regex(
self._search_regex( PIAULIZAPortalAPIIE.SCRIPT_TAG_REGEX_PATTERN,
r'<script [^>]*\bsrc="(https://player-api\.p\.uliza\.jp/v1/players/[^"]+)"', webpage, 'player data url')
webpage, 'player data url'), return self.url_result(
video_id, headers={'Referer': 'https://ulizaportal.jp/'}, smuggle_url(
note='Fetching player data', errnote='Unable to fetch player data') player_data_url,
{'video_id': video_id, 'referer': 'https://ulizaportal.jp/', 'info_dict': {
formats = self._extract_m3u8_formats(
self._search_regex(
r'["\'](https://vms-api\.p\.uliza\.jp/v1/prog-index\.m3u8[^"\']+)', player_data,
'm3u8 url', default=None),
video_id, fatal=False)
m3u8_type = self._search_regex(
r'/hls/(dvr|video)/', traverse_obj(formats, (0, 'url')), 'm3u8 type', default=None)
return {
'id': video_id, 'id': video_id,
'title': self._html_extract_title(webpage), 'title': self._html_extract_title(webpage),
'formats': formats, }},
'live_status': { ),
'video': 'is_live', ie=PIAULIZAPortalAPIIE.ie_key(),
'dvr': 'was_live', # short-term archives )
}.get(m3u8_type, 'not_live'), # VOD or long-term archives
}