1 from .common
import InfoExtractor
8 class SovietsClosetBaseIE(InfoExtractor
):
9 MEDIADELIVERY_REFERER
= {'Referer': 'https://iframe.mediadelivery.net/'}
11 def parse_nuxt_jsonp(self
, nuxt_jsonp_url
, video_id
, name
):
12 nuxt_jsonp
= self
._download
_webpage
(nuxt_jsonp_url
, video_id
, note
=f
'Downloading {name} __NUXT_JSONP__')
13 return self
._search
_nuxt
_data
(nuxt_jsonp
, video_id
, '__NUXT_JSONP__')
15 def video_meta(self
, video_id
, game_name
, category_name
, episode_number
, stream_date
):
17 if category_name
and category_name
!= 'Misc':
18 title
+= f
' - {category_name}'
20 title
+= f
' #{episode_number}'
22 timestamp
= unified_timestamp(stream_date
)
27 'http_headers': self
.MEDIADELIVERY_REFERER
,
28 'uploader': 'SovietWomble',
29 'creator': 'SovietWomble',
30 'release_timestamp': timestamp
,
31 'timestamp': timestamp
,
32 'uploader_id': 'SovietWomble',
33 'uploader_url': 'https://www.twitch.tv/SovietWomble',
35 'availability': 'public',
37 'season': category_name
,
38 'episode_number': episode_number
,
42 class SovietsClosetIE(SovietsClosetBaseIE
):
43 _VALID_URL
= r
'https?://(?:www\.)?sovietscloset\.com/video/(?P<id>[0-9]+)/?'
46 'url': 'https://sovietscloset.com/video/1337',
47 'md5': 'bd012b04b261725510ca5383074cdd55',
51 'title': 'The Witcher #13',
52 'thumbnail': r
're:^https?://.*\.b-cdn\.net/2f0cfbf4-3588-43a9-a7d6-7c9ea3755e67/thumbnail\.jpg$',
53 'uploader': 'SovietWomble',
54 'creator': 'SovietWomble',
55 'release_timestamp': 1492091580,
56 'release_date': '20170413',
57 'timestamp': 1492091580,
58 'upload_date': '20170413',
59 'uploader_id': 'SovietWomble',
60 'uploader_url': 'https://www.twitch.tv/SovietWomble',
63 'availability': 'public',
64 'series': 'The Witcher',
67 'episode': 'Episode 13',
71 'url': 'https://sovietscloset.com/video/1105',
72 'md5': '89fa928f183893cb65a0b7be846d8a90',
76 'title': 'Arma 3 - Zeus Games #5',
77 'uploader': 'SovietWomble',
78 'thumbnail': r
're:^https?://.*\.b-cdn\.net/c0e5e76f-3a93-40b4-bf01-12343c2eec5d/thumbnail\.jpg$',
79 'creator': 'SovietWomble',
80 'release_timestamp': 1461157200,
81 'release_date': '20160420',
82 'timestamp': 1461157200,
83 'upload_date': '20160420',
84 'uploader_id': 'SovietWomble',
85 'uploader_url': 'https://www.twitch.tv/SovietWomble',
88 'availability': 'public',
90 'season': 'Zeus Games',
92 'episode': 'Episode 5',
97 def _extract_bunnycdn_iframe(self
, video_id
, bunnycdn_id
):
98 iframe
= self
._download
_webpage
(
99 f
'https://iframe.mediadelivery.net/embed/5105/{bunnycdn_id}',
100 video_id
, note
='Downloading BunnyCDN iframe', headers
=self
.MEDIADELIVERY_REFERER
)
102 m3u8_url
= self
._search
_regex
(r
'(https?://.*?\.m3u8)', iframe
, 'm3u8 url')
103 thumbnail_url
= self
._search
_regex
(r
'(https?://.*?thumbnail\.jpg)', iframe
, 'thumbnail url')
105 m3u8_formats
= self
._extract
_m
3u8_formats
(m3u8_url
, video_id
, headers
=self
.MEDIADELIVERY_REFERER
)
110 duration
= self
._extract
_m
3u8_vod
_duration
(
111 m3u8_formats
[0]['url'], video_id
, headers
=self
.MEDIADELIVERY_REFERER
)
114 'formats': m3u8_formats
,
115 'thumbnail': thumbnail_url
,
116 'duration': duration
,
119 def _real_extract(self
, url
):
120 video_id
= self
._match
_id
(url
)
121 webpage
= self
._download
_webpage
(url
, video_id
)
123 static_assets_base
= self
._search
_regex
(r
'(/_nuxt/static/\d+)', webpage
, 'staticAssetsBase')
124 static_assets_base
= f
'https://sovietscloset.com{static_assets_base}'
126 stream
= self
.parse_nuxt_jsonp(f
'{static_assets_base}/video/{video_id}/payload.js', video_id
, 'video')['stream']
130 video_id
=video_id
, game_name
=stream
['game']['name'],
131 category_name
=try_get(stream
, lambda x
: x
['subcategory']['name'], str),
132 episode_number
=stream
.get('number'), stream_date
=stream
.get('date')),
133 **self
._extract
_bunnycdn
_iframe
(video_id
, stream
['bunnyId']),
137 class SovietsClosetPlaylistIE(SovietsClosetBaseIE
):
138 _VALID_URL
= r
'https?://(?:www\.)?sovietscloset\.com/(?!video)(?P<id>[^#?]+)'
142 'url': 'https://sovietscloset.com/The-Witcher',
145 'title': 'The Witcher',
147 'playlist_mincount': 31,
150 'url': 'https://sovietscloset.com/Arma-3/Zeus-Games',
152 'id': 'Arma-3/Zeus-Games',
153 'title': 'Arma 3 - Zeus Games',
155 'playlist_mincount': 3,
158 'url': 'https://sovietscloset.com/arma-3/zeus-games/',
160 'id': 'arma-3/zeus-games',
161 'title': 'Arma 3 - Zeus Games',
163 'playlist_mincount': 3,
166 'url': 'https://sovietscloset.com/Total-War-Warhammer',
168 'id': 'Total-War-Warhammer',
169 'title': 'Total War: Warhammer - Greenskins',
171 'playlist_mincount': 33,
175 def _real_extract(self
, url
):
176 playlist_id
= self
._match
_id
(url
)
177 if playlist_id
.endswith('/'):
178 playlist_id
= playlist_id
[:-1]
180 webpage
= self
._download
_webpage
(url
, playlist_id
)
182 static_assets_base
= self
._search
_regex
(r
'(/_nuxt/static/\d+)', webpage
, 'staticAssetsBase')
183 static_assets_base
= f
'https://sovietscloset.com{static_assets_base}'
185 sovietscloset
= self
.parse_nuxt_jsonp(f
'{static_assets_base}/payload.js', playlist_id
, 'global')['games']
187 if '/' in playlist_id
:
188 game_slug
, category_slug
= playlist_id
.lower().split('/')
190 game_slug
= playlist_id
.lower()
191 category_slug
= 'misc'
193 game
= next(game
for game
in sovietscloset
if game
['slug'].lower() == game_slug
)
194 category
= next((cat
for cat
in game
['subcategories'] if cat
.get('slug', '').lower() == category_slug
),
195 game
['subcategories'][0])
196 category_slug
= category
.get('slug', '').lower() or category_slug
197 playlist_title
= game
.get('name') or game_slug
198 if category_slug
!= 'misc':
199 playlist_title
+= f
' - {category.get("name") or category_slug}'
201 **self
.url_result(f
'https://sovietscloset.com/video/{stream["id"]}', ie
=SovietsClosetIE
.ie_key()),
203 video_id
=stream
['id'], game_name
=game
['name'], category_name
=category
.get('name'),
204 episode_number
=i
+ 1, stream_date
=stream
.get('date')),
205 } for i
, stream
in enumerate(category
['streams'])]
207 return self
.playlist_result(entries
, playlist_id
, playlist_title
)