3 from .common
import InfoExtractor
16 class CineverseBaseIE(InfoExtractor
):
17 _VALID_URL_BASE
= r
'https?://www\.(?P<host>{})'.format('|'.join(map(re
.escape
, (
28 class CineverseIE(CineverseBaseIE
):
29 _VALID_URL
= rf
'{CineverseBaseIE._VALID_URL_BASE}/watch/(?P<id>[A-Z0-9]+)'
31 'url': 'https://www.asiancrush.com/watch/DMR00018919/Women-Who-Flirt',
32 'skip': 'geo-blocked',
34 'title': 'Women Who Flirt',
37 'modified_timestamp': 1678744575289,
38 'cast': ['Xun Zhou', 'Xiaoming Huang', 'Yi-Lin Sie', 'Sonia Sui', 'Quniciren'],
40 'description': 'md5:892fd62a05611d394141e8394ace0bc6',
44 'url': 'https://www.retrocrush.tv/watch/1000000023016/Archenemy! Crystal Bowie',
45 'skip': 'geo-blocked',
47 'title': 'Archenemy! Crystal Bowie',
49 'id': '1000000023016',
52 'cast': ['Nachi Nozawa', 'Yoshiko Sakakibara', 'Toshiko Fujita'],
54 'episode': 'Episode 3',
57 'description': 'Cobra meets a beautiful bounty hunter by the name of Jane Royal.',
58 'series': 'Space Adventure COBRA (Original Japanese)',
62 def _real_extract(self
, url
):
63 url
, smuggled_data
= unsmuggle_url(url
, default
={})
64 self
._initialize
_geo
_bypass
({
65 'countries': smuggled_data
.get('geo_countries'),
67 video_id
= self
._match
_id
(url
)
68 html
= self
._download
_webpage
(url
, video_id
)
69 idetails
= self
._search
_nextjs
_data
(html
, video_id
)['props']['pageProps']['idetails']
71 err_code
= idetails
.get('err_code')
73 self
.raise_login_required()
74 elif err_code
== 1200:
75 self
.raise_geo_restricted(
76 'This video is not available from your location due to geo restriction. '
77 'You may be able to bypass it by using the /details/ page instead of the /watch/ page',
78 countries
=smuggled_data
.get('geo_countries'))
81 'subtitles': filter_dict({
82 'en': traverse_obj(idetails
, (('cc_url_vtt', 'subtitle_url'), {'url': {url_or_none}
})) or None,
84 'formats': self
._extract
_m
3u8_formats
(idetails
['url'], video_id
),
85 **traverse_obj(idetails
, {
87 'id': ('details', 'item_id'),
88 'description': ('details', 'description'),
89 'duration': ('duration', {float_or_none(scale
=1000)}),
90 'cast': ('details', 'cast', {lambda x
: x
.split(', ')}),
91 'modified_timestamp': ('details', 'updated_by', 0, 'update_time', 'time', {int_or_none}
),
92 'season_number': ('details', 'season', {int_or_none}
),
93 'episode_number': ('details', 'episode', {int_or_none}
),
94 'age_limit': ('details', 'rating_code', {parse_age_limit}
),
95 'series': ('details', 'series_details', 'title'),
100 class CineverseDetailsIE(CineverseBaseIE
):
101 _VALID_URL
= rf
'{CineverseBaseIE._VALID_URL_BASE}/details/(?P<id>[A-Z0-9]+)'
103 'url': 'https://www.retrocrush.tv/details/1000000023012/Space-Adventure-COBRA-(Original-Japanese)',
104 'playlist_mincount': 30,
106 'title': 'Space Adventure COBRA (Original Japanese)',
107 'id': '1000000023012',
110 'url': 'https://www.asiancrush.com/details/NNVG4938/Hansel-and-Gretel',
114 'title': 'Hansel and Gretel',
115 'description': 'md5:e3e4c35309c2e82aee044f972c2fb05d',
116 'cast': ['Jeong-myeong Cheon', 'Eun Won-jae', 'Shim Eun-gyeong', 'Ji-hee Jin', 'Hee-soon Park', 'Lydia Park', 'Kyeong-ik Kim'],
117 'duration': 7030.732,
121 def _real_extract(self
, url
):
122 host
, series_id
= self
._match
_valid
_url
(url
).group('host', 'id')
123 html
= self
._download
_webpage
(url
, series_id
)
124 pageprops
= self
._search
_nextjs
_data
(html
, series_id
)['props']['pageProps']
126 geo_countries
= traverse_obj(pageprops
, ('itemDetailsData', 'geo_country', {lambda x
: x
.split(', ')}))
127 geoblocked
= traverse_obj(pageprops
, (
128 'itemDetailsData', 'playback_err_msg')) == 'This title is not available in your location.'
130 def item_result(item
):
131 item_url
= f
'https://www.{host}/watch/{item["item_id"]}/{item["title"]}'
133 item_url
= smuggle_url(item_url
, {'geo_countries': geo_countries
})
134 return self
.url_result(item_url
, CineverseIE
)
136 season
= traverse_obj(pageprops
, ('seasonEpisodes', ..., 'episodes', lambda _
, v
: v
['item_id'] and v
['title']))
138 return self
.playlist_result([item_result(ep
) for ep
in season
], playlist_id
=series_id
,
139 playlist_title
=traverse_obj(pageprops
, ('itemDetailsData', 'title')))
140 return item_result(pageprops
['itemDetailsData'])