mirror of
https://github.com/yt-dlp/yt-dlp
synced 2024-12-27 21:59:17 +01:00
[TikTok] Add music, sticker and tag IEs (#2119)
Closes #1752 Authored by: MinePlayersPE
This commit is contained in:
parent
6da22e7d4f
commit
8126298c1b
2 changed files with 111 additions and 0 deletions
|
@ -1538,6 +1538,9 @@ from .threeqsdn import ThreeQSDNIE
|
|||
from .tiktok import (
|
||||
TikTokIE,
|
||||
TikTokUserIE,
|
||||
TikTokSoundIE,
|
||||
TikTokEffectIE,
|
||||
TikTokTagIE,
|
||||
DouyinIE,
|
||||
)
|
||||
from .tinypic import TinyPicIE
|
||||
|
|
|
@ -464,6 +464,114 @@ class TikTokUserIE(TikTokBaseIE):
|
|||
return self.playlist_result(self._entries_api(webpage, user_id, user_name), user_id, user_name)
|
||||
|
||||
|
||||
class TikTokBaseListIE(TikTokBaseIE):
|
||||
def _entries(self, list_id, display_id):
|
||||
query = {
|
||||
self._QUERY_NAME: list_id,
|
||||
'cursor': 0,
|
||||
'count': 20,
|
||||
'type': 5,
|
||||
'device_id': ''.join(random.choice(string.digits) for i in range(19))
|
||||
}
|
||||
|
||||
max_retries = self.get_param('extractor_retries', 3)
|
||||
for page in itertools.count(1):
|
||||
for retries in itertools.count():
|
||||
try:
|
||||
post_list = self._call_api(self._API_ENDPOINT, query, display_id,
|
||||
note='Downloading video list page %d%s' % (page, f' (attempt {retries})' if retries != 0 else ''),
|
||||
errnote='Unable to download video list')
|
||||
except ExtractorError as e:
|
||||
if isinstance(e.cause, json.JSONDecodeError) and e.cause.pos == 0 and retries != max_retries:
|
||||
self.report_warning('%s. Retrying...' % str(e.cause or e.msg))
|
||||
continue
|
||||
raise
|
||||
break
|
||||
for video in post_list.get('aweme_list', []):
|
||||
yield {
|
||||
**self._parse_aweme_video_app(video),
|
||||
'ie_key': TikTokIE.ie_key(),
|
||||
'extractor': 'TikTok',
|
||||
'webpage_url': f'https://tiktok.com/@_/video/{video["aweme_id"]}',
|
||||
}
|
||||
if not post_list.get('has_more'):
|
||||
break
|
||||
query['cursor'] = post_list['cursor']
|
||||
|
||||
def _real_extract(self, url):
|
||||
list_id = self._match_id(url)
|
||||
return self.playlist_result(self._entries(list_id, list_id), list_id)
|
||||
|
||||
|
||||
class TikTokSoundIE(TikTokBaseListIE):
|
||||
IE_NAME = 'tiktok:sound'
|
||||
_VALID_URL = r'https?://(?:www\.)?tiktok\.com/music/[\w\.-]+-(?P<id>[\d]+)[/?#&]?'
|
||||
_QUERY_NAME = 'music_id'
|
||||
_API_ENDPOINT = 'music/aweme'
|
||||
_TESTS = [{
|
||||
'url': 'https://www.tiktok.com/music/Build-a-Btch-6956990112127585029?lang=en',
|
||||
'playlist_mincount': 100,
|
||||
'info_dict': {
|
||||
'id': '6956990112127585029'
|
||||
},
|
||||
'expected_warnings': ['Retrying']
|
||||
}, {
|
||||
# Actual entries are less than listed video count
|
||||
'url': 'https://www.tiktok.com/music/jiefei-soap-remix-7036843036118469381',
|
||||
'playlist_mincount': 2182,
|
||||
'info_dict': {
|
||||
'id': '7036843036118469381'
|
||||
},
|
||||
'expected_warnings': ['Retrying']
|
||||
}]
|
||||
|
||||
|
||||
class TikTokEffectIE(TikTokBaseListIE):
|
||||
IE_NAME = 'tiktok:effect'
|
||||
_VALID_URL = r'https?://(?:www\.)?tiktok\.com/sticker/[\w\.-]+-(?P<id>[\d]+)[/?#&]?'
|
||||
_QUERY_NAME = 'sticker_id'
|
||||
_API_ENDPOINT = 'sticker/aweme'
|
||||
_TESTS = [{
|
||||
'url': 'https://www.tiktok.com/sticker/MATERIAL-GWOOORL-1258156',
|
||||
'playlist_mincount': 100,
|
||||
'info_dict': {
|
||||
'id': '1258156',
|
||||
},
|
||||
'expected_warnings': ['Retrying']
|
||||
}, {
|
||||
# Different entries between mobile and web, depending on region
|
||||
'url': 'https://www.tiktok.com/sticker/Elf-Friend-479565',
|
||||
'only_matching': True
|
||||
}]
|
||||
|
||||
|
||||
class TikTokTagIE(TikTokBaseListIE):
|
||||
IE_NAME = 'tiktok:tag'
|
||||
_VALID_URL = r'https?://(?:www\.)?tiktok\.com/tag/(?P<id>[^/?#&]+)'
|
||||
_QUERY_NAME = 'ch_id'
|
||||
_API_ENDPOINT = 'challenge/aweme'
|
||||
_TESTS = [{
|
||||
'url': 'https://tiktok.com/tag/hello2018',
|
||||
'playlist_mincount': 39,
|
||||
'info_dict': {
|
||||
'id': '46294678',
|
||||
'title': 'hello2018',
|
||||
},
|
||||
'expected_warnings': ['Retrying']
|
||||
}, {
|
||||
'url': 'https://tiktok.com/tag/fypシ?is_copy_url=0&is_from_webapp=v1',
|
||||
'only_matching': True
|
||||
}]
|
||||
|
||||
def _real_extract(self, url):
|
||||
display_id = self._match_id(url)
|
||||
webpage = self._download_webpage(url, display_id, headers={
|
||||
'User-Agent': 'facebookexternalhit/1.1 (+http://www.facebook.com/externalhit_uatext.php)'
|
||||
})
|
||||
tag_id = self._html_search_regex(r'snssdk\d*://challenge/detail/(\d+)', webpage, 'tag ID')
|
||||
return self.playlist_result(self._entries(tag_id, display_id), tag_id, display_id)
|
||||
|
||||
|
||||
class DouyinIE(TikTokIE):
|
||||
_VALID_URL = r'https?://(?:www\.)?douyin\.com/video/(?P<id>[0-9]+)'
|
||||
_TESTS = [{
|
||||
|
|
Loading…
Reference in a new issue