使用“youtube-dl”获取 YouTube 视频的 URL 很慢,无需下载视频

bha*_*jja 10 performance downloads networking download-speed youtube-dl

我想使用 youtube-dl 获取 URL,以及-g不下载视频的“模拟”选项。

所以我给出了以下命令:

youtube-dl -g https://www.youtube.com/watch?v=k4JGSAmu4lg
Run Code Online (Sandbox Code Playgroud)

它在 7 到 8 秒后给出了以下输出

https://r20---sn-cvh7zn7d.googlevideo.com/videoplayback?initcwndbps=1113000&mt=1408702970&requiressl=yes&ipbits=0&sver=3&fexp=901454%2C902408%2C919145%2C924626%2C927622%2C927904%2C931330%2C931983%2C934024%2C934030%2C934804%2C945118%2C945308%2C946023%2C951914&ratebypass=yes&signature=38F111D46D72FFC50B47D50B3C9A631099BF5F83.FA134C91F407989B95ACADC1F1F6946B8F18C158&upn=tU0u5t7A2Uw&sparams=id%2Cinitcwndbps%2Cip%2Cipbits%2Citag%2Cmm%2Cms%2Cmv%2Cratebypass%2Crequiressl%2Csource%2Cupn%2Cexpire&mm=31&expire=1408724634&id=o-AJNPuDp9TKMKiwzUwvSk76W7JdA0cx0bRSum9mPJJ7Vo&mv=u&source=youtube&ms=au&key=yt5&ip=115.113.1.50&itag=18
Run Code Online (Sandbox Code Playgroud)

但问题是查询 URL 大约需要 7 到 8 秒。
有什么办法可以让它更快吗?

Vol*_*gel 9

时间花在工作上

命令不会挂起或等待浪费时间的东西,
它实际上是在做需要时间的工作;将多个小的网络延迟相加很可能需要时间。但也可能是 youtube 方面存在延迟,加起来。

它只是下载所需的 HTML 所需的时间;
该命令需要发出至少两个 HTTP 请求,一个接一个,可能更多。

因此,如果任何事情都很慢,它就会乘以已经请求的数量。

对我来说,一条非常快的线路需要 1.5 秒 - 这与 8 秒相差不远。


如何找出

我将展示我用来查找的命令:

为了使示例更加整洁,我们为 URL 使用了一个变量:

$ u="https://www.youtube.com/watch?v=k4JGSAmu4lg"
Run Code Online (Sandbox Code Playgroud)

我们想测量命令的持续时间;使用命令time需要注意不要混淆命令和 shell 内置。我们使用一个小函数来缩短行:

$ t(){/usr/bin/time -f 'Time: %es' "$@";}
Run Code Online (Sandbox Code Playgroud)

您的命令会写出视频文件的 URL(截断为 80 列):

$ youtube-dl -g "$u"
https://r20---sn-cxg7en7d.googlevideo.com/videoplayback?signature=091F68E823
Run Code Online (Sandbox Code Playgroud)

让我们测量在我的计算机上运行所需的时间:

$ t youtube-dl -g "$u"
https://r20---sn-cxg7en7d.googlevideo.com/videoplayback?signature=091F68E823
Time: 1.44s
Run Code Online (Sandbox Code Playgroud)

好的,一秒半。比问题中更快,但没有那么快。但它是如何消磨时间的?也许它确实以某种隐藏的方式下载视频并丢弃它?该视频为 11 分钟 360p。仅在没有选项的情况下下载它需要大约 13 秒 - 十倍。
需要仔细看看,使用详细选项-v

$ t youtube-dl -v -g "$u"
[debug] System config: []
[debug] User config: []
[debug] Command-line args: ['-v', '-g', 'https://www.youtube.com/watch?v=k4J
[debug] Encodings: locale 'UTF-8', fs 'UTF-8', out 'UTF-8', pref: 'UTF-8'
[debug] youtube-dl version 2014.02.06
[debug] Python version 2.7.6 - Linux-3.13.0-24-generic-x86_64-with-Ubuntu-14
[debug] Proxy map: {}
https://r20---sn-cxg7en7d.googlevideo.com/videoplayback?sparams=id%2Cinitcwn
Time: 1.40s
Run Code Online (Sandbox Code Playgroud)

哦,在打印 '[debug]' 行之前有一些延迟。看起来youtube-dl花费了一些时间来进行自己的配置设置。这是四分之一秒左右,而不是我们正在寻找的延迟。但是我们可以从中学到的是,youtube-dl实现本身可能很慢。
在消息之后,在打印结果 URL 之前什么也不会发生。所以我们仍然没有看到有趣的部分。
选项-g是“模拟”视频下载,因为它完成了找出半秘密 URL 的复杂部分,打印它,但最后跳过实际下载。有一个类似的选项-s不输出 URL,否则看起来很相似。如果它花费大约相同的时间,我们假设它足够相似;我们需要检查一下。

$ t youtube-dl -v -s "$u"
[debug] System config: []
[debug] User config: []
[debug] Command-line args: ['-v', '-s', 'https://www.youtube.com/watch?v=k4J
[debug] Encodings: locale 'UTF-8', fs 'UTF-8', out 'UTF-8', pref: 'UTF-8'
[debug] youtube-dl version 2014.02.06
[debug] Python version 2.7.6 - Linux-3.13.0-24-generic-x86_64-with-Ubuntu-14
[debug] Proxy map: {}
[youtube] Setting language
[youtube] k4JGSAmu4lg: Downloading webpage
[youtube] k4JGSAmu4lg: Downloading video info webpage
[youtube] k4JGSAmu4lg: Extracting video information
Time: 1.45s
Run Code Online (Sandbox Code Playgroud)

好的,-s时间和 一样-g,所以可以更换它们进行测试。
更有趣的是,我们现在得到了更多的输出。它以一个有趣的时间打印:这些行以彼此相似的延迟打印,所以看起来它们是关于实际上花费我们寻找时间的动作。
从消息中,至少下载了两个网页。但是我们可以假设“页面”一词并不意味着单个 HTTP 请求和单个 HTML 文档。

我们学到了什么?

重点是,程序的工作确实需要时间,它不是在等待某事,也不是挂起。
此外,我们看到多个步骤花费了相似的时间。没有多少要计算的,所以这在某种程度上是网络往返,加起来。
这意味着,我们的连接延迟仅在这里很重要。连接的吞吐量是无关紧要的。

如果您想让您的互联网连接速度更快,以便它可以以双倍速度传输数据 - 那根本无济于事。但是如果你能得到更好的ping时间,那会让它变得更快。
不过,这与您的互联网服务提供商的“ping”次数无关;一直到 YouTube 的 ping 时间很重要 - 并且可能无法更改。

有趣的是,对于下一步,下载视频,对快速线路的要求恰恰相反:延迟根本不相关,吞吐量确实很重要。


还不累?

想要了解更多细节以了解真正花在什么上的时间?
下一步是跟踪 HTTP 连接;我怀疑它可能会显示比两次更多的往返,例如重定向。您可以使用wireshark, 或日志记录 HTTP 代理,或者strace仅计算连接或写入的系统调用。

今天,我们都对网络的兔子洞进行了足够深入的研究。


小智 6

只需做一个:

youtube-dl -j --flat-playlist 'https://www.youtube.com/watch?v=k4JGSAmu4lg' | jq -r '.id' | sed 's_^_https://youtube.com/v/_'
Run Code Online (Sandbox Code Playgroud)

来源