]> jfr.im git - yt-dlp.git/blame - yt_dlp/extractor/mirrativ.py
[rokfin] Add stack and channel extractors (#1534)
[yt-dlp.git] / yt_dlp / extractor / mirrativ.py
CommitLineData
ff5e16f2
THD
1from __future__ import unicode_literals
2
3from .common import InfoExtractor
4from ..utils import (
5 ExtractorError,
6 dict_get,
7 traverse_obj,
8 try_get,
9)
10
11
12class MirrativBaseIE(InfoExtractor):
13 def assert_error(self, response):
14 error_message = traverse_obj(response, ('status', 'error'))
15 if error_message:
16 raise ExtractorError('Mirrativ says: %s' % error_message, expected=True)
17
18
19class MirrativIE(MirrativBaseIE):
20 IE_NAME = 'mirrativ'
21 _VALID_URL = r'https?://(?:www\.)?mirrativ\.com/live/(?P<id>[^/?#&]+)'
22 LIVE_API_URL = 'https://www.mirrativ.com/api/live/live?live_id=%s'
23
24 TESTS = [{
25 'url': 'https://mirrativ.com/live/POxyuG1KmW2982lqlDTuPw',
26 'only_matching': True,
27 }]
28
29 def _real_extract(self, url):
30 video_id = self._match_id(url)
31 webpage = self._download_webpage('https://www.mirrativ.com/live/%s' % video_id, video_id)
32 live_response = self._download_json(self.LIVE_API_URL % video_id, video_id)
33 self.assert_error(live_response)
34
35 hls_url = dict_get(live_response, ('archive_url_hls', 'streaming_url_hls'))
36 is_live = bool(live_response.get('is_live'))
37 was_live = bool(live_response.get('is_archive'))
38 if not hls_url:
39 raise ExtractorError('Neither archive nor live is available.', expected=True)
40
41 formats = self._extract_m3u8_formats(
42 hls_url, video_id,
43 ext='mp4', entry_protocol='m3u8_native',
44 m3u8_id='hls', live=is_live)
45 rtmp_url = live_response.get('streaming_url_edge')
46 if rtmp_url:
47 keys_to_copy = ('width', 'height', 'vcodec', 'acodec', 'tbr')
48 fmt = {
49 'format_id': 'rtmp',
50 'url': rtmp_url,
51 'protocol': 'rtmp',
52 'ext': 'mp4',
53 }
54 fmt.update({k: traverse_obj(formats, (0, k)) for k in keys_to_copy})
55 formats.append(fmt)
56 self._sort_formats(formats)
57
58 title = self._og_search_title(webpage, default=None) or self._search_regex(
59 r'<title>\s*(.+?) - Mirrativ\s*</title>', webpage) or live_response.get('title')
60 description = live_response.get('description')
61 thumbnail = live_response.get('image_url')
62
63 duration = try_get(live_response, lambda x: x['ended_at'] - x['started_at'])
64 view_count = live_response.get('total_viewer_num')
65 release_timestamp = live_response.get('started_at')
66 timestamp = live_response.get('created_at')
67
68 owner = live_response.get('owner', {})
69 uploader = owner.get('name')
70 uploader_id = owner.get('user_id')
71
72 return {
73 'id': video_id,
74 'title': title,
75 'is_live': is_live,
76 'description': description,
77 'formats': formats,
78 'thumbnail': thumbnail,
79 'uploader': uploader,
80 'uploader_id': uploader_id,
81 'duration': duration,
82 'view_count': view_count,
83 'release_timestamp': release_timestamp,
84 'timestamp': timestamp,
85 'was_live': was_live,
86 }
87
88
89class MirrativUserIE(MirrativBaseIE):
90 IE_NAME = 'mirrativ:user'
91 _VALID_URL = r'https?://(?:www\.)?mirrativ\.com/user/(?P<id>\d+)'
92 LIVE_HISTORY_API_URL = 'https://www.mirrativ.com/api/live/live_history?user_id=%s&page=%d'
93 USER_INFO_API_URL = 'https://www.mirrativ.com/api/user/profile?user_id=%s'
94
95 _TESTS = [{
96 # Live archive is available up to 3 days
97 # see: https://helpfeel.com/mirrativ/%E9%8C%B2%E7%94%BB-5e26d3ad7b59ef0017fb49ac (Japanese)
98 'url': 'https://www.mirrativ.com/user/110943130',
99 'note': 'multiple archives available',
100 'only_matching': True,
101 }]
102
103 def _entries(self, user_id):
104 page = 1
105 while page is not None:
106 api_response = self._download_json(
107 self.LIVE_HISTORY_API_URL % (user_id, page), user_id,
108 note='Downloading page %d' % page)
109 self.assert_error(api_response)
110 lives = api_response.get('lives')
111 if not lives:
112 break
113 for live in lives:
114 if not live.get('is_archive') and not live.get('is_live'):
115 # neither archive nor live is available, so skip it
116 # or the service will ban your IP address for a while
117 continue
118 live_id = live.get('live_id')
119 url = 'https://www.mirrativ.com/live/%s' % live_id
120 yield self.url_result(url, video_id=live_id, video_title=live.get('title'))
121 page = api_response.get('next_page')
122
123 def _real_extract(self, url):
124 user_id = self._match_id(url)
125 user_info = self._download_json(
126 self.USER_INFO_API_URL % user_id, user_id,
127 note='Downloading user info', fatal=False)
128 self.assert_error(user_info)
129
130 uploader = user_info.get('name')
131 description = user_info.get('description')
132
133 entries = self._entries(user_id)
134 return self.playlist_result(entries, user_id, uploader, description)