]>
jfr.im git - yt-dlp.git/blob - yt_dlp/extractor/ichinanalive.py
1 from .common
import InfoExtractor
2 from ..utils
import ExtractorError
, str_or_none
, traverse_obj
, unified_strdate
3 from ..compat
import compat_str
6 class IchinanaLiveIE(InfoExtractor
):
8 _VALID_URL
= r
'https?://(?:www\.)?17\.live/(?:[^/]+/)*(?:live|profile/r)/(?P<id>\d+)'
10 'url': 'https://17.live/live/3773096',
15 'uploader': '萠珈☕🤡🍫moka',
16 'uploader_id': '3773096',
19 'timestamp': 1630569012,
21 'skip': 'running as of writing, but may be ended as of testing',
23 'note': 'nothing except language differs',
24 'url': 'https://17.live/ja/live/3773096',
25 'only_matching': True,
29 def suitable(cls
, url
):
30 return not IchinanaLiveClipIE
.suitable(url
) and super(IchinanaLiveIE
, cls
).suitable(url
)
32 def _real_extract(self
, url
):
33 video_id
= self
._match
_id
(url
)
34 url
= 'https://17.live/live/%s' % video_id
36 enter
= self
._download
_json
(
37 'https://api-dsa.17app.co/api/v1/lives/%s/enter' % video_id
, video_id
,
38 headers
={'Referer': url}
, fatal
=False, expected_status
=420,
40 if enter
and enter
.get('message') == 'ended':
41 raise ExtractorError('This live has ended.', expected
=True)
43 view_data
= self
._download
_json
(
44 'https://api-dsa.17app.co/api/v1/lives/%s' % video_id
, video_id
,
45 headers
={'Referer': url}
)
47 uploader
= traverse_obj(
48 view_data
, ('userInfo', 'displayName'), ('userInfo', 'openID'))
50 video_urls
= view_data
.get('rtmpUrls')
52 raise ExtractorError('unable to extract live URL information')
54 for (name
, value
) in video_urls
[0].items():
55 if not isinstance(value
, compat_str
):
57 if not value
.startswith('http'):
70 'http_headers': {'Referer': url}
,
76 self
._sort
_formats
(formats
)
80 'title': uploader
or video_id
,
84 'uploader_id': video_id
,
85 'like_count': view_data
.get('receivedLikeCount'),
86 'view_count': view_data
.get('viewerCount'),
87 'thumbnail': view_data
.get('coverPhoto'),
88 'description': view_data
.get('caption'),
89 'timestamp': view_data
.get('beginTime'),
93 class IchinanaLiveClipIE(InfoExtractor
):
94 IE_NAME
= '17live:clip'
95 _VALID_URL
= r
'https?://(?:www\.)?17\.live/(?:[^/]+/)*profile/r/(?P<uploader_id>\d+)/clip/(?P<id>[^/]+)'
97 'url': 'https://17.live/profile/r/1789280/clip/1bHQSK8KUieruFXaCH4A4upCzlN',
99 'id': '1bHQSK8KUieruFXaCH4A4upCzlN',
100 'title': 'マチコ先生🦋Class💋',
101 'description': 'マチ戦隊 第一次 バスターコール\n総額200万coin!\n動画制作@うぉーかー🌱Walker🎫',
102 'uploader_id': '1789280',
105 'url': 'https://17.live/ja/profile/r/1789280/clip/1bHQSK8KUieruFXaCH4A4upCzlN',
106 'only_matching': True,
109 def _real_extract(self
, url
):
110 uploader_id
, video_id
= self
._match
_valid
_url
(url
).groups()
111 url
= 'https://17.live/profile/r/%s/clip/%s' % (uploader_id
, video_id
)
113 view_data
= self
._download
_json
(
114 'https://api-dsa.17app.co/api/v1/clips/%s' % video_id
, video_id
,
115 headers
={'Referer': url}
)
117 uploader
= traverse_obj(
118 view_data
, ('userInfo', 'displayName'), ('userInfo', 'name'))
121 if view_data
.get('videoURL'):
124 'url': view_data
['videoURL'],
127 if view_data
.get('transcodeURL'):
130 'url': view_data
['transcodeURL'],
133 if view_data
.get('srcVideoURL'):
137 'url': view_data
['srcVideoURL'],
147 'http_headers': {'Referer': url}
,
150 self
._sort
_formats
(formats
)
154 'title': uploader
or video_id
,
156 'uploader': uploader
,
157 'uploader_id': uploader_id
,
158 'like_count': view_data
.get('likeCount'),
159 'view_count': view_data
.get('viewCount'),
160 'thumbnail': view_data
.get('imageURL'),
161 'duration': view_data
.get('duration'),
162 'description': view_data
.get('caption'),
163 'upload_date': unified_strdate(str_or_none(view_data
.get('createdAt'))),