先参照这篇博客写sign,https://www.cnblogs.com/boothsun/p/7460105.html了解一下sign
然后开始youtube视频真实地址分析,之所以用youtube做分析,是因为youtube并没有做视频切片,新建网站服务端不需要做很多工作,基本上都可以丢给浏览器客户端用js做(使用客户端做的话就另说了,这里主要是说网页做的思路)
youtube的下载链接如下:
https://r5---sn-i3b7knlk.googlevideo.com/videoplayback?expire=1583084985&ei=WaFbXte7JeyE1d8PjO6d-A8&ip=112.120.125.249&id=o-APv2GZAKtidWtOg-EFLLI3FCRJEX4Pm9Lrq36teusL17&itag=251&source=**&requiressl=yes&mm=31,26&mn=sn-i3b7knlk,sn-npoeene6&ms=au,onr&mv=m&mvi=4&pl=19&initcwndbps=1313750&vprv=1&mime=audio/webm&gir=yes&clen=10471622&dur=811.281&lmt=1582982306022140&mt=1583063322&fvip=5&keepalive=yes&fexp=23842630,23882513&c=web&txp=6411222&sparams=expire,ei,ip,id,itag,source,requiressl,vprv,mime,gir,clen,dur,lmt&sig=ADKhkGMwRQIhAJL3b_OpRnLdUVNkTsVqfElLcsF0QunrlLFhSrHljixiAiAfs8bruj11w_XaI_b7DXfqB5mzFrI09ck-Jb2l2S2LZA==&lsparams=mm,mn,ms,mv,mvi,pl,initcwndbps&lsig=ABSNjpQwRAIgMFcOcinalm6VxZBvWcAc-XLzCuCJEybydBY9Nvkig8sCIFjoxjIFMN6vNIxNuNLEY47GL8oMfu_MBIwnJJ45JpSn&alr=yes&cpn=EWtuRS6qSNVh1cH9&cver=html5&range=128635-262609&rn=6&rbuf=9524
youtube的链接比较有意思,F12 直接在页面js中可以分析的到,但是不一定能直接使用,我这里用的是一个比较取巧的办法,直接在我自己的网页创建隐藏的video标签然后动态引入youtube的js创建youtube使用到的对象,例如:yt.player.Application.create("player-api", ytplayer.config);
然后创建的对象中有streamingData.adaptiveFormats,这里面就有各种分辨率对应的实际播放地址了。可以看到其实adaptiveFormats这个数组里面很多分辨率,每个分辨率详细信息都有,这个其实也分了两类型,
1:有现成的url,其中是带了sign的,这个sign是有效的,可以直接使用。忽略
2,是这里主要要说的,其中没有呢url,只有cipher里面带有播放地址:
sp=sig&s=LDADKhkGMwRAIgO2V4zHeTrQij4NgtmxDJprA8i8ob-ec6T0OyomcQA7kCIB4tqWJZT_Kam_ACns7ewOeYpFbnljhsi1t2Stu0tb-a&url=https://r4---sn-t0a7sn7d.googlevideo.com/videoplayback?expire=1583086010&ei=WqVbXrCgAp-g4gGl97qoAw&ip=144.208.100.216&id=o-AN9N59pTxxxMvqooPmx30b9gn7N19gCRXrLIaPTZLM-j&itag=136&aitags=133,134,135,136,160,242,243,244,247,278,394,395,396,397,398&source=**&requiressl=yes&mm=31,26&mn=sn-t0a7sn7d,sn-vgqskned&ms=au,onr&mv=u&mvi=3&pl=22&vprv=1&mime=video/mp4&gir=yes&clen=24447277&dur=275.040&lmt=1575159615261812&mt=1583063918&fvip=4&keepalive=yes&fexp=23842630&c=WEB&txp=5535432&sparams=expire,ei,ip,id,aitags,source,requiressl,vprv,mime,gir,clen,dur,lmt&lsparams=mm,mn,ms,mv,mvi,pl&lsig=ABSNjpQwRAIgAOsUy0hgqIwEOMQ0zOW07Yx3Wf8ApVou3-YyJ_ZLD_wCIBBVODttEGNK707ikKBlXygvZt9_udXAiR3NlH6FteGW
这个地址是无法直接播放下载的,就是今天说的主角sign的问题了。youtube请求实际播放的时候会把这个sign重新计算,这里面带的就与服务器上计算后的对不上号了。
怎么办?能怎么办,当然就是需要我们去分析怎么计算他的这个sign,然后替换了。关键是在两个cipher里面的参数s=LDADKhkGMwRAIgO2V4zHeTrQij4NgtmxDJprA8i8ob-ec6T0OyomcQA7kCIB4tqWJZT_Kam_ACns7ewOeYpFbnljhsi1t2Stu0tb-a
其实上一步引入youtube的js的时候我们就在创建对象了,这里我也没找到好办法从他压缩后的js中分析他计算的js,全凭感觉和调试,并且后面你会发现,它引入的js 计算sign(也可以叫加密或者解密吧)的函数并不会对外公开,所以在我们网页js中其实是无法直接使用的。这个不是我们讨论的重点,今天的重点其实是如何计算他的sign达到我们获取可以观看下载的视频地址。
我们去youtube自带的js中找到一个base.js的文件。这个就是我们之前引入的js,一步一步的调试(实在没找到好一点的分析方式,大佬们如果有好办法可以分享一下),可以找到
var Js = {
cm: function(a, b) {
a.splice(0, b)
},
vB: function(a) {
a.reverse()
},
L3: function(a, b) {
var c = a[0];
a[0] = a[b % a.length];
a[b % a.length] = c
}
};
这一串,这个就是计算sign的具体函数了,这里就需要用到cipher里面的sig=后面的一串字符了。但是参数和值究竟怎样,就有了下面一段js的发现
Ks = function(a) {
a = a.split("");
Js.L3(a, 54);
Js.vB(a, 21);
Js.L3(a, 68);
Js.vB(a, 80);
Js.cm(a, 2);
return a.join("")
}
注:这个函数里面的具体调用,youtube都是在不停修改的,上面的三个具体实现的函数才是很少变动的
我们只要将s=LDADKhkGMwRAIgO2V4zHeTrQij4NgtmxDJprA8i8ob-ec6T0OyomcQA7kCIB4tqWJZT_Kam_ACns7ewOeYpFbnljhsi1t2Stu0tb-a这个s=后面内容传入 Ks这个函数重新计算就可以得出新的sign的值了
然后取出cipher中的url参数,用计算到的新字符串替换一下(如果没有sig,参照cipher中的p参数加上对应的参数这里就是&sig=),就可以拿到可以观看下载的真实地址了。
至此,分析结束,后面就是用代码实现了。
其实网站去解析youtube下载地址最主要的问题有两个,
1,获取youtube网页内容跨域的问题,解决办法是做个服务端中转,这里会引发另外一个问题,youtube会封ip,于是服务端就加上代理。
2,即使是我从youtube的base.js中分析出了生成sign的函数,但是我们无法直接调用,base.js并未对外开放这个函数,而且youtube会频繁改动这个算法,如何将这个函数也做成自动的呢?我暂时没想出好办法来,只是分析出来,然后复制出来写入到自己js中,希望有大佬提点一下。当然如果是客户端来做这个事,2的问题就不是问题了,大不了每次把js请求回来,当做字符串去分析,用正则找出这一串,生成自己的js文件然后调用。
这里说明一下,调试别人网站的js脚本,经常遇到网站在js中做处理,禁止客户端调试,我的办法其实是对网站的js做重定向处理,自己搭建服务器,拉回网站js代码,删除禁止调试的相关代码,然后配置host,将网站引用的js指向本机修改过的js。
原文地址:https://www.cnblogs.com/dengrenyi/p/12391938.html