yt-dlp: [TikTok] Failed to parse JSON/ No video formats found

DO NOT REMOVE OR SKIP THE ISSUE TEMPLATE

  • I understand that I will be blocked if I intentionally remove or skip any mandatory* field

Checklist

Please make sure the question is worded well enough to be understood

EDIT:

yt-dlp’s TikTok extractor is failing to parse JSON from the feed API endpoint even on nightly/master or with passing --extractor-args "tiktok:api_hostname=api22-normal-c-useast2a.tiktokv.com"

original log for reference
yt-dlp -f "bv*[vcodec^=avc]+ba[ext=m4a]/b[ext=mp4]/b" https://www.tiktok.com/@pouveronica/video/7322479967147740459
[TikTok] Extracting URL: https://www.tiktok.com/@pouveronica/video/7322479967147740459
[TikTok] 7322479967147740459: Downloading video feed
WARNING: [TikTok] Expecting value in '': line 1 column 1 (char 0). Retrying... (attempt 1 of 4)
[TikTok] 7322479967147740459: Downloading video feed
WARNING: [TikTok] Expecting value in '': line 1 column 1 (char 0). Retrying... (attempt 2 of 4)
[TikTok] 7322479967147740459: Downloading video feed
WARNING: [TikTok] Expecting value in '': line 1 column 1 (char 0). Retrying... (attempt 3 of 4)
[TikTok] 7322479967147740459: Downloading video feed
WARNING: [TikTok] 7322479967147740459: Failed to parse JSON (caused by JSONDecodeError("Expecting value in '': line 1 column 1 (char 0)")); trying with webpage
[TikTok] 7322479967147740459: Downloading webpage
[info] 7322479967147740459: Downloading 1 format(s): download
ERROR: unable to open for writing: [Errno 2] No such file or directory: 'Replying to @Vy Puthny some key differences in finance and accounting 😃  #hr #humanresources #hrinsight #hrrole #hrtips #hrtrend #hrknowledge #learning #careergrowth #accounting #finance #manpoweroutsourcing #eor  @Nica - និកា  [7322479967147740459].mp4.part'

Provide verbose output that clearly demonstrates the problem

  • Run your yt-dlp command with -vU flag added (yt-dlp -vU <your command line>)
  • If using API, add 'verbose': True to YoutubeDL params instead
  • Copy the WHOLE output (starting with [debug] Command-line config) and insert it below

Complete Verbose Output

