Open TagAcheron opened 2 years ago
YT made the client solve a puzzle in order to get full download speed. We can do that now (again, after YT broke it last night) and an imminent release will fix it. Or you can install from the git HEAD using pip, but as you're using the Windows .exe probably you should wait for the release.
This issue also happened to me.
using the last update, the download stuck at 74.93KiB/s
Good luck team.
Yeah I was also getting this issue.. Previously it was running fine, now something wrong may be happened with youtube. Then I updated it to the latest version, but no improvement.
Using the "fixed" version of the youtube.py, works now, but there is a problem. Too much processing power is needed to get the link's streams. Trying to load a playlist of tracks (not a single playlist link) takes a lot of time (50 tracks ~ 2.5 minutes on a i7)! I know that it must compute the puzzle, but isn't it possible to cash the first computation result somewhere?
@dirkf Should i open a different issue with this?
The results are supposed to be cached. In my original version, I had a local per-item memo so the descramble was only done once. This version is meant to use the player cache as in yt-dlp.
You can see that it does so with -v
because the entry like this [debug] [youtube] Decrypted nsig jCeO6nveAEs8dCNvd => Syl79sOxyyy2rQ
logs when the actual computation is done, and any other URLs with the n value 'jCeO6nveAEs8dCNvd' are just being looked up.
I've only tested it on a scrap laptop (OK, I upgraded the CPU to T7700 2.4GHz) and I didn't see anything unusual. Equally I didn't timeit
this implementation against the VLC regex version.
Would you be able to try your playlist against yt-dlp as well, or reveal the URL anyway?
I use it like a library in an app, so I can't use -v
.
Other than that, I also use a different thread for every track of the playlist, so maybe the cache strategy does not work here?
Any playlist have the same (analogous) delay..
If this has to do with cashing the player, then, I might use the same code strategy I send you the last time there where problems.
I'll try that and post the update here..
UPDATE: I couldn't make the older cashing code to work with the current changes.
Also, checking yt-dlp 2021.12.27
with the same links in the same app works OK.
The code uses the IV _player_cache
which is a dict
. I would be happy to consider some patch for a potentially thread-safe global cache. But this SO implies that dict
operations are atomic. As the cache usage is either to read a value by key or to insert a value for a key that is always the same, it appears that a module-level cache could work effectively without any locking.
S/t like this:
...
_PLAYER_CACHE = {}
...
class YoutubeIE(YoutubeBaseInfoExtractor):
...
def __init__(self, *args, **kwargs):
super(YoutubeIE, self).__init__(*args, **kwargs)
self._code_cache = {}
self._player_cache = _PLAYER_CACHE
...
Here I'm assuming you have a different YoutubeIE
instance in each thread, but that the module-level variable is shared across threads.
That was a nice idea, but unfortunately it produces an error:
ERROR: Signature extraction failed: Traceback (most recent call last):
File "...\PYTHON\Python27\lib\site-packages\youtube_dl\extractor\youtube.py", line 1445, in _decrypt_signature
return func(s)
File "...\PYTHON\Python27\lib\site-packages\youtube_dl\extractor\youtube.py", line 1427, in <lambda>
return lambda s: initial_function([s])
File "...\PYTHON\Python27\lib\site-packages\youtube_dl\jsinterp.py", line 554, in resf
ret, should_abort = self.interpret_statement(stmt, var_stack)
File "...\PYTHON\Python27\lib\site-packages\youtube_dl\jsinterp.py", line 157, in interpret_statement
v = self.interpret_expression(expr, local_vars, allow_recursion)
File "...\PYTHON\Python27\lib\site-packages\youtube_dl\jsinterp.py", line 470, in interpret_expression
return eval_method()
File "...\PYTHON\Python27\lib\site-packages\youtube_dl\jsinterp.py", line 463, in eval_method
return obj[member](argvals)
File "...\PYTHON\Python27\lib\site-packages\youtube_dl\jsinterp.py", line 554, in resf
ret, should_abort = self.interpret_statement(stmt, var_stack)
File "...\PYTHON\Python27\lib\site-packages\youtube_dl\jsinterp.py", line 157, in interpret_statement
v = self.interpret_expression(expr, local_vars, allow_recursion)
File "...\PYTHON\Python27\lib\site-packages\youtube_dl\jsinterp.py", line 470, in interpret_expression
return eval_method()
File "...\PYTHON\Python27\lib\site-packages\youtube_dl\jsinterp.py", line 418, in eval_method
assertion(isinstance(obj, list), 'must be applied on a list')
File "...\PYTHON\Python27\lib\site-packages\youtube_dl\jsinterp.py", line 370, in assertion
raise ExtractorError('{0} {1}: {2}'.format(nl.member, msg, expr))
This says fixed but I am getting 526 B/s downloads - slower than if I watched the video! Realplayer download works at 10 MiS but not what I want. I tried with both youtube-dl and yt-dlp both running that slow.
I tried with both youtube-dl and yt-dlp both running that slow.
The master version in the yt-dl repo is fixed. The fix is not in a released version yet.
yt-dlp release 2022.02.04 should run unthrottled.
That was a nice idea, but unfortunately it produces an error:
If you can make a small program that reproduces the problem, we might be able to make progress.
If you can make a small program that reproduces the problem, we might be able to make progress.
Unfortunately, I use QThreads
in a complicated manner in my app, but I will try to make something minimal with the native Treads
, for a simple scripts.
Any already existing, simple threading example, will be greatly appreciated..
P.S. The updated extractor has the same results.. :cry:
Sorry for the delay, but I was busy yesterday.. Here is some example code:
# coding=utf-8
from __future__ import absolute_import, division, print_function, unicode_literals
from queue import Queue
from threading import Thread, Event
import youtube_dl
# import yt_dlp as youtube_dl
ydl_opts = {'quiet': True, 'no_warnings': True}
link_ids = ["4jduuQh-Uho", "9GNpv7QDvMY", "MbEOR2Flc-4", "ZKUzNF21n9w", "y-JqH1M4Ya8",
"c5pi-SOlXQc", "pUqfaiUb3l4", "bL5eqSOXMtE", "HyMm4rJemtI", "BU4kGkrrJEw",
"pFS4zYWxzNA", "aF6hDcAbSoE", "G1ckKDRc69w", "o9_jzBtdMZ4", "AGoQZx8Mn0g",
"6W-pHCD6Tow", "kszLwBaC4Sw", "mwTd_PzGY-c", "iqLTYD_nhsU", "X335gdcPE7A",
"z_54vDk8lWw", "8a82arE0JSQ", "tJmzQHWl9kc", "8jPQjjsBbIc", "ENJUB5thpB4",
"dEhUMvjFuQY", "D6XyJh1tsGI", "tFCfb-Qqdz0", "UkafA6r1caQ", "OO8HtAXnRqQ",
"--da0m2K4I4", "EOlI0UtLDk4", "r7tQbxTImKw", "s_YLPcW4Tu8", "9wIbhES2UkA",
"YkX9X4td7j8", "14cHz4ebonY", "saVUUZE50Co", "N1K4NYHqMx4", "iCBL33NKvPA",
"QPTNS3llm2E", "pFS4zYWxzNA", "wA1v207xlOw"]
infos = []
class Base(object):
def __init__(self, **kwargs):
super(Base, self).__init__(**kwargs)
self.feed_q = Queue()
self.threads = []
for i in range(8):
thread = Worker(self.feed_q)
thread.daemon = True
self.threads.append(thread)
thread.start()
class Node(object):
pass
class Worker(Thread):
def __init__(self, feed_q):
super(Worker, self).__init__()
self.node = None
self.feed_q = feed_q
self.stop = False
def run(self):
while not self.stop:
self.node = self.feed_q.get()
url = "https://www.youtube.com/watch?v=" + self.node.id
with youtube_dl.YoutubeDL(ydl_opts) as ydl:
try:
ydl_info = ydl.extract_info(url, download=False)
except Exception as e:
error_text = "A {0} occurred for {2}. Arguments:\n{1!r}"
print(error_text.format(type(e).__name__, e.args, url))
self.feed_q.task_done()
continue
infos.append(ydl_info)
print("Got info from {}".format(url))
self.node.updated.set()
while True:
if self.node.updated.wait(timeout=2):
break
self.feed_q.task_done()
if __name__ == "__main__":
base = Base()
print("Getting info for {} YouTube videos".format(len(link_ids)))
for tube_id in link_ids:
node = Node()
node.id = tube_id
node.updated = Event()
base.feed_q.put(node)
from timeit import default_timer as timer
start = timer()
base.feed_q.join()
print("Finished in {} seconds".format(round(timer() - start)))
youtube_dl
takes 96 sec while yt-dlp
takes only 20 sec.
Before the last breakage, youtube_dl
was faster than yt-dlp
.
There is also more processing with youtube_dl
..
The links are random, you can use whatever links you like..
FYI: Followed advice regarding pulling from 'master'.....
For those wishing to build, here's what I did ( for better or worse & whether correct or not... ): NOTE: I previously build, so met dependencies referenced in the readme.md
/git/youtube-dl$ make mkdir -p zip for d in youtube_dl youtube_dl/downloader youtube_dl/extractor youtube_dl/postprocessor ; do \ mkdir -p zip/$d ;\ cp -pPR $d/.py zip/$d/ ;\ done touch -t 200001010101 zip/youtube_dl/.py zip/youtube_dl//.py mv zip/youtube_dl/main.py zip/ cd zip ; zip -q ../youtube-dl youtube_dl/.py youtube_dl//*.py main.py rm -rf zip echo '#!/usr/bin/env python' > youtube-dl cat youtube-dl.zip >> youtube-dl rm youtube-dl.zip chmod a+x youtube-dl COLUMNS=80 /usr/bin/env python youtube_dl/main.py --help | /usr/bin/env python devscripts/make_readme.py /usr/bin/env python devscripts/make_contributing.py README.md CONTRIBUTING.md pandoc -f markdown -t plain README.md -o README.txt /usr/bin/env python devscripts/prepare_manpage.py youtube-dl.1.temp.md pandoc -s -f markdown -t man youtube-dl.1.temp.md -o youtube-dl.1 rm -f youtube-dl.1.temp.md /usr/bin/env python devscripts/bash-completion.py /usr/bin/env python devscripts/zsh-completion.py /usr/bin/env python devscripts/fish-completion.py /usr/bin/env python devscripts/make_supportedsites.py docs/supportedsites.md
-rwxrwxr-x 1 god god 1849986 Feb 9 01:00 youtube-dl
[download] 100% of 51.86MiB in 00:04
Yeah very fast download speed !!
If anyone has a Python installation with a recent pip (pip3), you can install the latest master branch (or any other commit level) directly from GitHub or a downloaded tar.gz.
Tested the current latest master with the example above, and the time got improved from 96 to 76 secs. But unfortunately still way over the 20 sec of yt-dlp or the even faster previous yt-dl.. :disappointed:
As a temporary fix you can use Aria2c external downloader to get split file downloading and/or batch file downloading, effectively removing throttle issues.
@dirkf Should I open a different issue with the code for the multi-threading problem? Opened #30641
CONFIRMING FIX ON MASTER: had throttling issue on 2022.12.17... pulled master > make = resolved
[download] 43.0% of 274.52MiB at 15.43MiB/s ETA 00:10
i"m on windows, i don't understant your "fix". can you explain please :)
What I did was to replace my local youtube_dl/extractor/youtube.py
with this one...
The fix committed to the repo requires more than one file to be updated.
@TagAcheron, https://github.com/ytdl-org/youtube-dl/issues/30583#issuecomment-1027312830, or install Python and https://github.com/ytdl-org/youtube-dl/issues/30583#issuecomment-1033668493.
@dirkf Yes, I already had that update. I was referring to the last change ~11-12 days ago..
CONFIRMING FIX ON MASTER: had throttling issue on 2022.12.17... pulled master > make = resolved
[download] 43.0% of 274.52MiB at 15.43MiB/s ETA 00:10
Building and replacing the binaries, worked for me too
Using youtube-dl v. 2021.12.17
on macOS 12.4 exhibits the same problem. The speed has been around 50-60 kbps for each download from a playlist on YouTube. After reading some suggestions, I installed and tried yt-dlp v. 2022.05.18
and the speed instantly shot up to about 10 mbps. If a fork of youtube-dl
can solve this old issue, then I'm sure you can too.
FYI brew with macOS uses version 2021.12.17 as stable. So if anyone runs into this issue just switch to yt-dlp.
Neither did you.
Checklist
Verbose log
Description
I can't understand why my youtube download is so slow, can someone explain me what i'am missing here because my internet is like 45 Mbps