diff options
Diffstat (limited to 'gallery_dl/extractor/tiktok.py')
| -rw-r--r-- | gallery_dl/extractor/tiktok.py | 47 |
1 files changed, 37 insertions, 10 deletions
diff --git a/gallery_dl/extractor/tiktok.py b/gallery_dl/extractor/tiktok.py index f450806..a4c7171 100644 --- a/gallery_dl/extractor/tiktok.py +++ b/gallery_dl/extractor/tiktok.py @@ -25,6 +25,7 @@ class TiktokExtractor(Extractor): def _init(self): self.audio = self.config("audio", True) self.video = self.config("videos", True) + self.cover = self.config("covers", False) def items(self): for tiktok_url in self.urls(): @@ -43,10 +44,10 @@ class TiktokExtractor(Extractor): post = video_detail["itemInfo"]["itemStruct"] post["user"] = (a := post.get("author")) and a["uniqueId"] or "" - post["date"] = text.parse_timestamp(post["createTime"]) + post["date"] = self.parse_timestamp(post["createTime"]) original_title = title = post["desc"] - yield Message.Directory, post + yield Message.Directory, "", post ytdl_media = False if "imagePost" in post: @@ -70,12 +71,14 @@ class TiktokExtractor(Extractor): if self.audio and "music" in post: if self.audio == "ytdl": ytdl_media = "audio" - else: - url = self._extract_audio(post) + elif url := self._extract_audio(post): yield Message.Url, url, post - elif self.video and "video" in post: - ytdl_media = "video" + elif "video" in post: + if self.video: + ytdl_media = "video" + if self.cover and (url := self._extract_cover(post, "video")): + yield Message.Url, url, post else: self.log.info("%s: Skipping post", tiktok_url) @@ -144,6 +147,30 @@ class TiktokExtractor(Extractor): post["extension"] = "mp3" return url + def _extract_cover(self, post, type): + media = post[type] + + for cover_id in ("thumbnail", "cover", "originCover", "dynamicCover"): + if url := media.get(cover_id): + break + else: + return + + text.nameext_from_url(url, post) + post.update({ + "type" : "cover", + "extension": "jpg", + "image" : url, + "title" : post["desc"] or f"TikTok {type} cover #{post['id']}", + "duration" : media.get("duration"), + "num" : 0, + "img_id" : "", + "cover_id" : cover_id, + "width" : 0, + "height" : 0, + }) + return url + def _check_status_code(self, detail, url): status = detail.get("statusCode") if not status: @@ -166,7 +193,7 @@ class TiktokExtractor(Extractor): class TiktokPostExtractor(TiktokExtractor): """Extract a single video or photo TikTok link""" subcategory = "post" - pattern = BASE_PATTERN + r"/(?:@([\w_.-]*)|share)/(?:phot|vide)o/(\d+)" + pattern = rf"{BASE_PATTERN}/(?:@([\w_.-]*)|share)/(?:phot|vide)o/(\d+)" example = "https://www.tiktok.com/@USER/photo/1234567890" def urls(self): @@ -199,7 +226,7 @@ class TiktokVmpostExtractor(TiktokExtractor): class TiktokUserExtractor(TiktokExtractor): """Extract a TikTok user's profile""" subcategory = "user" - pattern = BASE_PATTERN + r"/@([\w_.-]+)/?(?:$|\?|#)" + pattern = rf"{BASE_PATTERN}/@([\w_.-]+)/?(?:$|\?|#)" example = "https://www.tiktok.com/@USER" def _init(self): @@ -214,7 +241,7 @@ class TiktokUserExtractor(TiktokExtractor): except (ImportError, SyntaxError) as exc: self.log.error("Cannot import module '%s'", getattr(exc, "name", "")) - self.log.debug("", exc_info=exc) + self.log.traceback(exc) raise exception.ExtractionError("yt-dlp or youtube-dl is required " "for this feature!") @@ -254,7 +281,7 @@ class TiktokUserExtractor(TiktokExtractor): self.log.warning("Unable to extract 'avatar' URL (%s: %s)", exc.__class__.__name__, exc) else: - yield Message.Directory, avatar + yield Message.Directory, "", avatar yield Message.Url, avatar_url, avatar with ytdl_instance as ydl: |