[debug] Command-line config: ['-v', '-U', '-o', '%(title).200B.%(ext)s', 'https://www.tiktok.com/@mix_editor_5/video/7342789941371571462']
[debug] Encodings: locale cp1252, fs utf-8, pref cp1252, out utf-8, error utf-8, screen utf-8
[debug] yt-dlp version master@2024.03.20.232831 from yt-dlp/yt-dlp-master-builds [07f5b2f75] (win_exe)
[debug] Python 3.8.10 (CPython AMD64 64bit) - Windows-10-10.0.22631-SP0 (OpenSSL 1.1.1k  25 Mar 2021)
[debug] exe versions: ffmpeg 6.1.1-full_build-www.gyan.dev (setts), ffprobe 6.1.1-full_build-www.gyan.dev, phantomjs 2.5.0, rtmpdump 2.4
[debug] Optional libraries: Cryptodome-3.20.0, brotli-1.1.0, certifi-2024.02.02, curl_cffi-0.5.10, mutagen-1.47.0, requests-2.31.0, sqlite3-3.35.5, urllib3-2.2.1, websockets-12.0
[debug] Proxy map: {}
[debug] Request Handlers: urllib, requests, websockets, curl_cffi
[debug] Loaded 1806 extractors
[debug] Fetching release info: https://api.github.com/repos/yt-dlp/yt-dlp-master-builds/releases/latest
Latest version: master@2024.03.20.232831 from yt-dlp/yt-dlp-master-builds
yt-dlp is up to date (master@2024.03.20.232831 from yt-dlp/yt-dlp-master-builds)
[TikTok] Extracting URL: https://www.tiktok.com/@mix_editor_5/video/7342789941371571462
[TikTok] 7342789941371571462: Downloading video feed
WARNING: [TikTok] Expecting value in '': line 1 column 1 (char 0). Retrying... (attempt 1 of 4)
[TikTok] 7342789941371571462: Downloading video feed
WARNING: [TikTok] Expecting value in '': line 1 column 1 (char 0). Retrying... (attempt 2 of 4)
[TikTok] 7342789941371571462: Downloading video feed
WARNING: [TikTok] Expecting value in '': line 1 column 1 (char 0). Retrying... (attempt 3 of 4)
[TikTok] 7342789941371571462: Downloading video feed
WARNING: [TikTok] 7342789941371571462: Failed to parse JSON (caused by JSONDecodeError("Expecting value in '': line 1 column 1 (char 0)")); trying with webpage
[TikTok] 7342789941371571462: Downloading webpage
[debug] [TikTok] Found universal data for rehydration
[debug] Formats sorted by: hasvid, ie_pref, lang, quality, res, fps, hdr:12(7), vcodec:vp9.2(10), channels, acodec, size, br, asr, proto, vext, aext, hasaud, source, id
[debug] Default format spec: bestvideo*+bestaudio/best
[info] 7342789941371571462: Downloading 1 format(s): download
[debug] Invoking http downloader on "https://v16-webapp-prime.tiktok.com/video/tos/useast2a/tos-useast2a-ve-0068c004/okMCLjLWAqjFQ5CIXaAfaAiMNgbSzfFCh48fSV/?a=1988&ch=0&cr=3&dr=0&lr=tiktok_m&cd=0%7C0%7C1%7C&cv=1&br=1800&bt=900&bti=ODszNWYuMDE6&cs=0&ds=3&ft=4fUEKMFx8Zmo0H.5Y94jV..7rpWrKsd.&mime_type=video_mp4&qs=0&rc=NGQ5OTY1NTdnaDM0Ojs1ZUBpMzs4N3Q5cnlncTMzNzczM0AzLi9gMi4vNjUxX14uLV4yYSNqZWpoMmQ0NWdgLS1kMTZzcw%3D%3D&btag=e00088000&expire=1711056619&l=20240321153003FA72D5DD8E2EFA514E6F&ply_type=2&policy=2&signature=eb207c9a24f5509f1e4668cbac840d00&tk=tt_chain_token"
[debug] File locking is not supported. Proceeding without locking
[download] Destination: #CapCut #🥺💔 #new #trending #plz #plz #😭😭 #viralvideo #plunfrezzmyaccount🙏🥺 #plzvirulvideo😥 #plzviral🥺🥺🙏🙏foryoupage ⧸⧸ 𝑫𝒆𝒂𝒓 𝑻𝒊𝒌𝒕𝒐𝒌 𝑻.mp4
[download] 100% of    1.62MiB in 00:00:00 at 14.79MiB/s

About this issue

  • Original URL
  • State: open
  • Created 3 months ago
  • Reactions: 7
  • Comments: 38 (6 by maintainers)

Most upvoted comments

while I am against hardcoding someone else’s iid into the extractor, perhaps a “bring your own iid” approach would be acceptable until a better/proper solution is found.

here’s a patch with a minimal diff that would allow you to pass --extractor-args "tiktok:iid=VALUE", replacing VALUE with an actual working iid value

diff --git a/yt_dlp/extractor/tiktok.py b/yt_dlp/extractor/tiktok.py
index 02545bc79..e7d0c2063 100644
--- a/yt_dlp/extractor/tiktok.py
+++ b/yt_dlp/extractor/tiktok.py
@@ -32,8 +32,8 @@
 class TikTokBaseIE(InfoExtractor):
     _APP_VERSIONS = [('26.1.3', '260103'), ('26.1.2', '260102'), ('26.1.1', '260101'), ('25.6.2', '250602')]
     _WORKING_APP_VERSION = None
-    _APP_NAME = 'trill'
-    _AID = 1180
+    _APP_NAME = 'musical_ly'
+    _AID = 0
     _UPLOADER_URL_FORMAT = 'https://www.tiktok.com/@%s'
     _WEBPAGE_HOST = 'https://www.tiktok.com/'
     QUALITIES = ('360p', '540p', '720p', '1080p')
@@ -41,7 +41,7 @@ class TikTokBaseIE(InfoExtractor):
     @property
     def _API_HOSTNAME(self):
         return self._configuration_arg(
-            'api_hostname', ['api22-normal-c-useast2a.tiktokv.com'], ie_key=TikTokIE)[0]
+            'api_hostname', ['api22-normal-c-alisg.tiktokv.com'], ie_key=TikTokIE)[0]
 
     @staticmethod
     def _create_url(user_id, video_id):
@@ -106,6 +106,8 @@ def _build_api_query(self, query, app_version, manifest_app_version):
             'ssmix': 'a',
             'as': 'a1qwert123',
             'cp': 'cbfhckdckkde1',
