Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[youtube] yt-dlp fails to fall back if primary video server is unavailable #1986

Open
6 of 7 tasks
mateon1 opened this issue Dec 13, 2021 · 13 comments
Open
6 of 7 tasks
Labels
enhancement New feature or request site-enhancement Feature request for some website

Comments

@mateon1
Copy link

mateon1 commented Dec 13, 2021

Checklist

Region

No response

Description

For whatever reason, the server r1---sn-u2oxu-3g3s.googlevideo.com is unreachable for me. Despite this, videos with this server as the primary video server continue to play in the browser.
Youtube provides a fallback server in the mn query field of the /videoplayback link, and the browser uses that after the first connection fails or times out.
After failing the request:

https://r1---sn-u2oxu-3g3s.googlevideo.com/videoplayback?expire=1639406888&ei=xwi3YeyCOZSA7QTo5Z-wCg&ip=178.43.248.254&id=o-AKG06qiQ7vVcraci8eURvYya_hNC2r5YzHhgH1hJFr28&itag=302&aitags=133%2C134%2C135%2C136%2C160%2C242%2C243%2C244%2C247%2C278%2C298%2C299%2C302%2C303&source=youtube&requiressl=yes&mh=n1&mm=31%2C29&mn=sn-u2oxu-3g3s%2Csn-u2oxu-f5fed&ms=au%2Crdu&mv=m&mvi=1&pl=24&initcwndbps=633750&vprv=1&mime=video%2Fwebm&ns=AM7JhiAAIf0Niwbk_kwe69UG&gir=yes&clen=582421497&dur=2826.466&lmt=1636443049858752&mt=1639384385&fvip=1&keepalive=yes&fexp=24001373%2C24007246&c=WEB&txp=4416222&n=OgjuvMhKmfSAVw&sparams=expire%2Cei%2Cip%2Cid%2Caitags%2Csource%2Crequiressl%2Cvprv%2Cmime%2Cns%2Cgir%2Cclen%2Cdur%2Clmt&sig=AOq0QJ8wRAIgMrl5MAOeIg7hHI8uzdzab9fRpq6jjVuUSDU3iI3hVDECIFVoJW994O5iR7BhsOS2-r370X2u4u6-e1gVk520kROV&lsparams=mh%2Cmm%2Cmn%2Cms%2Cmv%2Cmvi%2Cpl%2Cinitcwndbps&lsig=AG3C_xAwRQIgExNob_C59kCKVgvdiQk80aGK_uF6hi1r9MtKsYdAzk0CIQCN4FlPvS589owvqUHTZdQwAtWNbho9-HJQTwZQjYRiig%3D%3D&alr=yes&cpn=dcP_Z2Q6nf8BHN8C&cver=2.20211210.01.00&range=0-917412&rn=1&rbuf=0

the browser connects to

https://r1---sn-u2oxu-f5fed.googlevideo.com/videoplayback?expire=1639406888&ei=xwi3YeyCOZSA7QTo5Z-wCg&ip=178.43.248.254&id=o-AKG06qiQ7vVcraci8eURvYya_hNC2r5YzHhgH1hJFr28&itag=302&aitags=133%2C134%2C135%2C136%2C160%2C242%2C243%2C244%2C247%2C278%2C298%2C299%2C302%2C303&source=youtube&requiressl=yes&mh=n1&mm=31%2C29&mn=sn-u2oxu-3g3s%2Csn-u2oxu-f5fed&ms=au%2Crdu&mv=m&mvi=1&pl=24&initcwndbps=633750&vprv=1&mime=video%2Fwebm&ns=AM7JhiAAIf0Niwbk_kwe69UG&gir=yes&clen=582421497&dur=2826.466&lmt=1636443049858752&mt=1639384385&fvip=1&keepalive=yes&fexp=24001373%2C24007246&c=WEB&txp=4416222&n=OgjuvMhKmfSAVw&sparams=expire%2Cei%2Cip%2Cid%2Caitags%2Csource%2Crequiressl%2Cvprv%2Cmime%2Cns%2Cgir%2Cclen%2Cdur%2Clmt&sig=AOq0QJ8wRAIgMrl5MAOeIg7hHI8uzdzab9fRpq6jjVuUSDU3iI3hVDECIFVoJW994O5iR7BhsOS2-r370X2u4u6-e1gVk520kROV&lsparams=mh%2Cmm%2Cmn%2Cms%2Cmv%2Cmvi%2Cpl%2Cinitcwndbps&lsig=AG3C_xAwRQIgExNob_C59kCKVgvdiQk80aGK_uF6hi1r9MtKsYdAzk0CIQCN4FlPvS589owvqUHTZdQwAtWNbho9-HJQTwZQjYRiig%3D%3D&alr=yes&cpn=dcP_Z2Q6nf8BHN8C&cver=2.20211210.01.00&fallback_count=1&range=0-10377&rn=3&rbuf=0

which succeeds.

yt-dlp should use that server as a fallback if connection to the primary one fails before it gives up.

NOTE:
I believe the debug log fails with 'Network is unreachable' because it tries to connect over broken ipv6 after the ipv4 connection fails.

