1 from .common
import InfoExtractor
7 get_element_html_by_class
,
13 from ..utils
.traversal
import traverse_obj
16 class PiaLiveIE(InfoExtractor
):
17 _VALID_URL
= r
'https?://player\.pia-live\.jp/stream/(?P<id>[\w-]+)'
18 _PLAYER_ROOT_URL
= 'https://player.pia-live.jp/'
19 _PIA_LIVE_API_URL
= 'https://api.pia-live.jp'
20 _API_KEY
= 'kfds)FKFps-dms9e'
22 'url': 'https://player.pia-live.jp/stream/4JagFBEIM14s_hK9aXHKf3k3F3bY5eoHFQxu68TC6krUDqGOwN4d61dCWQYOd6CTxl4hjya9dsfEZGsM4uGOUdax60lEI4twsXGXf7crmz8Gk__GhupTrWxA7RFRVt76',
24 'id': '88f3109a-f503-4d0f-a9f7-9f39ac745d84',
25 'display_id': '2431867_001',
26 'title': 'こながめでたい日2024の視聴ページ | PIA LIVE STREAM(ぴあライブストリーム)',
27 'live_status': 'was_live',
32 'skip_download': True,
33 'ignore_no_formats_error': True,
35 'skip': 'The video is no longer available',
37 'url': 'https://player.pia-live.jp/stream/4JagFBEIM14s_hK9aXHKf3k3F3bY5eoHFQxu68TC6krJdu0GVBVbVy01IwpJ6J3qBEm3d9TCTt1d0eWpsZGj7DrOjVOmS7GAWGwyscMgiThopJvzgWC4H5b-7XQjAfRZ',
39 'id': '9ce8b8ba-f6d1-4d1f-83a0-18c3148ded93',
40 'display_id': '2431867_002',
41 'title': 'こながめでたい日2024の視聴ページ | PIA LIVE STREAM(ぴあライブストリーム)',
42 'live_status': 'was_live',
47 'skip_download': True,
48 'ignore_no_formats_error': True,
50 'skip': 'The video is no longer available',
53 def _extract_var(self
, variable
, html
):
54 return self
._search
_regex
(
55 rf
'(?:var|const|let)\s+{variable}\s*=\s*(["\'])(?P<value>(?:(?!\1).)+)\1',
56 html
, f
'variable {variable}', group
='value')
58 def _real_extract(self
, url
):
59 video_key
= self
._match
_id
(url
)
60 webpage
= self
._download
_webpage
(url
, video_key
)
62 program_code
= self
._extract
_var
('programCode', webpage
)
63 article_code
= self
._extract
_var
('articleCode', webpage
)
64 title
= self
._html
_extract
_title
(webpage
)
66 if get_element_html_by_class('play-end', webpage
):
67 raise ExtractorError('The video is no longer available', expected
=True, video_id
=program_code
)
69 if start_info
:= clean_html(get_element_by_class('play-waiting__date', webpage
)):
70 date
, time
= self
._search
_regex
(
71 r
'(?P<date>\d{4}/\d{1,2}/\d{1,2})\([月火水木金土日]\)(?P<time>\d{2}:\d{2})',
72 start_info
, 'start_info', fatal
=False, group
=('date', 'time'))
74 release_timestamp_str
= f
'{date} {time} +09:00'
75 release_timestamp
= unified_timestamp(release_timestamp_str
)
76 self
.raise_no_formats(f
'The video will be available after {release_timestamp_str}', expected
=True)
80 'live_status': 'is_upcoming',
81 'release_timestamp': release_timestamp
,
84 payload
, content_type
= multipart_encode({
85 'play_url': video_key
,
86 'api_key': self
._API
_KEY
,
88 api_data_and_headers
= {
90 'headers': {'Content-Type': content_type
, 'Referer': self
._PLAYER
_ROOT
_URL
},
93 player_tag_list
= self
._download
_json
(
94 f
'{self._PIA_LIVE_API_URL}/perf/player-tag-list/{program_code}', program_code
,
95 'Fetching player tag list', 'Unable to fetch player tag list', **api_data_and_headers
)
97 return self
.url_result(
98 extract_attributes(player_tag_list
['data']['movie_one_tag'])['src'],
99 url_transparent
=True, title
=title
, display_id
=program_code
,
100 __post_extractor
=self
.extract_comments(program_code
, article_code
, api_data_and_headers
))
102 def _get_comments(self
, program_code
, article_code
, api_data_and_headers
):
103 chat_room_url
= traverse_obj(self
._download
_json
(
104 f
'{self._PIA_LIVE_API_URL}/perf/chat-tag-list/{program_code}/{article_code}', program_code
,
105 'Fetching chat info', 'Unable to fetch chat info', fatal
=False, **api_data_and_headers
),
106 ('data', 'chat_one_tag', {extract_attributes}
, 'src', {url_or_none}
))
107 if not chat_room_url
:
109 comment_page
= self
._download
_webpage
(
110 chat_room_url
, program_code
, 'Fetching comment page', 'Unable to fetch comment page',
111 fatal
=False, headers
={'Referer': self
._PLAYER
_ROOT
_URL
})
114 yield from traverse_obj(self
._search
_json
(
115 r
'var\s+_history\s*=', comment_page
, 'comment list',
116 program_code
, contains_pattern
=r
'\[(?s:.+)\]', fatal
=False), (..., {
117 'timestamp': (0, {int}
),
118 'author_is_uploader': (1, {lambda x
: x
== 2}),
119 'author': (2, {str}
),
121 'id': (4, {str_or_none}
),