]>
Commit | Line | Data |
---|---|---|
89f383c4 HTL |
1 | import functools |
2 | ||
920134b2 | 3 | from .common import InfoExtractor |
89f383c4 HTL |
4 | from ..utils import ( |
5 | OnDemandPagedList, | |
6 | traverse_obj, | |
7 | unified_strdate, | |
8 | ) | |
920134b2 AG |
9 | |
10 | ||
11 | class GronkhIE(InfoExtractor): | |
375d9360 | 12 | _VALID_URL = r'https?://(?:www\.)?gronkh\.tv/(?:watch/)?stream/(?P<id>\d+)' |
920134b2 AG |
13 | |
14 | _TESTS = [{ | |
15 | 'url': 'https://gronkh.tv/stream/536', | |
16 | 'info_dict': { | |
17 | 'id': '536', | |
18 | 'ext': 'mp4', | |
19 | 'title': 'GTV0536, 2021-10-01 - MARTHA IS DEAD #FREiAB1830 !FF7 !horde !archiv', | |
20 | 'view_count': 19491, | |
21 | 'thumbnail': 'https://01.cdn.vod.farm/preview/6436746cce14e25f751260a692872b9b.jpg', | |
22 | 'upload_date': '20211001' | |
23 | }, | |
24 | 'params': {'skip_download': True} | |
375d9360 S |
25 | }, { |
26 | 'url': 'https://gronkh.tv/watch/stream/546', | |
27 | 'only_matching': True, | |
920134b2 AG |
28 | }] |
29 | ||
30 | def _real_extract(self, url): | |
31 | id = self._match_id(url) | |
32 | data_json = self._download_json(f'https://api.gronkh.tv/v1/video/info?episode={id}', id) | |
33 | m3u8_url = self._download_json(f'https://api.gronkh.tv/v1/video/playlist?episode={id}', id)['playlist_url'] | |
34 | formats, subtitles = self._extract_m3u8_formats_and_subtitles(m3u8_url, id) | |
35 | if data_json.get('vtt_url'): | |
36 | subtitles.setdefault('en', []).append({ | |
37 | 'url': data_json['vtt_url'], | |
38 | 'ext': 'vtt', | |
39 | }) | |
920134b2 AG |
40 | return { |
41 | 'id': id, | |
42 | 'title': data_json.get('title'), | |
43 | 'view_count': data_json.get('views'), | |
44 | 'thumbnail': data_json.get('preview_url'), | |
45 | 'upload_date': unified_strdate(data_json.get('created_at')), | |
46 | 'formats': formats, | |
47 | 'subtitles': subtitles, | |
48 | } | |
89f383c4 HTL |
49 | |
50 | ||
51 | class GronkhFeedIE(InfoExtractor): | |
52 | _VALID_URL = r'https?://(?:www\.)?gronkh\.tv(?:/feed)?/?(?:#|$)' | |
53 | IE_NAME = 'gronkh:feed' | |
54 | ||
55 | _TESTS = [{ | |
56 | 'url': 'https://gronkh.tv/feed', | |
57 | 'info_dict': { | |
58 | 'id': 'feed', | |
59 | }, | |
60 | 'playlist_count': 16, | |
61 | }, { | |
62 | 'url': 'https://gronkh.tv', | |
63 | 'only_matching': True, | |
64 | }] | |
65 | ||
66 | def _entries(self): | |
67 | for type_ in ('recent', 'views'): | |
68 | info = self._download_json( | |
69 | f'https://api.gronkh.tv/v1/video/discovery/{type_}', 'feed', note=f'Downloading {type_} API JSON') | |
70 | for item in traverse_obj(info, ('discovery', ...)) or []: | |
71 | yield self.url_result(f'https://gronkh.tv/watch/stream/{item["episode"]}', GronkhIE, item.get('title')) | |
72 | ||
73 | def _real_extract(self, url): | |
74 | return self.playlist_result(self._entries(), 'feed') | |
75 | ||
76 | ||
77 | class GronkhVodsIE(InfoExtractor): | |
78 | _VALID_URL = r'https?://(?:www\.)?gronkh\.tv/vods/streams/?(?:#|$)' | |
79 | IE_NAME = 'gronkh:vods' | |
80 | ||
81 | _TESTS = [{ | |
82 | 'url': 'https://gronkh.tv/vods/streams', | |
83 | 'info_dict': { | |
84 | 'id': 'vods', | |
85 | }, | |
86 | 'playlist_mincount': 150, | |
87 | }] | |
88 | _PER_PAGE = 25 | |
89 | ||
90 | def _fetch_page(self, page): | |
91 | items = traverse_obj(self._download_json( | |
92 | 'https://api.gronkh.tv/v1/search', 'vods', query={'offset': self._PER_PAGE * page, 'first': self._PER_PAGE}, | |
93 | note=f'Downloading stream video page {page + 1}'), ('results', 'videos', ...)) | |
94 | for item in items or []: | |
95 | yield self.url_result(f'https://gronkh.tv/watch/stream/{item["episode"]}', GronkhIE, item['episode'], item.get('title')) | |
96 | ||
97 | def _real_extract(self, url): | |
98 | entries = OnDemandPagedList(functools.partial(self._fetch_page), self._PER_PAGE) | |
99 | return self.playlist_result(entries, 'vods') |