+            'iid': self._configuration_arg('iid', ['0'], ie_key=TikTokIE)[0],
+            'device_id': ''.join(random.choices(string.digits, k=16)),
         }
 
     def _call_api(self, ep, query, video_id, fatal=True,

I’m not very related to tiktok extractor. But I think that with this piece of code can solve the problem. The json response is identical to what the old api used to respond:

import requests

video_id = 'ur video id'
headers = {'User-Agent': 'Mozilla/5.0 (Linux; Android 10; K) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/122.0.0.0 Mobile Safari/537.36' }

tiktok_video_data_endpoint = 'https://api22-normal-c-alisg.tiktokv.com/aweme/v1/feed/'
params = {
            "iid": "7318518857994389254",
            "device_id": "7318517321748022790",
            "channel": "googleplay",
            "app_name": "musical_ly",
            "version_code": "300904",
            "device_platform": "android",
            "device_type": "ASUS_Z01QD",
            "os_version": "9",
            "aweme_id": video_id  # now video id is used here
        }

try:
    json_video_data = requests.get(tiktok_video_data_endpoint, params=params, headers=headers).json()
except Exception as e:
    raise SystemExit('connection error with api')

print(json_video_data)

This issue still happen on nightly and master right?

Yes it does

Does that mean there’s still a risk of access to the TikTok API endpoint being down again in the future?

The endpoint hasn’t been down. It has become more restricted. One solution to these increased restrictions is to pass an iid & device_id pair.

Each installation of the TT mobile app is assigned a unique iid value, presumably for security and tracking purposes. If we were to add this 1 iid value to yt-dlp’s TT extractor, then due to the volume of yt-dlp users, there is a high probability that this iid would be blocked by TT shortly after the next stable release (if not sooner). IMO this is not a viable solution. It would be fairly easy to create a plugin that utilizes this solution, though

format 0 but quality is not good

A verbose log is just about always required when reporting a bug, as it shows things such as the version of yt-dlp, device you are running on, proxies used, dependencies installed, extra setting from a config file…

            "aweme_id": video_id  # now video id is used here

^ nah this is how we were always doing it

            "iid": "7318518857994389254",
            "device_id": "7318517321748022790",

^ this is what is new, and what I’ve seen a couple other projects on github start doing today.

TikTok seems to be enforcing/checking the iid and device_id params now for the feed endpoint. The problem here, is that iid is the installation id of the mobile app and device_id is the accompanying id for the mobile device on which it is installed. These params cannot be faked with random values. So since this iid and device_id belong to a real TikTok installation on someone’s device, it’s likely only a matter of time before it is banned for spam/scraping

@bashonly Seems like a decent workaround. Is there an easy way to get our own iid from the iOS tiktok app?

try it, work well.

https://www.tiktokarchive.com/

it does not work, bro.

Anyone have any ideas on how to fix this?

sorry for asking questions here but I need to know if there’s ANY other way of downloading in full quality (watermarked or not) from the webpage. i’m not web literate, so I’m not sure if it’s possible to manually access a video through your browser or something, but since i’ve never seen a mention of it i’m guessing it’s not? just wanna be sure很抱歉在这里提问,但我需要知道是否有任何其他方法可以从网页下载全质量(水印或无水印)。我不懂网络,所以我不确定是否可以通过浏览器或其他东西手动访问视频,但由于我从未见过提及它,我猜它不是?只是想确定一下

try it, work well.

https://www.tiktokarchive.com/

i want data in json and it returns but when i open the video url in my browser i get access deneid Access Denied i try to open this url in different browsers but result is same You don’t have permission to access “http://v16-webapp-prime.tiktok.com/video/tos/useast2a/tos-useast2a-ve-0068c003/o0lJmAxvtJdSiEIlb5FfBBQ0R1U7RYQQRfD1E8/?” on this server. Reference #18.9584dead.1711040325.fc05b85

That’s because some specific cookies have to be passed with the request, which your browser obviously doesn’t do. So it’s not an actual problem in this case Just checked the code, it isn’t. Sorry for misinformation

yt-dlp should still be able to download the webpage version of the video in most cases. Try adding -f 0 to your command to select the format without a watermark. The quality will not be quite as good as the mobile API feed formats, though.

ERROR: unable to open for writing: [Errno 2] No such file or directory ERROR: unable to open for writing: [Errno 22] Invalid argument:

If you get an error like this, it just means the output filename is too long. Add -o "%(title).100B [%(id)s].%(ext)s" to your command

You get a verbose log by adding --verbose (or -v for short) to your command:

[debug] Command-line config: ['-v', '-U', '-o', '%(title).200B.%(ext)s', 'https://www.tiktok.com/@mix_editor_5/video/7342789941371571462']
[debug] Encodings: locale cp1252, fs utf-8, pref cp1252, out utf-8, error utf-8, screen utf-8
[debug] yt-dlp version master@2024.03.20.232831 from yt-dlp/yt-dlp-master-builds [07f5b2f75] (win_exe)
[debug] Python 3.8.10 (CPython AMD64 64bit) - Windows-10-10.0.22631-SP0 (OpenSSL 1.1.1k  25 Mar 2021)
[debug] exe versions: ffmpeg 6.1.1-full_build-www.gyan.dev (setts), ffprobe 6.1.1-full_build-www.gyan.dev, phantomjs 2.5.0, rtmpdump 2.4
[debug] Optional libraries: Cryptodome-3.20.0, brotli-1.1.0, certifi-2024.02.02, curl_cffi-0.5.10, mutagen-1.47.0, requests-2.31.0, sqlite3-3.35.5, urllib3-2.2.1, websockets-12.0
[debug] Proxy map: {}
[debug] Request Handlers: urllib, requests, websockets, curl_cffi
[debug] Loaded 1806 extractors
[debug] Fetching release info: https://api.github.com/repos/yt-dlp/yt-dlp-master-builds/releases/latest
Latest version: master@2024.03.20.232831 from yt-dlp/yt-dlp-master-builds
yt-dlp is up to date (master@2024.03.20.232831 from yt-dlp/yt-dlp-master-builds)
[TikTok] Extracting URL: https://www.tiktok.com/@mix_editor_5/video/7342789941371571462
[TikTok] 7342789941371571462: Downloading video feed
WARNING: [TikTok] Expecting value in '': line 1 column 1 (char 0). Retrying... (attempt 1 of 4)
[TikTok] 7342789941371571462: Downloading video feed
WARNING: [TikTok] Expecting value in '': line 1 column 1 (char 0). Retrying... (attempt 2 of 4)
[TikTok] 7342789941371571462: Downloading video feed
WARNING: [TikTok] Expecting value in '': line 1 column 1 (char 0). Retrying... (attempt 3 of 4)
[TikTok] 7342789941371571462: Downloading video feed
WARNING: [TikTok] 7342789941371571462: Failed to parse JSON (caused by JSONDecodeError("Expecting value in '': line 1 column 1 (char 0)")); trying with webpage
[TikTok] 7342789941371571462: Downloading webpage
[debug] [TikTok] Found universal data for rehydration
[debug] Formats sorted by: hasvid, ie_pref, lang, quality, res, fps, hdr:12(7), vcodec:vp9.2(10), channels, acodec, size, br, asr, proto, vext, aext, hasaud, source, id
[debug] Default format spec: bestvideo*+bestaudio/best
[info] 7342789941371571462: Downloading 1 format(s): download
[debug] Invoking http downloader on "https://v16-webapp-prime.tiktok.com/video/tos/useast2a/tos-useast2a-ve-0068c004/okMCLjLWAqjFQ5CIXaAfaAiMNgbSzfFCh48fSV/?a=1988&ch=0&cr=3&dr=0&lr=tiktok_m&cd=0%7C0%7C1%7C&cv=1&br=1800&bt=900&bti=ODszNWYuMDE6&cs=0&ds=3&ft=4fUEKMFx8Zmo0H.5Y94jV..7rpWrKsd.&mime_type=video_mp4&qs=0&rc=NGQ5OTY1NTdnaDM0Ojs1ZUBpMzs4N3Q5cnlncTMzNzczM0AzLi9gMi4vNjUxX14uLV4yYSNqZWpoMmQ0NWdgLS1kMTZzcw%3D%3D&btag=e00088000&expire=1711056619&l=20240321153003FA72D5DD8E2EFA514E6F&ply_type=2&policy=2&signature=eb207c9a24f5509f1e4668cbac840d00&tk=tt_chain_token"
[debug] File locking is not supported. Proceeding without locking
[download] Destination: #CapCut #🥺💔 #new #trending #plz #plz #😭😭 #viralvideo #plunfrezzmyaccount🙏🥺 #plzvirulvideo😥 #plzviral🥺🥺🙏🙏foryoupage ⧸⧸ 𝑫𝒆𝒂𝒓 𝑻𝒊𝒌𝒕𝒐𝒌 𝑻.mp4
[download] 100% of    1.62MiB in 00:00:00 at 14.79MiB/s