NOTE 2:
In the browser, the first connection times out significantly quicker than in yt-dlp. In Firefox devtools, the first connection to sn-u2oxu-3g3s gets queued at 1.43s, and the connection to sn-u2oxu-f5fed starts at 2.50s.
yt-dlp with the -4 flag takes so long to retry all the connections 10 times that I've managed to capture a Firefox network trace of the relevant youtube page and write most of this report while waiting for the command to finally finish.

Verbose log

$ yt-dlp -v STdtpAZYJIM
[debug] Command-line config: ['-v', 'STdtpAZYJIM']
[debug] Encodings: locale UTF-8, fs utf-8, out utf-8, err utf-8, pref UTF-8
[debug] yt-dlp version 2021.12.01 [91f071af6]
[debug] Python version 3.9.6 (CPython 64bit) - Linux-5.10.72-x86_64-with-glibc2.33
[debug] exe versions: ffmpeg 4.4.1 (setts), ffprobe 4.4.1, rtmpdump 2.4
[debug] Optional libraries: Cryptodome, mutagen, sqlite, websockets
[debug] Proxy map: {}
[debug] [youtube] Extracting URL: STdtpAZYJIM
[youtube] STdtpAZYJIM: Downloading webpage
[youtube] STdtpAZYJIM: Downloading android player API JSON
[debug] Loading youtube-nsig.dc05ba20 from cache
[debug] [youtube] Decrypted nsig -vj6PE4UV1_lq4 => FcmX9ogR9qhaKg
[debug] Sort order given by extractor: quality, res, fps, hdr:12, source, codec:vp9.2, lang, proto
[debug] Formats sorted by: hasvid, ie_pref, quality, res, fps, hdr:12(7), source, vcodec:vp9.2(10), acodec, lang, proto, filesize, fs_approx, tbr, vbr, abr, asr, vext, aext, hasaud, id
[debug] Default format spec: bestvideo*+bestaudio/best
[info] STdtpAZYJIM: Downloading 1 format(s): 303+251
[debug] Invoking downloader on "https://r1---sn-u2oxu-3g3s.googlevideo.com/videoplayback?expire=1639411230&ei=vhm3YY3wH8eOv_IPqZ6J8A8&ip=178.43.249.1&id=o-AKiRQ4mZunaZUs3P2_ybYCNP5yAqRNKyYfAczEhF_dKb&itag=303&source=youtube&requiressl=yes&mh=n1&mm=31%2C29&mn=sn-u2oxu-3g3s%2Csn-u2oxu-f5fed&ms=au%2Crdu&mv=m&mvi=1&pl=24&initcwndbps=918750&vprv=1&mime=video%2Fwebm&gir=yes&clen=905762974&dur=2826.466&lmt=1636443049869271&mt=1639389179&fvip=1&keepalive=yes&fexp=24001373%2C24007246&c=ANDROID&txp=4416222&sparams=expire%2Cei%2Cip%2Cid%2Citag%2Csource%2Crequiressl%2Cvprv%2Cmime%2Cgir%2Cclen%2Cdur%2Clmt&sig=AOq0QJ8wRQIhAO-qTRC6QBM-gDzUBlgCXYequFm_YGPc8BVwPnviYLkWAiBGO-y3A8j_6hcCPUV06pXfbkiSMFjYrsDMvw5zQYN2Kg%3D%3D&lsparams=mh%2Cmm%2Cmn%2Cms%2Cmv%2Cmvi%2Cpl%2Cinitcwndbps&lsig=AG3C_xAwRQIhAMnqW4U3ykkrB7cUurpBM8YIHytniPVCwhFt-3XPanY7AiA_3_yxrLZVZltmXUdrsCWhXRU_1mvpJjJeU9jpkOcibg%3D%3D"
ERROR: unable to download video data: <urlopen error [Errno 101] Network is unreachable>
Traceback (most recent call last):
  File "/nix/store/k0z9n599k02hab8qjjp3ljw065iwjcvg-python3-3.9.6/lib/python3.9/urllib/request.py", line 1346, in do_open
    h.request(req.get_method(), req.selector, req.data, headers,
  File "/nix/store/k0z9n599k02hab8qjjp3ljw065iwjcvg-python3-3.9.6/lib/python3.9/http/client.py", line 1257, in request
    self._send_request(method, url, body, headers, encode_chunked)
  File "/nix/store/k0z9n599k02hab8qjjp3ljw065iwjcvg-python3-3.9.6/lib/python3.9/http/client.py", line 1303, in _send_request
    self.endheaders(body, encode_chunked=encode_chunked)
  File "/nix/store/k0z9n599k02hab8qjjp3ljw065iwjcvg-python3-3.9.6/lib/python3.9/http/client.py", line 1252, in endheaders
    self._send_output(message_body, encode_chunked=encode_chunked)
  File "/nix/store/k0z9n599k02hab8qjjp3ljw065iwjcvg-python3-3.9.6/lib/python3.9/http/client.py", line 1012, in _send_output
    self.send(msg)
  File "/nix/store/k0z9n599k02hab8qjjp3ljw065iwjcvg-python3-3.9.6/lib/python3.9/http/client.py", line 952, in send
    self.connect()
  File "/nix/store/k0z9n599k02hab8qjjp3ljw065iwjcvg-python3-3.9.6/lib/python3.9/http/client.py", line 1419, in connect
    super().connect()
  File "/nix/store/k0z9n599k02hab8qjjp3ljw065iwjcvg-python3-3.9.6/lib/python3.9/http/client.py", line 923, in connect
    self.sock = self._create_connection(
  File "/nix/store/k0z9n599k02hab8qjjp3ljw065iwjcvg-python3-3.9.6/lib/python3.9/socket.py", line 843, in create_connection
    raise err
  File "/nix/store/k0z9n599k02hab8qjjp3ljw065iwjcvg-python3-3.9.6/lib/python3.9/socket.py", line 831, in create_connection
    sock.connect(sa)
OSError: [Errno 101] Network is unreachable

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/nix/store/f32z0h1x4a2f2c53sa9s369v7fvrsgqr-python3.9-yt-dlp-2021.12.1/lib/python3.9/site-packages/yt_dlp/YoutubeDL.py", line 2916, in process_info
    partial_success, real_download = self.dl(fname, new_info)
  File "/nix/store/f32z0h1x4a2f2c53sa9s369v7fvrsgqr-python3.9-yt-dlp-2021.12.1/lib/python3.9/site-packages/yt_dlp/YoutubeDL.py", line 2654, in dl
    return fd.download(name, new_info, subtitle)
  File "/nix/store/f32z0h1x4a2f2c53sa9s369v7fvrsgqr-python3.9-yt-dlp-2021.12.1/lib/python3.9/site-packages/yt_dlp/downloader/common.py", line 421, in download
    ret = self.real_download(filename, info_dict)
  File "/nix/store/f32z0h1x4a2f2c53sa9s369v7fvrsgqr-python3.9-yt-dlp-2021.12.1/lib/python3.9/site-packages/yt_dlp/downloader/http.py", line 372, in real_download
    establish_connection()
  File "/nix/store/f32z0h1x4a2f2c53sa9s369v7fvrsgqr-python3.9-yt-dlp-2021.12.1/lib/python3.9/site-packages/yt_dlp/downloader/http.py", line 120, in establish_connection
    raise err
  File "/nix/store/f32z0h1x4a2f2c53sa9s369v7fvrsgqr-python3.9-yt-dlp-2021.12.1/lib/python3.9/site-packages/yt_dlp/downloader/http.py", line 114, in establish_connection
    ctx.data = self.ydl.urlopen(request)
  File "/nix/store/f32z0h1x4a2f2c53sa9s369v7fvrsgqr-python3.9-yt-dlp-2021.12.1/lib/python3.9/site-packages/yt_dlp/YoutubeDL.py", line 3385, in urlopen
    return self._opener.open(req, timeout=self._socket_timeout)
  File "/nix/store/k0z9n599k02hab8qjjp3ljw065iwjcvg-python3-3.9.6/lib/python3.9/urllib/request.py", line 517, in open
    response = self._open(req, data)
  File "/nix/store/k0z9n599k02hab8qjjp3ljw065iwjcvg-python3-3.9.6/lib/python3.9/urllib/request.py", line 534, in _open
    result = self._call_chain(self.handle_open, protocol, protocol +
  File "/nix/store/k0z9n599k02hab8qjjp3ljw065iwjcvg-python3-3.9.6/lib/python3.9/urllib/request.py", line 494, in _call_chain
    result = func(*args)
  File "/nix/store/f32z0h1x4a2f2c53sa9s369v7fvrsgqr-python3.9-yt-dlp-2021.12.1/lib/python3.9/site-packages/yt_dlp/utils.py", line 2929, in https_open
    return self.do_open(functools.partial(
  File "/nix/store/k0z9n599k02hab8qjjp3ljw065iwjcvg-python3-3.9.6/lib/python3.9/urllib/request.py", line 1349, in do_open
    raise URLError(err)
urllib.error.URLError: <urlopen error [Errno 101] Network is unreachable>


$ yt-dlp -v4 STdtpAZYJIM
[debug] Command-line config: ['-v4', 'STdtpAZYJIM']
[debug] Encodings: locale UTF-8, fs utf-8, out utf-8, err utf-8, pref UTF-8
[debug] yt-dlp version 2021.12.01 [91f071af6]
[debug] Python version 3.9.6 (CPython 64bit) - Linux-5.10.72-x86_64-with-glibc2.33
[debug] exe versions: ffmpeg 4.4.1 (setts), ffprobe 4.4.1, rtmpdump 2.4
[debug] Optional libraries: Cryptodome, mutagen, sqlite, websockets
[debug] Proxy map: {}
[debug] [youtube] Extracting URL: STdtpAZYJIM
[youtube] STdtpAZYJIM: Downloading webpage
[youtube] STdtpAZYJIM: Downloading android player API JSON
[debug] Loading youtube-nsig.dc05ba20 from cache
[debug] [youtube] Decrypted nsig jwg05Lwi-RC_tk => jPq9WfH26SzAEw
[debug] Sort order given by extractor: quality, res, fps, hdr:12, source, codec:vp9.2, lang, proto
[debug] Formats sorted by: hasvid, ie_pref, quality, res, fps, hdr:12(7), source, vcodec:vp9.2(10), acodec, lang, proto, filesize, fs_approx, tbr, vbr, abr, asr, vext, aext, hasaud, id
[debug] Default format spec: bestvideo*+bestaudio/best
[info] STdtpAZYJIM: Downloading 1 format(s): 303+251
[debug] Invoking downloader on "https://r1---sn-u2oxu-3g3s.googlevideo.com/videoplayback?expire=1639411321&ei=GRq3YY2SLb6F0u8Pq9WY4A8&ip=178.43.249.1&id=o-AC9Xt8_glXUZKScHy2at3wCPr_0nQf5hkqq92Dfiab5n&itag=303&source=youtube&requiressl=yes&mh=n1&mm=31%2C29&mn=sn-u2oxu-3g3s%2Csn-u2oxu-f5fed&ms=au%2Crdu&mv=m&mvi=1&pl=24&initcwndbps=932500&vprv=1&mime=video%2Fwebm&gir=yes&clen=905762974&dur=2826.466&lmt=1636443049869271&mt=1639389417&fvip=1&keepalive=yes&fexp=24001373%2C24007246&c=ANDROID&txp=4416222&sparams=expire%2Cei%2Cip%2Cid%2Citag%2Csource%2Crequiressl%2Cvprv%2Cmime%2Cgir%2Cclen%2Cdur%2Clmt&sig=AOq0QJ8wRAIgbeFlZoT5XfiWOzZVWbE6i42txmZfx8V0_6_w6Q6vGqkCIDwMk65b9jH5wqWMOMLiBYXow9vA-shC59jlrQT6OViv&lsparams=mh%2Cmm%2Cmn%2Cms%2Cmv%2Cmvi%2Cpl%2Cinitcwndbps&lsig=AG3C_xAwRAIgLg3hew_uOaXC7PzLHIuQon-AyhcxAL8tJKPe7F1-ScYCIBSEgcE7VvkRCpLZtQIEminRUSWCCCnn52_rwu5X9gAZ"
[download] Got server HTTP error: <urlopen error timed out>. Retrying (attempt 1 of 10) ...
[download] Got server HTTP error: <urlopen error timed out>. Retrying (attempt 2 of 10) ...
[download] Got server HTTP error: <urlopen error timed out>. Retrying (attempt 3 of 10) ...
[download] Got server HTTP error: <urlopen error timed out>. Retrying (attempt 4 of 10) ...
[download] Got server HTTP error: <urlopen error timed out>. Retrying (attempt 5 of 10) ...
[download] Got server HTTP error: <urlopen error timed out>. Retrying (attempt 6 of 10) ...
[download] Got server HTTP error: <urlopen error timed out>. Retrying (attempt 7 of 10) ...
[download] Got server HTTP error: <urlopen error timed out>. Retrying (attempt 8 of 10) ...
[download] Got server HTTP error: <urlopen error timed out>. Retrying (attempt 9 of 10) ...
[download] Got server HTTP error: <urlopen error timed out>. Retrying (attempt 10 of 10) ...
[download] Got server HTTP error: <urlopen error timed out>
ERROR: giving up after 10 retries
  File "/nix/store/f32z0h1x4a2f2c53sa9s369v7fvrsgqr-python3.9-yt-dlp-2021.12.1/bin/.yt-dlp-wrapped", line 9, in <module>
    sys.exit(main())
  File "/nix/store/f32z0h1x4a2f2c53sa9s369v7fvrsgqr-python3.9-yt-dlp-2021.12.1/lib/python3.9/site-packages/yt_dlp/__init__.py", line 823, in main
    _real_main(argv)
  File "/nix/store/f32z0h1x4a2f2c53sa9s369v7fvrsgqr-python3.9-yt-dlp-2021.12.1/lib/python3.9/site-packages/yt_dlp/__init__.py", line 813, in _real_main
    retcode = ydl.download(all_urls)
  File "/nix/store/f32z0h1x4a2f2c53sa9s369v7fvrsgqr-python3.9-yt-dlp-2021.12.1/lib/python3.9/site-packages/yt_dlp/YoutubeDL.py", line 3050, in download
    self.__download_wrapper(self.extract_info)(
  File "/nix/store/f32z0h1x4a2f2c53sa9s369v7fvrsgqr-python3.9-yt-dlp-2021.12.1/lib/python3.9/site-packages/yt_dlp/YoutubeDL.py", line 3023, in wrapper
    res = func(*args, **kwargs)
  File "/nix/store/f32z0h1x4a2f2c53sa9s369v7fvrsgqr-python3.9-yt-dlp-2021.12.1/lib/python3.9/site-packages/yt_dlp/YoutubeDL.py", line 1321, in extract_info
    return self.__extract_info(url, self.get_info_extractor(ie_key), download, extra_info, process)
  File "/nix/store/f32z0h1x4a2f2c53sa9s369v7fvrsgqr-python3.9-yt-dlp-2021.12.1/lib/python3.9/site-packages/yt_dlp/YoutubeDL.py", line 1329, in wrapper
    return func(self, *args, **kwargs)
  File "/nix/store/f32z0h1x4a2f2c53sa9s369v7fvrsgqr-python3.9-yt-dlp-2021.12.1/lib/python3.9/site-packages/yt_dlp/YoutubeDL.py", line 1412, in __extract_info
    return self.process_ie_result(ie_result, download, extra_info)
  File "/nix/store/f32z0h1x4a2f2c53sa9s369v7fvrsgqr-python3.9-yt-dlp-2021.12.1/lib/python3.9/site-packages/yt_dlp/YoutubeDL.py", line 1462, in process_ie_result
    ie_result = self.process_video_result(ie_result, download=download)
  File "/nix/store/f32z0h1x4a2f2c53sa9s369v7fvrsgqr-python3.9-yt-dlp-2021.12.1/lib/python3.9/site-packages/yt_dlp/YoutubeDL.py", line 2506, in process_video_result
    self.process_info(new_info)
  File "/nix/store/f32z0h1x4a2f2c53sa9s369v7fvrsgqr-python3.9-yt-dlp-2021.12.1/lib/python3.9/site-packages/yt_dlp/YoutubeDL.py", line 2916, in process_info
    partial_success, real_download = self.dl(fname, new_info)
  File "/nix/store/f32z0h1x4a2f2c53sa9s369v7fvrsgqr-python3.9-yt-dlp-2021.12.1/lib/python3.9/site-packages/yt_dlp/YoutubeDL.py", line 2654, in dl
    return fd.download(name, new_info, subtitle)
  File "/nix/store/f32z0h1x4a2f2c53sa9s369v7fvrsgqr-python3.9-yt-dlp-2021.12.1/lib/python3.9/site-packages/yt_dlp/downloader/common.py", line 421, in download
    ret = self.real_download(filename, info_dict)
  File "/nix/store/f32z0h1x4a2f2c53sa9s369v7fvrsgqr-python3.9-yt-dlp-2021.12.1/lib/python3.9/site-packages/yt_dlp/downloader/http.py", line 386, in real_download
    self.report_error('giving up after %s retries' % retries)
  File "/nix/store/f32z0h1x4a2f2c53sa9s369v7fvrsgqr-python3.9-yt-dlp-2021.12.1/lib/python3.9/site-packages/yt_dlp/downloader/common.py", line 174, in report_error
    self.ydl.report_error(*args, **kargs)
  File "/nix/store/f32z0h1x4a2f2c53sa9s369v7fvrsgqr-python3.9-yt-dlp-2021.12.1/lib/python3.9/site-packages/yt_dlp/YoutubeDL.py", line 902, in report_error
    self.trouble(f'{self._format_err("ERROR:", self.Styles.ERROR)} {message}', tb)
  File "/nix/store/f32z0h1x4a2f2c53sa9s369v7fvrsgqr-python3.9-yt-dlp-2021.12.1/lib/python3.9/site-packages/yt_dlp/YoutubeDL.py", line 834, in trouble
    tb_data = traceback.format_list(traceback.extract_stack())


[debug] Invoking downloader on "https://r1---sn-u2oxu-3g3s.googlevideo.com/videoplayback?expire=1639411321&ei=GRq3YY2SLb6F0u8Pq9WY4A8&ip=178.43.249.1&id=o-AC9Xt8_glXUZKScHy2at3wCPr_0nQf5hkqq92Dfiab5n&itag=251&source=youtube&requiressl=yes&mh=n1&mm=31%2C29&mn=sn-u2oxu-3g3s%2Csn-u2oxu-f5fed&ms=au%2Crdu&mv=m&mvi=1&pl=24&initcwndbps=932500&vprv=1&mime=audio%2Fwebm&gir=yes&clen=42415125&dur=2826.501&lmt=1636442952291937&mt=1639389417&fvip=1&keepalive=yes&fexp=24001373%2C24007246&c=ANDROID&txp=4411222&sparams=expire%2Cei%2Cip%2Cid%2Citag%2Csource%2Crequiressl%2Cvprv%2Cmime%2Cgir%2Cclen%2Cdur%2Clmt&sig=AOq0QJ8wRAIgR9FR_v8gURHyR_rFe7oQ7-FfF0bJvvWQuI7m4wYhJbACIEMMnxZK9Nt6EFA4bH68MoWE910VqU-f_FLidbtj5twg&lsparams=mh%2Cmm%2Cmn%2Cms%2Cmv%2Cmvi%2Cpl%2Cinitcwndbps&lsig=AG3C_xAwRAIgLg3hew_uOaXC7PzLHIuQon-AyhcxAL8tJKPe7F1-ScYCIBSEgcE7VvkRCpLZtQIEminRUSWCCCnn52_rwu5X9gAZ"
[download] Got server HTTP error: <urlopen error timed out>. Retrying (attempt 1 of 10) ...
[download] Got server HTTP error: <urlopen error timed out>. Retrying (attempt 2 of 10) ...
[download] Got server HTTP error: <urlopen error timed out>. Retrying (attempt 3 of 10) ...
[download] Got server HTTP error: <urlopen error timed out>. Retrying (attempt 4 of 10) ...
[download] Got server HTTP error: <urlopen error timed out>. Retrying (attempt 5 of 10) ...
[download] Got server HTTP error: <urlopen error timed out>. Retrying (attempt 6 of 10) ...
[download] Got server HTTP error: <urlopen error timed out>. Retrying (attempt 7 of 10) ...
[download] Got server HTTP error: <urlopen error timed out>. Retrying (attempt 8 of 10) ...
[download] Got server HTTP error: <urlopen error timed out>. Retrying (attempt 9 of 10) ...
[download] Got server HTTP error: <urlopen error timed out>. Retrying (attempt 10 of 10) ...
[download] Got server HTTP error: <urlopen error timed out>
ERROR: giving up after 10 retries
  File "/nix/store/f32z0h1x4a2f2c53sa9s369v7fvrsgqr-python3.9-yt-dlp-2021.12.1/bin/.yt-dlp-wrapped", line 9, in <module>
    sys.exit(main())
  File "/nix/store/f32z0h1x4a2f2c53sa9s369v7fvrsgqr-python3.9-yt-dlp-2021.12.1/lib/python3.9/site-packages/yt_dlp/__init__.py", line 823, in main
    _real_main(argv)
  File "/nix/store/f32z0h1x4a2f2c53sa9s369v7fvrsgqr-python3.9-yt-dlp-2021.12.1/lib/python3.9/site-packages/yt_dlp/__init__.py", line 813, in _real_main
    retcode = ydl.download(all_urls)
  File "/nix/store/f32z0h1x4a2f2c53sa9s369v7fvrsgqr-python3.9-yt-dlp-2021.12.1/lib/python3.9/site-packages/yt_dlp/YoutubeDL.py", line 3050, in download
    self.__download_wrapper(self.extract_info)(
  File "/nix/store/f32z0h1x4a2f2c53sa9s369v7fvrsgqr-python3.9-yt-dlp-2021.12.1/lib/python3.9/site-packages/yt_dlp/YoutubeDL.py", line 3023, in wrapper
    res = func(*args, **kwargs)
  File "/nix/store/f32z0h1x4a2f2c53sa9s369v7fvrsgqr-python3.9-yt-dlp-2021.12.1/lib/python3.9/site-packages/yt_dlp/YoutubeDL.py", line 1321, in extract_info
    return self.__extract_info(url, self.get_info_extractor(ie_key), download, extra_info, process)
  File "/nix/store/f32z0h1x4a2f2c53sa9s369v7fvrsgqr-python3.9-yt-dlp-2021.12.1/lib/python3.9/site-packages/yt_dlp/YoutubeDL.py", line 1329, in wrapper
    return func(self, *args, **kwargs)
  File "/nix/store/f32z0h1x4a2f2c53sa9s369v7fvrsgqr-python3.9-yt-dlp-2021.12.1/lib/python3.9/site-packages/yt_dlp/YoutubeDL.py", line 1412, in __extract_info
    return self.process_ie_result(ie_result, download, extra_info)
  File "/nix/store/f32z0h1x4a2f2c53sa9s369v7fvrsgqr-python3.9-yt-dlp-2021.12.1/lib/python3.9/site-packages/yt_dlp/YoutubeDL.py", line 1462, in process_ie_result
    ie_result = self.process_video_result(ie_result, download=download)
  File "/nix/store/f32z0h1x4a2f2c53sa9s369v7fvrsgqr-python3.9-yt-dlp-2021.12.1/lib/python3.9/site-packages/yt_dlp/YoutubeDL.py", line 2506, in process_video_result
    self.process_info(new_info)
  File "/nix/store/f32z0h1x4a2f2c53sa9s369v7fvrsgqr-python3.9-yt-dlp-2021.12.1/lib/python3.9/site-packages/yt_dlp/YoutubeDL.py", line 2916, in process_info
    partial_success, real_download = self.dl(fname, new_info)
  File "/nix/store/f32z0h1x4a2f2c53sa9s369v7fvrsgqr-python3.9-yt-dlp-2021.12.1/lib/python3.9/site-packages/yt_dlp/YoutubeDL.py", line 2654, in dl
    return fd.download(name, new_info, subtitle)
  File "/nix/store/f32z0h1x4a2f2c53sa9s369v7fvrsgqr-python3.9-yt-dlp-2021.12.1/lib/python3.9/site-packages/yt_dlp/downloader/common.py", line 421, in download
    ret = self.real_download(filename, info_dict)
  File "/nix/store/f32z0h1x4a2f2c53sa9s369v7fvrsgqr-python3.9-yt-dlp-2021.12.1/lib/python3.9/site-packages/yt_dlp/downloader/http.py", line 386, in real_download
    self.report_error('giving up after %s retries' % retries)
  File "/nix/store/f32z0h1x4a2f2c53sa9s369v7fvrsgqr-python3.9-yt-dlp-2021.12.1/lib/python3.9/site-packages/yt_dlp/downloader/common.py", line 174, in report_error
    self.ydl.report_error(*args, **kargs)
  File "/nix/store/f32z0h1x4a2f2c53sa9s369v7fvrsgqr-python3.9-yt-dlp-2021.12.1/lib/python3.9/site-packages/yt_dlp/YoutubeDL.py", line 902, in report_error
    self.trouble(f'{self._format_err("ERROR:", self.Styles.ERROR)} {message}', tb)
  File "/nix/store/f32z0h1x4a2f2c53sa9s369v7fvrsgqr-python3.9-yt-dlp-2021.12.1/lib/python3.9/site-packages/yt_dlp/YoutubeDL.py", line 834, in trouble
    tb_data = traceback.format_list(traceback.extract_stack())
@mateon1 mateon1 added site-bug Issue with a specific website triage Untriaged issue labels Dec 13, 2021
@pukkandan
Copy link
Member

Duplicate of #3, but this issue report is much more well described, so I will close that instead

yt-dlp with the -4 flag takes so long to retry all the connections 10 times that

yt-dlp has a default --socket-timeout of 20 secs

@pukkandan pukkandan added enhancement New feature or request site-enhancement Feature request for some website and removed site-bug Issue with a specific website triage Untriaged issue enhancement New feature or request labels Dec 13, 2021
@mateon1
Copy link
Author

mateon1 commented Dec 20, 2021

I'm not very experienced with ytdl code, so this is extremely hacky, but I've been able to implement a poor proof of concept. It works for downloading videos when yt-dlp is used standalone, but does not work when used via mpv's ytdl_hook.

index 6290884..f4981a8 100644
--- a/yt_dlp/downloader/http.py
+++ b/yt_dlp/downloader/http.py
@@ -374,6 +374,17 @@ class HttpFD(FileDownloader):
             except RetryDownload as e:
                 count += 1
                 if count <= retries:
+                    fallback_m = re.search(r'(?:---|\.)([^.]+)\.googlevideo\.com/.*&mn=([^&]*)', url)
+                    if fallback_m:
+                        host = fallback_m.group(1)
+                        fallbacks = fallback_m.group(2).split("%2C")
+                        assert host in fallbacks
+                        newhost = fallbacks[(fallbacks.index(host) + 1) % len(fallbacks)]
+                        url = re.sub(host+r"\.googlevideo\.com",newhost+".googlevideo.com",url)
+                        if "fallback_count=" in url:
+                            url = re.sub(r"fallback_count=[^&]*","fallback_count={}".format(count),url)
+                        else:
+                            url += "&fallback_count={}".format(count)
                     self.report_retry(e.source_error, count, retries)
                 else:
                     self.to_screen(f'[download] Got server HTTP error: {e.source_error}')

This is obviously a horrible solution, as it places extractor-specific code deep in generic http download code, and it doesn't always work as the broken ytdl_hook shows.
This might be a good place to add a retry_hook or something like that, that an extractor could set. Then all this code could be placed in the youtube extractor.

@pukkandan
Copy link
Member

Looks reasonable as a POC. ofc, like you said, this is not a proper solution and won't be merged as-is. Maybe the extractor can add a fallback_url in the info_dict which can be used by the downloader. But this will need to be handled properly by not just the HttpFD, but the fragment downloaders as well (and ideally the external downloaders too)

and it doesn't always work as the broken ytdl_hook shows.

mpv will have to implement it separately since they only use our extractors, not our downloaders. If we go with the fallback_url approach I mentioned above, mpv can ofc piggy-back off of it

@DenisMilon
Copy link

We really need this fix. I experienced about a dozen of such videos with broken primary google server link, but works fine with altenative servers provided via mn last week. I don't provide exact links here because I think it will not be 100% reproducible, because I can open this links (even with primary server) when I use VPN or Thor. So it may be related to some issues with google CDN servers in my country. As a test case for a fix I think it's possible to just set nonexistent server as a primary in url and working servers in mn (in test suit). I'll be very gracefull @pukkandan for your attention to this issue, thanks in advance.

@mateon1
Copy link
Author

mateon1 commented Jan 14, 2022

To anyone who wants to implement this: Seems like there are actually two kinds of URL formats youtube uses, one of them I believe is used for DASH (live videos, premieres?) and uses parameters between slashes in the URL path instead of using the URL query part.
A patch adjusted with this in mind (and tested in practice) - although it removes the fallback_count parameter:

--- a/yt_dlp/downloader/http.py
+++ b/yt_dlp/downloader/http.py
@@ -374,6 +374,15 @@ class HttpFD(FileDownloader):
             except RetryDownload as e:
                 count += 1
                 if count <= retries:
+                    fallback_m = re.search(r'(?:---|\.)([^./]+)\.googlevideo\.com/.*[&/]mn[=/]([^/&]*)', url)
+                    if fallback_m:
+                        host = fallback_m.group(1)
+                        fallbacks = fallback_m.group(2).split("%2C")
+                        assert host in fallbacks
+                        newhost = fallbacks[(fallbacks.index(host) + 1) % len(fallbacks)]
+                        url = re.sub(host+r"\.googlevideo\.com",newhost+".googlevideo.com",url)
+                        for prop in ["manifest_url","fragment_base_url"]:
+                            if prop in f: f[prop] = re.sub(host+r"\.googlevideo\.com",newhost+".googlevideo.com",f[prop])
                     self.report_retry(e.source_error, count, retries)
                 else:
                     self.to_screen(f'[download] Got server HTTP error: {e.source_error}')

@mateon1
Copy link
Author

mateon1 commented Jan 14, 2022

Additionally, here's a patch I'm using to block the specific server that doesn't work for me, might work as inspiration for where to place the fallback urls in the extractor code, but making that actually work would require redesigning some ytdl internals I'm not entirely comfortable with.
I'm using this patch because it allows mpv to work, despite the broken server.

--- a/yt_dlp/downloader/http.py
+++ b/yt_dlp/downloader/http.py
@@ -369,6 +369,8 @@ class HttpFD(FileDownloader):
 
         while count <= retries:
             try:
+                if "sn-u2oxu-3g3s.googlevideo.com/" in url:
+                    raise RetryDownload(RuntimeError("Bad video server"))
                 establish_connection()
                 return download()
             except RetryDownload as e:
--- a/yt_dlp/extractor/youtube.py
+++ b/yt_dlp/extractor/youtube.py
@@ -2846,6 +2846,21 @@ class YoutubeIE(YoutubeBaseInfoExtractor):
         # When throttling issue is fully fixed, remove this
         self._sort_formats(formats, ('quality', 'res', 'fps', 'hdr:12', 'source', 'codec:vp9.2', 'lang', 'proto'))
 
+        for f in formats:
+            if "sn-u2oxu-3g3s.googlevideo.com/" in f.get("url"):
+                url = f["url"]
+                fallback_m = re.search(r'(?:---|\.)([^./]+)\.googlevideo\.com/.*[&/]mn[=/]([^/&]*)', url)
+                #print(url + "\n", fallback_m, fallback_m.group(2) if fallback_m else None)
+                assert fallback_m
+                host = fallback_m.group(1)
+                fallbacks = fallback_m.group(2).split("%2C")
+                assert host in fallbacks
+                newhost = fallbacks[(fallbacks.index(host) + 1) % len(fallbacks)]
+                url = re.sub(host+r"\.googlevideo\.com",newhost+".googlevideo.com",url)
+                f["url"] = url
+                for prop in ["manifest_url","fragment_base_url"]:
+                    if prop in f: f[prop] = re.sub(host+r"\.googlevideo\.com",newhost+".googlevideo.com",f[prop])
+
         info = {
             'id': video_id,
             'title': self._live_title(video_title) if is_live else video_title,

@ChillerDragon
Copy link

Thanks @mateon1 for the ipv6 note. Indeed turning ipv6 off hotfixed the problem for me 🙂

So on linux it just needed those 2 commands with no reboot required

echo 1 > /proc/sys/net/ipv6/conf/default/disable_ipv6
echo 1 > /proc/sys/net/ipv6/conf/all/disable_ipv6

@pukkandan
Copy link
Member

So on linux it just needed those 2 commands with no reboot required

echo 1 > /proc/sys/net/ipv6/conf/default/disable_ipv6
echo 1 > /proc/sys/net/ipv6/conf/all/disable_ipv6

You can also just force yt-dlp to use ip4 with -4

@ChillerDragon
Copy link

So on linux it just needed those 2 commands with no reboot required

echo 1 > /proc/sys/net/ipv6/conf/default/disable_ipv6
echo 1 > /proc/sys/net/ipv6/conf/all/disable_ipv6

You can also just force yt-dlp to use ip4 with -4

Ah wopsi I didn't see that. That is ofc way better 👍

@LoveIsGrief
Copy link

Has the fallback mechanism been implemented in any way yet? Is there some kind of flag one can use?

@pukkandan
Copy link
Member

pukkandan commented Aug 20, 2023

You can try out #5639 or #1986 (comment), otherwise no

@LoveIsGrief
Copy link

The PR has conflicts. Maybe the patch will work. If I get tired of opening a separate, clean browser instance for every single youtube video, I might give it a shot. Thanks.

@Zapeth
Copy link

Zapeth commented Feb 29, 2024

Have there been any updates in terms of implementing a fallback method when the primary server is not reachable?

I've been getting the same error since yesterday with yt-dlp for any youtube video I try (with either -4 or -6 setting as well), but they all load in the browser, so I'm pretty sure its the same issue.

Or is it maybe possible to override using a different server via cli/url parameters as a workaround?

edit: Turns out I just had an unlucky video selection, some videos still load as usual, others fail with the described issue

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request site-enhancement Feature request for some website
Projects
Status: Working around youtube's bugs
Development

No branches or pull requests

6 participants