如何像 KeepVid (2017) 一样获取 YouTube 视频下载地址?

Jay*_*Jay 5 javascript youtube video download

我正在编写一个 youtube 视频下载器。让我们以这个视频为例:

https://www.youtube.com/watch?v=_UbDeqPdUek

在研究如何获取 YouTube 视频的 url 时,我在 stackoverflow 上发现了一段代码:

(function() {
    return ytplayer.config.args.adaptive_fmts
        .split(',')
        .map(item => item
            .split('&')
            .reduce((prev, curr) => (curr = curr.split('='),
                Object.assign(prev, { [curr[0]]: decodeURIComponent(curr[1]) })
            ), {})
        )
        .reduce((prev, curr) => Object.assign(prev, {
            [curr.quality_label || curr.type]: curr
        }), {});
})();
Run Code Online (Sandbox Code Playgroud)

在上面的 youtube url 上的 chrome dev 控制台中执行此操作,您将看到它会喷出一个包含信息的对象,包括视频 url。

'720p' 属性中的 'url' 属性如下:

https://r2---sn-5hne6nlk.googlevideo.com/videoplayback?mn=sn-5hne6nlk&ip=92.111.133.132&mm=31&sparams=clen%2Cdur%2Cei%2Cgir%2Cid%2Cinitcwndbps%2Cip%2Cipbits%2Citag%2Ckeepalive%2Clmt%2Cmime%2Cmm%2Cmn%2Cms%2Cmv%2Cpl%2Crequiressl%2Csource%2Cexpire&itag=247&mime=video%2Fwebm&dur=250.800&id=o-AEgCrHyMCCJXgH39WmxsSwNs01bFa3BDVFEIzgAyrthL&mv=m&pl=18&mt=1500667926&requiressl=yes&ms=au&expire=1500689653&initcwndbps=1997500&keepalive=yes&key=yt6&ei=lWByWcWwI4Th1gKa2aDoCg&signature=596BF2603202A1BC60493C8263928FB365A14B2A.92D082149A543786BA5C29A547A8F78DE9346F95&source=youtube&clen=47937010&gir=yes&ipbits=0&lmt=1449652247373936
Run Code Online (Sandbox Code Playgroud)

当我将此 url 粘贴到 chrome 选项卡时,它开始在准系统窗口中播放视频。您可以使用此链接下载视频。问题是,视频没有声音!

当我使用keepvid下载视频时,它会在 720p 下载按钮上显示以下网址:

https://r17---sn-o097znll.googlevideo.com/videoplayback?lmt=1470986968011625&mt=1500670510&dur=250.891&itag=22&ipbits=0&ms=au&sparams=dur%2Cei%2Cid%2Cip%2Cipbits%2Citag%2Clmt%2Cmime%2Cmm%2Cmn%2Cms%2Cmv%2Cpl%2Cratebypass%2Crequiressl%2Csource%2Cexpire&ei=pWpyWZ75BZyf1gLf6rXQCA&id=o-AMPIR2-sd--NM8eDZyPKMqOu1B5qqSkBd1brw-H44ARx&pl=24&mn=sn-o097znll&mm=31&source=youtube&signature=6F5B6D2EFCF5CD600D9B12C984A19DBA58AC6A7E.CC2EE5E63809D4C9A07BB2C194328C7825015976&ratebypass=yes&mv=m&mime=video%2Fmp4&ip=159.253.144.86&requiressl=yes&key=yt6&expire=1500692229&title=Cubs+Meet+Adult+Tiger+For+The+First+Time+-+Tigers+About+The+House+-+BBC
Run Code Online (Sandbox Code Playgroud)

两个 url(和查询参数)之间的差异很小。但事实是,keepvid 的网址比我的好:

  1. 它将文件作为下载文件展开,而不是在浏览器中播放。
  2. 它有声音。

为方便起见,这里是这些 url 的 url 解码、格式化版本,参数按字母顺序排列。

我从上面的 js 片段中得到的 url,声音不起作用:

https://r2---sn-5hne6nlk.googlevideo.com/videoplayback
clen=47937010
dur=250.800
ei=lWByWcWwI4Th1gKa2aDoCg
expire=1500689653
gir=yes
id=o-AEgCrHyMCCJXgH39WmxsSwNs01bFa3BDVFEIzgAyrthL
initcwndbps=1997500
ip=92.111.133.132
ipbits=0
itag=247
keepalive=yes
key=yt6
lmt=1449652247373936
mime=video/webm
mm=31
mn=sn-5hne6nlk
ms=au
mt=1500667926
mv=m
pl=18
requiressl=yes
signature=596BF2603202A1BC60493C8263928FB365A14B2A.92D082149A543786BA5C29A547A8F78DE9346F95
source=youtube
sparams=clen,dur,ei,gir,id,initcwndbps,ip,ipbits,itag,keepalive,lmt,mime,mm,mn,ms,mv,pl,requiressl,source,expire
Run Code Online (Sandbox Code Playgroud)

我从 keepvid 得到的 url,声音正常:

https://r17---sn-o097znll.googlevideo.com/videoplayback
dur=250.891
ei=pWpyWZ75BZyf1gLf6rXQCA
expire=1500692229
id=o-AMPIR2-sd--NM8eDZyPKMqOu1B5qqSkBd1brw-H44ARx
ip=159.253.144.86
ipbits=0
itag=22
key=yt6
lmt=1470986968011625
mime=video/mp4
mm=31
mn=sn-o097znll
ms=au
mt=1500670510
mv=m
pl=24
ratebypass=yes
requiressl=yes
signature=6F5B6D2EFCF5CD600D9B12C984A19DBA58AC6A7E.CC2EE5E63809D4C9A07BB2C194328C7825015976
source=youtube
sparams=dur,ei,id,ip,ipbits,itag,lmt,mime,mm,mn,ms,mv,pl,ratebypass,requiressl,source,expire
title=Cubs Meet Adult Tiger For The First Time - Tigers About The House - BBC
Run Code Online (Sandbox Code Playgroud)

如您所见,网址/参数非常相似。但是,当我的 js 片段在没有音频的情况下对我产生影响时,keepvid 如何设法生成一个文件 url 有声音工作?

网址有一个签名作为参数。这可能是(某些)查询参数本身的签名。更改参数中的一些小内容(删除它或更改其值),会导致 url 访问被拒绝。这使得很难对其进行实验。

js 代码段只是访问一个在线变量并从中挖掘视频信息。但是缺少什么导致其网址指向无声视频的片段?

任何人都可以帮助我以编程方式获取 url 就像 keepvid 一样,这将导致下载的文件带有工作音频?

[更新]

我刚刚了解到您可以像这样获取视频信息:

http://youtube.com/get_video_info?video_id=_UbDeqPdUek
Run Code Online (Sandbox Code Playgroud)

它产生了一个包含大量信息的大文件,我还没有弄清楚如何解析。

我必须走在正确的道路上,因为这就是youtube-dl的做法。该程序运行完美。

我想我可以简单地对 youtube-dl 进行逆向工程(花费时间)。或者甚至使用 Process 从我的 C# 程序调用它(让我依赖它)。

但这仍然给我留下了一个问题,如果没有可用的帮助,一个人将如何自己解决这个问题?