yt-dlp: [Zoom] fails at authencation for meeting recording with password

Checklist

Region

No response

Description

Password-protected Zoom meeting recording cannot be downloaded. Not tested with recordings without password protection.

Verbose log

$ yt-dlp 'https://zoom.us/rec/share/redacted' --video-pass 'redacted' -v
[debug] Command-line config: ['https://zoom.us/rec/share/redacted', '--video-pass', 'redacted', '-v']
[debug] Encodings: locale UTF-8, fs utf-8, out utf-8, err utf-8, pref UTF-8
[debug] yt-dlp version 2021.12.27 [6223f67a8]
[debug] Python version 3.9.9 (CPython 64bit) - Linux-5.15.5-051505-generic-x86_64-with-glibc2.34
[debug] exe versions: ffmpeg n4.4.1-3-ge16ff82624-20211127 (setts), ffprobe n4.4.1-3-ge16ff82624-20211127, rtmpdump 2.4
[debug] Optional libraries: Crypto, mutagen, sqlite, websockets
[debug] Proxy map: {}
[debug] [zoom] Extracting URL: https://zoom.us/rec/share/redacted
[zoom] redacted: Downloading webpage
[zoom] redacted: Validating passcode
ERROR: [zoom] redacted: Wrong passcode: HTTP Error 401: Unauthorized (caused by <HTTPError 401: 'Unauthorized'>); please report this issue on  https://github.com/yt-dlp/yt-dlp . Make sure you are using the latest version; see  https://github.com/yt-dlp/yt-dlp  on how to update. Be sure to call yt-dlp with the --verbose flag and include its complete output. (caused by <HTTPError 401: 'Unauthorized'>); please report this issue on  https://github.com/yt-dlp/yt-dlp . Make sure you are using the latest version; see  https://github.com/yt-dlp/yt-dlp  on how to update. Be sure to call yt-dlp with the --verbose flag and include its complete output.
  File "/home/linuxbrew/.linuxbrew/Cellar/yt-dlp/2021.12.27/libexec/lib/python3.9/site-packages/yt_dlp/extractor/common.py", line 717, in _request_webpage
    return self._downloader.urlopen(url_or_request)
  File "/home/linuxbrew/.linuxbrew/Cellar/yt-dlp/2021.12.27/libexec/lib/python3.9/site-packages/yt_dlp/YoutubeDL.py", line 3458, in urlopen
    return self._opener.open(req, timeout=self._socket_timeout)
  File "/home/linuxbrew/.linuxbrew/opt/python@3.9/lib/python3.9/urllib/request.py", line 523, in open
    response = meth(req, response)
  File "/home/linuxbrew/.linuxbrew/opt/python@3.9/lib/python3.9/urllib/request.py", line 632, in http_response
    response = self.parent.error(
  File "/home/linuxbrew/.linuxbrew/opt/python@3.9/lib/python3.9/urllib/request.py", line 561, in error
    return self._call_chain(*args)
  File "/home/linuxbrew/.linuxbrew/opt/python@3.9/lib/python3.9/urllib/request.py", line 494, in _call_chain
    result = func(*args)
  File "/home/linuxbrew/.linuxbrew/opt/python@3.9/lib/python3.9/urllib/request.py", line 641, in http_error_default
    raise HTTPError(req.full_url, code, msg, hdrs, fp)

About this issue

  • Original URL
  • State: open
  • Created 2 years ago
  • Reactions: 10
  • Comments: 20 (2 by maintainers)

Most upvoted comments

If you are on Firefox, you can just <kbd>Shift</kbd>+right click to force the context menu, then just click “Save Video As…” as usual. For Chromium browsers, I guess you could use some “enable right click” extensions, which should be less sketchy than the above option ^^

Have the same issue. The validate_passwd endpoint now seems to use some weird signature in the headers. Unlocking the video in browser and passing cookies does work around the issue.

I can provide a video URL and password if anyone wants to work on this (expired)

Faced with the same situation, I tried right-clicking and downloading the video directly, but I could not download it due to a 403 error, perhaps because Zoom had patched it. So, I found the other way to download video with developer tools.

1. Open developer tools and check the video file with Status 206, Type Media.

image

2. Right-click the row and copy it with Copy -> Copy as cURL.

image

3. Paste the copied content into a text editor and modify -H 'range: bytes=A-B' to -H 'range: bytes=0-B'.

image

4. Finally, add --compressed --output FILE_NAME.mp4 at the end of the code and run the modified code in the terminal.

image

5. Success!

image

Manual workaround

In the meantime, a workaround for manually downloading the recordings:

  1. Open the zoom link, enter the credentials, you should see the video player.
  2. Open developer tools (F12 or Ctrl+Shift+I) and paste the following into the Console tab:
javascript:function enableContextMenu(aggressive = true) { void(document.ondragstart=null); void(document.onselectstart=null); void(document.onclick=null); void(document.onmousedown=null); void(document.onmouseup=null); void(document.body.oncontextmenu=null); enableRightClickLight(document); if (aggressive) { enableRightClick(document); removeContextMenuOnAll('body'); removeContextMenuOnAll('img'); removeContextMenuOnAll('td'); } } function removeContextMenuOnAll(tagName) { var elements = document.getElementsByTagName(tagName); for (var i = 0; i < elements.length; i++) { enableRightClick(elements[i]); enablePointerEvents(elements[i]); } } function enableRightClickLight(el) { el || (el = document); el.addEventListener('contextmenu', bringBackDefault, true); } function enableRightClick(el) { el || (el = document); el.addEventListener('contextmenu', bringBackDefault, true); el.addEventListener('dragstart', bringBackDefault, true); el.addEventListener('selectstart', bringBackDefault, true); el.addEventListener('click', bringBackDefault, true); el.addEventListener('mousedown', bringBackDefault, true); el.addEventListener('mouseup', bringBackDefault, true); } function restoreRightClick(el) { el || (el = document); el.removeEventListener('contextmenu', bringBackDefault, true); el.removeEventListener('dragstart', bringBackDefault, true); el.removeEventListener('selectstart', bringBackDefault, true); el.removeEventListener('click', bringBackDefault, true); el.removeEventListener('mousedown', bringBackDefault, true); el.removeEventListener('mouseup', bringBackDefault, true); } function bringBackDefault(event) { event.returnValue = true; (typeof event.stopPropagation === 'function') && event.stopPropagation(); (typeof event.cancelBubble === 'function') && event.cancelBubble(); } function enablePointerEvents(el) {  if (!el) return; el.style.pointerEvents='auto'; el.style.webkitTouchCallout='default'; el.style.webkitUserSelect='auto'; el.style.MozUserSelect='auto'; el.style.msUserSelect='auto'; el.style.userSelect='auto'; enablePointerEvents(el.parentElement); } function appendDownloadLink() { const videoSrc = document.querySelector(".player-view").querySelector("video").getAttribute("src"); const textNode = document.createTextNode("Right-clink on this link and press \"Save link as\""); const link = document.createElement("a"); link.append(textNode); link.href = videoSrc;const textRightZoomColumn = document.querySelector(".text-right.zm-col.zm-col-8"); textRightZoomColumn.appendChild(document.createElement("br")); textRightZoomColumn.appendChild(link); } enableContextMenu(); appendDownloadLink()
  1. In the top right corner, you should see a text link appear that reads Right-clink on this link and press "Save link as"
  2. Do what the link says 😃

2023-09-16_14-10-06

If it doesn’t work, Zoom must’ve changed something, so see the technical explanation below.


Technical explanation:

There are three parts:

  1. Zoom disables right clicks via event listeners - in theory, that’s the only thing stopping you. I copy-pasted the script from this stackoverflow answer that enables right clicks. Once it’s executed, you can right-click on the video player and press “Save video as”.
  2. The video link is extracted and added as a child element purely for convenience and in case Zoom does something with their web player that prevents the direct action “Save video as”. In this case, you can modify the script to extract the video url from the correct (new) place, and it should work the same way as before.
  3. The one-liner script you see above is a combination of 1 + 2, in one line for convenience.

Links:

is there any hope for this to work(get fixed) in near future

Unless you know how to, no…


@sagz You can open and “unlock” the links in browser and then pass cookies to yt-dlp. Though copy-pasting 1200 passwords is quite a bit of work too… It could be automated through a headless browser/userscript

I’m afraid I could not get the --cookies or --cookies-from-browser workarounds to succeed. yt-dlp still says the video is passcode-protected after loading cookies, and if also given the --video-password it still gets a 401 Unauthorized error.

Looks like Zoom has continued locking this stuff down, unfortunately.

A browser extension (in a dedicated profile) was the solution for me this time, but I’d rather use yt-dlp of course.