Repository: yt-dlp
Issue: [Vimeo] Vimeo subtitles fail with error 403 (CAPTCHA page) due to use of vimeo.com instead of player.vimeo.com
Labels: cant-reproduce,site-bug

### DO NOT REMOVE OR SKIP THE ISSUE TEMPLATE

- [x] I understand that I will be **blocked** if I *intentionally* remove or skip any mandatory\* field

### Checklist

- [x] I'm reporting that yt-dlp is broken on a **supported** site
- [x] I've verified that I have **updated yt-dlp to nightly or master** ([update instructions](https://github.com/yt-dlp/yt-dlp#update-channels))
- [x] I've checked that all provided URLs are playable in a browser with the same IP and same login details
- [x] I've checked that all URLs and arguments with special characters are [properly quoted or escaped](https://github.com/yt-dlp/yt-dlp/wiki/FAQ#video-url-contains-an-ampersand--and-im-getting-some-strange-output-1-2839-or-v-is-not-recognized-as-an-internal-or-external-command)
- [x] I've searched [known issues](https://github.com/yt-dlp/yt-dlp/issues/3766) and the [bugtracker](https://github.com/yt-dlp/yt-dlp/issues?q=) for similar issues **including closed ones**. DO NOT post duplicates
- [x] I've read the [guidelines for opening an issue](https://github.com/yt-dlp/yt-dlp/blob/master/CONTRIBUTING.md#opening-an-issue)
- [ ] I've read about [sharing account credentials](https://github.com/yt-dlp/yt-dlp/blob/master/CONTRIBUTING.md#are-you-willing-to-share-account-details-if-needed) and I'm willing to share it if required

### Region

Global (I am accessing from Australia)

### Provide a description that is worded well enough to be understood

### Short Version:

I believe Vimeo subtitles should be loaded from `player.vimeo.com` NOT `vimeo.com` (even though both often work) because the latter domain appears to have stricter Cloudflare rules that display a CAPTCHA page for some users (especially when on a VPN). 

This breaks the downloading of VTT subtitles. 

I don't seem to get a CAPTCHA page when downloading subtitles from `player.vimeo.com`.

### Further Details With Example:

When I attempt to download the following Vimeo video _WITH SUBTITLES_ the download fails due to a 403 Error on the VTT subtitles file. The 403 is being triggered by a Vimeo CAPTCHA page (presumably because I'm using a VPN) that requires a browser to interact with.

Sample Vimeo URL: https://player.vimeo.com/video/1049393408?h=2cb35698c0
Another video with same issue: https://player.vimeo.com/video/1048984535?h=a31d608c45

- I am NOT logged into Vimeo. These are Vimeo embed URLs with a hash in the URL that can be accessed by anybody that knows the URL. I'm not sure whether it being private makes any difference to the issue.
- The video and subtitles both display fine in the browser. 
- The video also downloads perfectly well when subtitles are not requested.
- The 403 error appears when loading the VTT subtitle file from `vimeo.com` domain
- The VTT subtitle file downloads correctly if I manually download from `player.vimeo.com` domain

I can see that yt-dlp is looking for the subtitles at the following URL:
https://vimeo.com/texttrack/208674890.vtt?token=679603b0_0x7ccc9366954d27f115285bec40f878866c8a37d3
(Error 403)

When I check Chrome dev tools it is downloading the VTT file from:
https://player.vimeo.com/texttrack/208674890.vtt?token=6795ffb1_0xeddbfa0b80f86caa13c0f963d9be29fc5146c67c
(URL loads successfully)

I presume that the path to the VTT is being parsed from the JSON embedded in the HTML page (https://player.vimeo.com/video/1049393408?h=2cb35698c0) where the JSON looks like this:

```
"text_tracks": [{
    "id": 208674890,
    "lang": "en-x-autogen",
    "url": "/texttrack/208674890.vtt?token=6795ffb1_0xeddbfa0b80f86caa13c0f963d9be29fc5146c67c",
    "kind": "captions",
    "label": "English (auto-generated)"
}],
```

If the HTML is coming from `player.vimeo.com` and browsers like Chrome also load the VTT files from `player.vimeo.com`, perhaps yt-dlp should also use this domain. Would there be any downsides to fetching the VTT subtitles from `player.vimeo.com`?

### Provide verbose output that clearly demonstrates the problem

- [x] 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
- [x] Copy the WHOLE output (starting with `[debug] Command-line config`) and insert it below

### Complete Verbose Output

```shell
yt-dlp -f "bestvideo*[height=720]+bestaudio*/best" --embed-subs --write-subs  "https://player.vimeo.com/video/1049393408?h=2cb35698c0" --download-sections "*0-20" --verbose -U

[debug] Command-line config: ['-f', 'bestvideo*[height=720]+bestaudio*/best', '--embed-subs', '--write-subs', 'https://player.vimeo.com/video/1049393408?h=2cb35698c0', '--download-sections', '*0-20', '--verbose', '-U']
[debug] Encodings: locale cp1252, fs utf-8, pref cp1252, out utf-8, error utf-8, screen utf-8
[debug] yt-dlp version nightly@2025.01.26.034637 from yt-dlp/yt-dlp-nightly-builds [3b4531934] (win_exe)
[debug] Python 3.10.11 (CPython AMD64 64bit) - Windows-10-10.0.19045-SP0 (OpenSSL 1.1.1t  7 Feb 2023)
[debug] exe versions: ffmpeg 7.1-essentials_build-www.gyan.dev (setts), ffprobe 7.1-essentials_build-www.gyan.dev
[debug] Optional libraries: Cryptodome-3.21.0, brotli-1.1.0, certifi-2024.12.14, curl_cffi-0.5.10, mutagen-1.47.0, requests-2.32.3, sqlite3-3.40.1, urllib3-2.3.0, websockets-14.2
[debug] Proxy map: {}
[debug] Request Handlers: urllib, requests, websockets, curl_cffi
[debug] Loaded 1839 extractors
[debug] Fetching release info: https://api.github.com/repos/yt-dlp/yt-dlp-nightly-builds/releases/latest
Latest version: nightly@2025.01.26.034637 from yt-dlp/yt-dlp-nightly-builds
yt-dlp is up to date (nightly@2025.01.26.034637 from yt-dlp/yt-dlp-nightly-builds)
[vimeo] Extracting URL: https://player.vimeo.com/video/1049393408?h=2cb35698c0
[vimeo] 1049393408: Downloading webpage
[vimeo] 1049393408: Downloading akfire_interconnect_quic m3u8 information
[vimeo] 1049393408: Downloading fastly_skyfire m3u8 information
[vimeo] 1049393408: Downloading akfire_interconnect_quic MPD information
WARNING: [vimeo] 1049393408: Failed to parse XML: not well-formed (invalid token): line 1, column 0
[vimeo] 1049393408: Downloading fastly_skyfire MPD information
WARNING: [vimeo] 1049393408: Failed to parse XML: not well-formed (invalid token): line 1, column 0
[info] 1049393408: Downloading subtitles: en-x-autogen
[debug] Sort order given by extractor: quality, res, fps, hdr:12, source
[debug] Formats sorted by: hasvid, ie_pref, quality, res, fps, hdr:12(7), source, lang, vcodec, channels, acodec, size, br, asr, proto, vext, aext, hasaud, id
[info] 1049393408: Downloading 1 format(s): hls-fastly_skyfire-960+hls-fastly_skyfire-audio-high-English
[info] 1049393408: Downloading 1 time ranges: 0.0-20.0
[info] Writing video subtitles to: 2025-01-22 mid-week video [1049393408].en-x-autogen.vtt
[debug] Invoking http downloader on "https://vimeo.com/texttrack/208674890.vtt?token=679603b0_0x7ccc9366954d27f115285bec40f878866c8a37d3"
ERROR: Unable to download video subtitles for 'en-x-autogen': HTTP Error 403: Forbidden
Traceback (most recent call last):
  File "yt_dlp\YoutubeDL.py", line 4364, in _write_subtitles
  File "yt_dlp\YoutubeDL.py", line 3212, in dl
  File "yt_dlp\downloader\common.py", line 464, in download
  File "yt_dlp\downloader\http.py", line 367, in real_download
  File "yt_dlp\downloader\http.py", line 118, in establish_connection
  File "yt_dlp\YoutubeDL.py", line 4175, in urlopen
  File "yt_dlp\networking\common.py", line 117, in send
  File "yt_dlp\networking\_helper.py", line 208, in wrapper
  File "yt_dlp\networking\common.py", line 340, in send
  File "yt_dlp\networking\_requests.py", line 365, in _send
yt_dlp.networking.exceptions.HTTPError: HTTP Error 403: Forbidden

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "yt_dlp\YoutubeDL.py", line 1637, in wrapper
  File "yt_dlp\YoutubeDL.py", line 1793, in __extract_info
  File "yt_dlp\YoutubeDL.py", line 1852, in process_ie_result
  File "yt_dlp\YoutubeDL.py", line 3024, in process_video_result
  File "yt_dlp\YoutubeDL.py", line 177, in wrapper
  File "yt_dlp\YoutubeDL.py", line 3280, in process_info
  File "yt_dlp\YoutubeDL.py", line 4372, in _write_subtitles
yt_dlp.utils.DownloadError: Unable to download video subtitles for 'en-x-autogen': HTTP Error 403: Forbidden
```