]>
jfr.im git - yt-dlp.git/blob - yt_dlp/extractor/mirrativ.py
1 from __future__
import unicode_literals
3 from .common
import InfoExtractor
12 class MirrativBaseIE(InfoExtractor
):
13 def assert_error(self
, response
):
14 error_message
= traverse_obj(response
, ('status', 'error'))
16 raise ExtractorError('Mirrativ says: %s' % error_message
, expected
=True)
19 class MirrativIE(MirrativBaseIE
):
21 _VALID_URL
= r
'https?://(?:www\.)?mirrativ\.com/live/(?P<id>[^/?#&]+)'
24 'url': 'https://mirrativ.com/live/UQomuS7EMgHoxRHjEhNiHw',
26 'id': 'UQomuS7EMgHoxRHjEhNiHw',
27 'title': 'ねむいぃ、。『参加型』🔰jcが初めてやるCOD✨初見さん大歓迎💗',
29 'description': 'md5:bfcd8f77f2fab24c3c672e5620f3f16e',
30 'thumbnail': r
're:https?://.+',
31 'uploader': '# あ ち ゅ 。💡',
32 'uploader_id': '118572165',
35 'release_timestamp': 1646229192,
36 'timestamp': 1646229167,
41 'url': 'https://mirrativ.com/live/POxyuG1KmW2982lqlDTuPw',
42 'only_matching': True,
45 def _real_extract(self
, url
):
46 video_id
= self
._match
_id
(url
)
47 webpage
= self
._download
_webpage
('https://www.mirrativ.com/live/%s' % video_id
, video_id
)
48 live_response
= self
._download
_json
(f
'https://www.mirrativ.com/api/live/live?live_id={video_id}', video_id
)
49 self
.assert_error(live_response
)
51 hls_url
= dict_get(live_response
, ('archive_url_hls', 'streaming_url_hls'))
52 is_live
= bool(live_response
.get('is_live'))
54 raise ExtractorError('Neither archive nor live is available.', expected
=True)
56 formats
= self
._extract
_m
3u8_formats
(
58 ext
='mp4', entry_protocol
='m3u8_native',
59 m3u8_id
='hls', live
=is_live
)
60 self
._sort
_formats
(formats
)
64 'title': self
._og
_search
_title
(webpage
, default
=None) or self
._search
_regex
(
65 r
'<title>\s*(.+?) - Mirrativ\s*</title>', webpage
) or live_response
.get('title'),
67 'description': live_response
.get('description'),
69 'thumbnail': live_response
.get('image_url'),
70 'uploader': traverse_obj(live_response
, ('owner', 'name')),
71 'uploader_id': traverse_obj(live_response
, ('owner', 'user_id')),
72 'duration': try_get(live_response
, lambda x
: x
['ended_at'] - x
['started_at']) if not is_live
else None,
73 'view_count': live_response
.get('total_viewer_num'),
74 'release_timestamp': live_response
.get('started_at'),
75 'timestamp': live_response
.get('created_at'),
76 'was_live': bool(live_response
.get('is_archive')),
80 class MirrativUserIE(MirrativBaseIE
):
81 IE_NAME
= 'mirrativ:user'
82 _VALID_URL
= r
'https?://(?:www\.)?mirrativ\.com/user/(?P<id>\d+)'
85 # Live archive is available up to 3 days
86 # see: https://helpfeel.com/mirrativ/%E9%8C%B2%E7%94%BB-5e26d3ad7b59ef0017fb49ac (Japanese)
87 'url': 'https://www.mirrativ.com/user/110943130',
88 'note': 'multiple archives available',
89 'only_matching': True,
92 def _entries(self
, user_id
):
94 while page
is not None:
95 api_response
= self
._download
_json
(
96 f
'https://www.mirrativ.com/api/live/live_history?user_id={user_id}&page={page}', user_id
,
97 note
=f
'Downloading page {page}')
98 self
.assert_error(api_response
)
99 lives
= api_response
.get('lives')
103 if not live
.get('is_archive') and not live
.get('is_live'):
104 # neither archive nor live is available, so skip it
105 # or the service will ban your IP address for a while
107 live_id
= live
.get('live_id')
108 url
= 'https://www.mirrativ.com/live/%s' % live_id
109 yield self
.url_result(url
, video_id
=live_id
, video_title
=live
.get('title'))
110 page
= api_response
.get('next_page')
112 def _real_extract(self
, url
):
113 user_id
= self
._match
_id
(url
)
114 user_info
= self
._download
_json
(
115 f
'https://www.mirrativ.com/api/user/profile?user_id={user_id}', user_id
,
116 note
='Downloading user info', fatal
=False)
117 self
.assert_error(user_info
)
119 return self
.playlist_result(
120 self
._entries
(user_id
), user_id
,
121 user_info
.get('name'), user_info
.get('description'))