[tiktok] download best quality videos (#8846)

* [tiktok] download best quality videos
* [tiktok] code formatting fix
* simplify sorting in '_extract_video_urls'
This commit is contained in:
CasualYouTuber31
2026-01-23 18:09:53 +00:00
committed by GitHub
parent f869085476
commit 88a3153df8

View File

@@ -92,6 +92,7 @@ class TiktokExtractor(Extractor):
ytdl_media = "video"
elif self.video and (url := self._extract_video(post)):
yield Message.Url, url, post
del post["_fallback"]
if self.cover and (url := self._extract_cover(post, "video")):
yield Message.Url, url, post
@@ -212,13 +213,16 @@ class TiktokExtractor(Extractor):
def _extract_video(self, post):
video = post["video"]
try:
url = video["playAddr"]
except KeyError:
raise exception.ExtractionError("Failed to extract video URL, you "
"may need cookies to continue")
urls = self._extract_video_urls(video)
if not urls:
raise exception.ExtractionError(
f"{post['id']}: Failed to extract video URLs. "
f"You may need cookies to continue.")
url = urls[0]
text.nameext_from_url(url, post)
post.update({
"_fallback": urls[1:],
"type" : "video",
"image" : None,
"title" : post["desc"] or f"TikTok video #{post['id']}",
@@ -232,6 +236,37 @@ class TiktokExtractor(Extractor):
post["extension"] = video.get("format", "mp4")
return url
def _extract_video_urls(self, video):
# First, look for bitrateInfo.
# This will include URLs pointing to the best quality videos.
if "bitrateInfo" in video:
bitrate_info = video["bitrateInfo"]
if not isinstance(bitrate_info, list):
bitrate_info = [bitrate_info]
bitrate_urls = {}
for video_info in bitrate_info:
play_addr = video_info["PlayAddr"]
width = text.parse_int(play_addr.get("Width"))
height = text.parse_int(play_addr.get("Height"))
size = width * height
if size in bitrate_urls:
bitrate_urls[size] += play_addr.get("UrlList")
else:
bitrate_urls[size] = play_addr.get("UrlList").copy()
# Sort the URLs by descending quality.
sizes = list(bitrate_urls)
sizes.sort(reverse=True)
urls = [url for size in sizes for url in bitrate_urls[size]]
else:
urls = []
# As a fallback, try to look for the root playAddr,
# which won't necessarily point to the best quality.
if "playAddr" in video:
urls.append(video["playAddr"])
return urls
def _extract_audio(self, post):
audio = post["music"]
url = audio["playUrl"]