]> jfr.im git - yt-dlp.git/blame - yt_dlp/extractor/goodgame.py
[ie/matchtv] Fix extractor (#10190)
[yt-dlp.git] / yt_dlp / extractor / goodgame.py
CommitLineData
3ac7b660
DN
1from .common import InfoExtractor
2from ..utils import (
3 clean_html,
4 int_or_none,
5 str_or_none,
6 traverse_obj,
7)
8
9
10class GoodGameIE(InfoExtractor):
11 IE_NAME = 'goodgame:stream'
12 _VALID_URL = r'https?://goodgame\.ru/channel/(?P<id>\w+)'
13 _TESTS = [{
14 'url': 'https://goodgame.ru/channel/Pomi/#autoplay',
15 'info_dict': {
16 'id': 'pomi',
17 'ext': 'mp4',
18 'title': r're:Reynor vs Special \(1/2,bo3\) Wardi Spring EU \- playoff \(финальный день\) \d{4}-\d{2}-\d{2} \d{2}:\d{2}$',
19 'channel_id': '1644',
20 'channel': 'Pomi',
21 'channel_url': 'https://goodgame.ru/channel/Pomi/',
22 'description': 'md5:4a87b775ee7b2b57bdccebe285bbe171',
23 'thumbnail': r're:^https?://.*\.jpg$',
24 'live_status': 'is_live',
25 'view_count': int,
26 },
27 'params': {'skip_download': 'm3u8'},
28 'skip': 'May not be online',
29 }]
30
31 def _real_extract(self, url):
32 channel_name = self._match_id(url)
33 response = self._download_json(f'https://api2.goodgame.ru/v2/streams/{channel_name}', channel_name)
34 player_id = response['channel']['gg_player_src']
35
36 formats, subtitles = [], {}
37 if response.get('status') == 'Live':
38 formats, subtitles = self._extract_m3u8_formats_and_subtitles(
39 f'https://hls.goodgame.ru/manifest/{player_id}_master.m3u8',
40 channel_name, 'mp4', live=True)
41 else:
42 self.raise_no_formats('User is offline', expected=True, video_id=channel_name)
43
3ac7b660
DN
44 return {
45 'id': player_id,
46 'formats': formats,
47 'subtitles': subtitles,
48 'title': traverse_obj(response, ('channel', 'title')),
49 'channel': channel_name,
50 'channel_id': str_or_none(traverse_obj(response, ('channel', 'id'))),
51 'channel_url': response.get('url'),
52 'description': clean_html(traverse_obj(response, ('channel', 'description'))),
53 'thumbnail': traverse_obj(response, ('channel', 'thumb')),
54 'is_live': bool(formats),
55 'view_count': int_or_none(response.get('viewers')),
56 'age_limit': 18 if traverse_obj(response, ('channel', 'adult')) else None,
57 }