3 from .common
import InfoExtractor
15 class CineverseBaseIE(InfoExtractor
):
16 _VALID_URL_BASE
= r
'https://www\.(?P<host>%s)' % '|'.join(map(re
.escape
, (
27 class CineverseIE(CineverseBaseIE
):
28 _VALID_URL
= rf
'{CineverseBaseIE._VALID_URL_BASE}/watch/(?P<id>[A-Z0-9]+)'
30 'url': 'https://www.asiancrush.com/watch/DMR00018919/Women-Who-Flirt',
31 'skip': 'geo-blocked',
33 'title': 'Women Who Flirt',
36 'modified_timestamp': 1678744575289,
37 'cast': ['Xun Zhou', 'Xiaoming Huang', 'Yi-Lin Sie', 'Sonia Sui', 'Quniciren'],
39 'description': 'md5:892fd62a05611d394141e8394ace0bc6',
43 'url': 'https://www.retrocrush.tv/watch/1000000023016/Archenemy! Crystal Bowie',
44 'skip': 'geo-blocked',
46 'title': 'Archenemy! Crystal Bowie',
48 'id': '1000000023016',
51 'cast': ['Nachi Nozawa', 'Yoshiko Sakakibara', 'Toshiko Fujita'],
53 'episode': 'Episode 3',
56 'description': 'Cobra meets a beautiful bounty hunter by the name of Jane Royal.',
57 'series': 'Space Adventure COBRA (Original Japanese)',
61 def _real_extract(self
, url
):
62 url
, smuggled_data
= unsmuggle_url(url
, default
={})
63 self
._initialize
_geo
_bypass
({
64 'countries': smuggled_data
.get('geo_countries'),
66 video_id
= self
._match
_id
(url
)
67 html
= self
._download
_webpage
(url
, video_id
)
68 idetails
= self
._search
_nextjs
_data
(html
, video_id
)['props']['pageProps']['idetails']
70 if idetails
.get('err_code') == 1200:
71 self
.raise_geo_restricted(
72 'This video is not available from your location due to geo restriction. '
73 'You may be able to bypass it by using the /details/ page instead of the /watch/ page',
74 countries
=smuggled_data
.get('geo_countries'))
77 'subtitles': filter_dict({
78 'en': traverse_obj(idetails
, (('cc_url_vtt', 'subtitle_url'), {'url': {url_or_none}
})) or None,
80 'formats': self
._extract
_m
3u8_formats
(idetails
['url'], video_id
),
81 **traverse_obj(idetails
, {
83 'id': ('details', 'item_id'),
84 'description': ('details', 'description'),
85 'duration': ('duration', {lambda x: x / 1000}
),
86 'cast': ('details', 'cast', {lambda x: x.split(', ')}
),
87 'modified_timestamp': ('details', 'updated_by', 0, 'update_time', 'time', {int_or_none}
),
88 'season_number': ('details', 'season', {int_or_none}
),
89 'episode_number': ('details', 'episode', {int_or_none}
),
90 'age_limit': ('details', 'rating_code', {parse_age_limit}
),
91 'series': ('details', 'series_details', 'title'),
96 class CineverseDetailsIE(CineverseBaseIE
):
97 _VALID_URL
= rf
'{CineverseBaseIE._VALID_URL_BASE}/details/(?P<id>[A-Z0-9]+)'
99 'url': 'https://www.retrocrush.tv/details/1000000023012/Space-Adventure-COBRA-(Original-Japanese)',
100 'playlist_mincount': 30,
102 'title': 'Space Adventure COBRA (Original Japanese)',
103 'id': '1000000023012',
106 'url': 'https://www.asiancrush.com/details/NNVG4938/Hansel-and-Gretel',
110 'title': 'Hansel and Gretel',
111 'description': 'md5:e3e4c35309c2e82aee044f972c2fb05d',
112 'cast': ['Jeong-myeong Cheon', 'Eun Won-jae', 'Shim Eun-gyeong', 'Ji-hee Jin', 'Hee-soon Park', 'Lydia Park', 'Kyeong-ik Kim'],
113 'duration': 7030.732,
117 def _real_extract(self
, url
):
118 host
, series_id
= self
._match
_valid
_url
(url
).group('host', 'id')
119 html
= self
._download
_webpage
(url
, series_id
)
120 pageprops
= self
._search
_nextjs
_data
(html
, series_id
)['props']['pageProps']
122 geo_countries
= traverse_obj(pageprops
, ('itemDetailsData', 'geo_country', {lambda x: x.split(', ')}
))
123 geoblocked
= traverse_obj(pageprops
, (
124 'itemDetailsData', 'playback_err_msg')) == 'This title is not available in your location.'
126 def item_result(item
):
127 item_url
= f
'https://www.{host}/watch/{item["item_id"]}/{item["title"]}'
129 item_url
= smuggle_url(item_url
, {'geo_countries': geo_countries}
)
130 return self
.url_result(item_url
, CineverseIE
)
132 season
= traverse_obj(pageprops
, ('seasonEpisodes', ..., 'episodes', lambda _
, v
: v
['item_id'] and v
['title']))
134 return self
.playlist_result([item_result(ep
) for ep
in season
], playlist_id
=series_id
,
135 playlist_title
=traverse_obj(pageprops
, ('itemDetailsData', 'title')))
136 return item_result(pageprops
['itemDetailsData'])