parent
421ddcb8b4
commit
bc79491368
2 changed files with 171 additions and 0 deletions
|
@ -547,6 +547,10 @@ from .hungama import (
|
||||||
HungamaAlbumPlaylistIE,
|
HungamaAlbumPlaylistIE,
|
||||||
)
|
)
|
||||||
from .hypem import HypemIE
|
from .hypem import HypemIE
|
||||||
|
from .ichinanalive import (
|
||||||
|
IchinanaLiveIE,
|
||||||
|
IchinanaLiveClipIE,
|
||||||
|
)
|
||||||
from .ign import (
|
from .ign import (
|
||||||
IGNIE,
|
IGNIE,
|
||||||
IGNVideoIE,
|
IGNVideoIE,
|
||||||
|
|
167
yt_dlp/extractor/ichinanalive.py
Normal file
167
yt_dlp/extractor/ichinanalive.py
Normal file
|
@ -0,0 +1,167 @@
|
||||||
|
# coding: utf-8
|
||||||
|
from __future__ import unicode_literals
|
||||||
|
|
||||||
|
from .common import InfoExtractor
|
||||||
|
from ..utils import ExtractorError, str_or_none, traverse_obj, unified_strdate
|
||||||
|
from ..compat import compat_str
|
||||||
|
|
||||||
|
|
||||||
|
class IchinanaLiveIE(InfoExtractor):
|
||||||
|
IE_NAME = '17live'
|
||||||
|
_VALID_URL = r'https?://(?:www\.)?17\.live/(?:[^/]+/)*(?:live|profile/r)/(?P<id>\d+)'
|
||||||
|
_TESTS = [{
|
||||||
|
'url': 'https://17.live/live/3773096',
|
||||||
|
'info_dict': {
|
||||||
|
'id': '3773096',
|
||||||
|
'title': '萠珈☕🤡🍫moka',
|
||||||
|
'is_live': True,
|
||||||
|
'uploader': '萠珈☕🤡🍫moka',
|
||||||
|
'uploader_id': '3773096',
|
||||||
|
'like_count': 366,
|
||||||
|
'view_count': 18121,
|
||||||
|
'timestamp': 1630569012,
|
||||||
|
},
|
||||||
|
'skip': 'running as of writing, but may be ended as of testing',
|
||||||
|
}, {
|
||||||
|
'note': 'nothing except language differs',
|
||||||
|
'url': 'https://17.live/ja/live/3773096',
|
||||||
|
'only_matching': True,
|
||||||
|
}]
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def suitable(cls, url):
|
||||||
|
return not IchinanaLiveClipIE.suitable(url) and super(IchinanaLiveIE, cls).suitable(url)
|
||||||
|
|
||||||
|
def _real_extract(self, url):
|
||||||
|
video_id = self._match_id(url)
|
||||||
|
url = 'https://17.live/live/%s' % video_id
|
||||||
|
|
||||||
|
enter = self._download_json(
|
||||||
|
'https://api-dsa.17app.co/api/v1/lives/%s/enter' % video_id, video_id,
|
||||||
|
headers={'Referer': url}, fatal=False, expected_status=420,
|
||||||
|
data=b'\0')
|
||||||
|
if enter and enter.get('message') == 'ended':
|
||||||
|
raise ExtractorError('This live has ended.', expected=True)
|
||||||
|
|
||||||
|
view_data = self._download_json(
|
||||||
|
'https://api-dsa.17app.co/api/v1/lives/%s' % video_id, video_id,
|
||||||
|
headers={'Referer': url})
|
||||||
|
|
||||||
|
uploader = traverse_obj(
|
||||||
|
view_data, ('userInfo', 'displayName'), ('userInfo', 'openID'))
|
||||||
|
|
||||||
|
video_urls = view_data.get('rtmpUrls')
|
||||||
|
if not video_urls:
|
||||||
|
raise ExtractorError('unable to extract live URL information')
|
||||||
|
formats = []
|
||||||
|
for (name, value) in video_urls[0].items():
|
||||||
|
if not isinstance(value, compat_str):
|
||||||
|
continue
|
||||||
|
if not value.startswith('http'):
|
||||||
|
continue
|
||||||
|
quality = -1
|
||||||
|
if 'web' in name:
|
||||||
|
quality -= 1
|
||||||
|
if 'High' in name:
|
||||||
|
quality += 4
|
||||||
|
if 'Low' in name:
|
||||||
|
quality -= 2
|
||||||
|
formats.append({
|
||||||
|
'format_id': name,
|
||||||
|
'url': value,
|
||||||
|
'quality': quality,
|
||||||
|
'http_headers': {'Referer': url},
|
||||||
|
'ext': 'flv',
|
||||||
|
'vcodec': 'h264',
|
||||||
|
'acodec': 'aac',
|
||||||
|
})
|
||||||
|
|
||||||
|
self._sort_formats(formats)
|
||||||
|
|
||||||
|
return {
|
||||||
|
'id': video_id,
|
||||||
|
'title': uploader or video_id,
|
||||||
|
'formats': formats,
|
||||||
|
'is_live': True,
|
||||||
|
'uploader': uploader,
|
||||||
|
'uploader_id': video_id,
|
||||||
|
'like_count': view_data.get('receivedLikeCount'),
|
||||||
|
'view_count': view_data.get('viewerCount'),
|
||||||
|
'thumbnail': view_data.get('coverPhoto'),
|
||||||
|
'description': view_data.get('caption'),
|
||||||
|
'timestamp': view_data.get('beginTime'),
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
class IchinanaLiveClipIE(InfoExtractor):
|
||||||
|
IE_NAME = '17live:clip'
|
||||||
|
_VALID_URL = r'https?://(?:www\.)?17\.live/(?:[^/]+/)*profile/r/(?P<uploader_id>\d+)/clip/(?P<id>[^/]+)'
|
||||||
|
_TESTS = [{
|
||||||
|
'url': 'https://17.live/profile/r/1789280/clip/1bHQSK8KUieruFXaCH4A4upCzlN',
|
||||||
|
'info_dict': {
|
||||||
|
'id': '1bHQSK8KUieruFXaCH4A4upCzlN',
|
||||||
|
'title': 'マチコ先生🦋Class💋',
|
||||||
|
'description': 'マチ戦隊 第一次 バスターコール\n総額200万coin!\n動画制作@うぉーかー🌱Walker🎫',
|
||||||
|
'uploader_id': '1789280',
|
||||||
|
},
|
||||||
|
}, {
|
||||||
|
'url': 'https://17.live/ja/profile/r/1789280/clip/1bHQSK8KUieruFXaCH4A4upCzlN',
|
||||||
|
'only_matching': True,
|
||||||
|
}]
|
||||||
|
|
||||||
|
def _real_extract(self, url):
|
||||||
|
uploader_id, video_id = self._match_valid_url(url).groups()
|
||||||
|
url = 'https://17.live/profile/r/%s/clip/%s' % (uploader_id, video_id)
|
||||||
|
|
||||||
|
view_data = self._download_json(
|
||||||
|
'https://api-dsa.17app.co/api/v1/clips/%s' % video_id, video_id,
|
||||||
|
headers={'Referer': url})
|
||||||
|
|
||||||
|
uploader = traverse_obj(
|
||||||
|
view_data, ('userInfo', 'displayName'), ('userInfo', 'name'))
|
||||||
|
|
||||||
|
formats = []
|
||||||
|
if view_data.get('videoURL'):
|
||||||
|
formats.append({
|
||||||
|
'id': 'video',
|
||||||
|
'url': view_data['videoURL'],
|
||||||
|
'quality': -1,
|
||||||
|
})
|
||||||
|
if view_data.get('transcodeURL'):
|
||||||
|
formats.append({
|
||||||
|
'id': 'transcode',
|
||||||
|
'url': view_data['transcodeURL'],
|
||||||
|
'quality': -1,
|
||||||
|
})
|
||||||
|
if view_data.get('srcVideoURL'):
|
||||||
|
# highest quality
|
||||||
|
formats.append({
|
||||||
|
'id': 'srcVideo',
|
||||||
|
'url': view_data['srcVideoURL'],
|
||||||
|
'quality': 1,
|
||||||
|
})
|
||||||
|
|
||||||
|
for fmt in formats:
|
||||||
|
fmt.update({
|
||||||
|
'ext': 'mp4',
|
||||||
|
'protocol': 'https',
|
||||||
|
'vcodec': 'h264',
|
||||||
|
'acodec': 'aac',
|
||||||
|
'http_headers': {'Referer': url},
|
||||||
|
})
|
||||||
|
|
||||||
|
self._sort_formats(formats)
|
||||||
|
|
||||||
|
return {
|
||||||
|
'id': video_id,
|
||||||
|
'title': uploader or video_id,
|
||||||
|
'formats': formats,
|
||||||
|
'uploader': uploader,
|
||||||
|
'uploader_id': uploader_id,
|
||||||
|
'like_count': view_data.get('likeCount'),
|
||||||
|
'view_count': view_data.get('viewCount'),
|
||||||
|
'thumbnail': view_data.get('imageURL'),
|
||||||
|
'duration': view_data.get('duration'),
|
||||||
|
'description': view_data.get('caption'),
|
||||||
|
'upload_date': unified_strdate(str_or_none(view_data.get('createdAt'))),
|
||||||
|
}
|
Loading…
Reference in a new issue