【2019】优酷视频地址 分析(一)

点击 这里 查看在线 demo

抓包

随机打开一个视频,抓包
搜索 mp4,发现这个 m3u8 文件请求,所有的视频片段都在这里面
【2019】优酷视频地址 分析(一)_第1张图片
继续搜索 m3u8 文件的地址,可以发现是从这个 API 里出来的
【2019】优酷视频地址 分析(一)_第2张图片
地址是 https://acs.youku.com/h5/mtop.youku.play.ups.appinfo.get/1.1/
看一下参数:
【2019】优酷视频地址 分析(一)_第3张图片
还是挺多的…
经过筛选之后,其实只需要这些参数
【2019】优酷视频地址 分析(一)_第4张图片
其中 appkeyapi 固定,t 应该与时间有关(时间戳)
data 整理后得到:

{
	"steal_params": "{\"ccode\":\"0502\",\"client_ip\":\"192.168.1.1\",\"utid\":\"NBevFStAZEQCAW40jnu9IcNS\",\"client_ts\":1566290208,\"version\":\"1.8.1\",\"ckey\":\"119#MlKT3NBFM8PGzMMzlyfMRuVLT7EBEbACc6MtYBAsqUnTFatOwvVDvYyAjcplNL8GLeASRBsU3AALuwHNk9SKOrA8RJBONt8L9ei25SSUdGIy/Upp4SMn6rA2RW1zNNFGfeAzR/QYdUeIx4LL7G12qCnxSCqOfoDjsvmw6EOMAOl7Y/h6SYVHIxImmtyIKrTJDojBBgjZTamxD7tViyQxxP+C3W/fByo7iM3PGDP3dzMNrb0Y96bE7k8oJV6e6IaFwcLCuRUspdmc4zcGhpzU4m/8TqqD0cuYnEwbg+pQHpkBd9ALU3j6uFCi9h6jIaRrpTSV7kwAur6WcTODqT1B4d6/MJ9eFwkMZrVn5MabjVXDbKcnmaGmL9aj/4k1yfWkCY0YNhREFvU7N/slngR/mgjDBGPBvvm5CR4PHRrTE4c7DCfnW/xEW31J19xRLyc2P48mIQM2LQxfw2cBJhCDrxZXJBEWyA3XplF7/8a9D5z0BU0THL6GE4ec/ru6n9yNWaSMq5mY/uJNNf9wh3GymAu4hJTGV35dOFSIhSrYsMa3r/Icy4BmbcxCzxIw9f4xqeQxFBo8d8501Zl2vKkrOO2WMrom3RkH1OBfOLUwjPSJqOZ1Y7HFSE0RkD+FHtNhZdE1bTjG3FW56JBXao90g1tWjedX+Q14g9QTbhVSrzkXBbMUIC==\"}",
	"biz_params": "{\"vid\":\"XNDMxNzkyNjY2OA==\",\"play_ability\":5376,\"master_m3u8\":1,\"media_type\":\"standard,subtitle\",\"app_ver\":\"1.8.1\"}",
	"ad_params": "{\"vs\":\"1.0\",\"pver\":\"1.8.1\",\"sver\":\"2.0\",\"site\":1,\"aw\":\"w\",\"fu\":0,\"d\":\"0\",\"bt\":\"pc\",\"os\":\"win\",\"osv\":\"7\",\"dq\":\"auto\",\"atm\":\"\",\"partnerid\":\"null\",\"wintype\":\"interior\",\"isvert\":0,\"vip\":0,\"emb\":\"AjEwNzk3MDM3NzMCdi55b3VrdS5jb20CL3Zfc2hvdy9pZF9YTkRNeE9EZ3hOVEE1TWc9PS5odG1s\",\"p\":1,\"rst\":\"mp4\",\"needbf\":2}"
}

其中有视频的 ID XNDMxNzkyNjY2OA==,说明真实参数应该放这里面


配置 Fiddler

为了方便,这里使用 fiddler 替换 youku-player.min.js 为修改后的 js
保存 youku-player.min.js 到本地,在最上方加上一条提示:
【2019】优酷视频地址 分析(一)_第5张图片
在 fiddler 中设置好,具体可以参考百度
【2019】优酷视频地址 分析(一)_第6张图片
刷新,修改成功!
【2019】优酷视频地址 分析(一)_第7张图片


sign

那么就剩下 sign
经过一段时间的搜索,在 youku-player.min.js 中发现 sign 的位置
【2019】优酷视频地址 分析(一)_第8张图片
其中:

sign = u = s(i.token + "&" + l + "&" + o + "&" + n.data);

s() 函数暂时不管,先搞清楚参数

l 就是时间戳
l
o 就是 appkey
o

输出 appkey
与请求中的 appkey 是一样的
appkey

输出n.data,看看是什么
【2019】优酷视频地址 分析(一)_第9张图片
可见 n.data 就是请求里的 data
【2019】优酷视频地址 分析(一)_第10张图片
用同样的方法,输出 i.token
【2019】优酷视频地址 分析(一)_第11张图片
最后在 Cookie 中搜索到了 token 的内容
【2019】优酷视频地址 分析(一)_第12张图片

那这个 Cookie 又是哪来的?
搜索发现,不带 Cookie 调用此 API 就会返回 Cookie
Cookie


s()

参数都知道了,再看看 s() 函数
输出一下返回的内容
【2019】优酷视频地址 分析(一)_第13张图片
经过比较 sign 参数的确是这个

那么,s() 函数在哪??
在整个 js 中搜索太费时间,这里换一种方法
不传参数直接调用:
【2019】优酷视频地址 分析(一)_第14张图片
不传参数必然会抛异常,此时再去控制台看看
果然有了!
s() 行号
转到 s() 函数
【2019】优酷视频地址 分析(一)_第15张图片
【2019】优酷视频地址 分析(一)_第16张图片
…(╯°Д°)╯

后来突然想到 sign 会不会就是 md5
结果发现还真的是 md5
【2019】优酷视频地址 分析(一)_第17张图片


所以,sign 的算法是:

const appkey = 24679788;
var token = 在_Cookie_m_h5_tk_中获取();

var sign = md5(token + "&" + 时间戳 + "&" + appkey + "&" + 参数json);

写段 PHP 来测试一下

<meta charset="utf-8" />


$url = "http://acs.youku.com/h5/mtop.youku.play.ups.appinfo.get/1.1/?";
$appkey = "24679788";
$token = "5244eaea528c0c41bfdcea84251eb1ab"; //不要直接用这个 token,你看到的时候已经过期了
$time = time();
$data = file_get_contents("data");

//拼接参数
$params = array(
	"appKey" => $appkey,
	"t" => $time,
	"sign" => md5($token."&".$time."&".$appkey."&".$data),
	"api" => "mtop.youku.play.ups.appinfo.get",
	"data" => $data
);

echo "
data_sign=".$token."&".$time."&".$appkey."&".$data."
"
; echo "
sign=".$params["sign"]."
"
; $url = $url.http_build_query($params); $ch = curl_init($url); curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); //返回内容储存到变量中 $data = curl_exec($ch); echo "
".$data."
"
; ?>

这是 data 文件里的内容

{
	"steal_params": "{\"ccode\":\"0502\",\"client_ip\":\"192.168.1.1\",\"utid\":\"NBevFStAZEQCAW40jnu9IcNS\",\"client_ts\":1566290208,\"version\":\"1.8.1\",\"ckey\":\"119#MlKT3NBFM8PGzMMzlyfMRuVLT7EBEbACc6MtYBAsqUnTFatOwvVDvYyAjcplNL8GLeASRBsU3AALuwHNk9SKOrA8RJBONt8L9ei25SSUdGIy/Upp4SMn6rA2RW1zNNFGfeAzR/QYdUeIx4LL7G12qCnxSCqOfoDjsvmw6EOMAOl7Y/h6SYVHIxImmtyIKrTJDojBBgjZTamxD7tViyQxxP+C3W/fByo7iM3PGDP3dzMNrb0Y96bE7k8oJV6e6IaFwcLCuRUspdmc4zcGhpzU4m/8TqqD0cuYnEwbg+pQHpkBd9ALU3j6uFCi9h6jIaRrpTSV7kwAur6WcTODqT1B4d6/MJ9eFwkMZrVn5MabjVXDbKcnmaGmL9aj/4k1yfWkCY0YNhREFvU7N/slngR/mgjDBGPBvvm5CR4PHRrTE4c7DCfnW/xEW31J19xRLyc2P48mIQM2LQxfw2cBJhCDrxZXJBEWyA3XplF7/8a9D5z0BU0THL6GE4ec/ru6n9yNWaSMq5mY/uJNNf9wh3GymAu4hJTGV35dOFSIhSrYsMa3r/Icy4BmbcxCzxIw9f4xqeQxFBo8d8501Zl2vKkrOO2WMrom3RkH1OBfOLUwjPSJqOZ1Y7HFSE0RkD+FHtNhZdE1bTjG3FW56JBXao90g1tWjedX+Q14g9QTbhVSrzkXBbMUIC==\"}",
	"biz_params": "{\"vid\":\"XNDMxNzkyNjY2OA==\",\"play_ability\":5376,\"master_m3u8\":1,\"media_type\":\"standard,subtitle\",\"app_ver\":\"1.8.1\"}",
	"ad_params": "{\"vs\":\"1.0\",\"pver\":\"1.8.1\",\"sver\":\"2.0\",\"site\":1,\"aw\":\"w\",\"fu\":0,\"d\":\"0\",\"bt\":\"pc\",\"os\":\"win\",\"osv\":\"7\",\"dq\":\"auto\",\"atm\":\"\",\"partnerid\":\"null\",\"wintype\":\"interior\",\"isvert\":0,\"vip\":0,\"emb\":\"AjEwNzk3MDM3NzMCdi55b3VrdS5jb20CL3Zfc2hvdy9pZF9YTkRNeE9EZ3hOVEE1TWc9PS5odG1s\",\"p\":1,\"rst\":\"mp4\",\"needbf\":2}"
}

结果“令牌为空”?

{"api":"mtop.youku.play.ups.appinfo.get","data":{},"ret":["FAIL_SYS_TOKEN_EMPTY::令牌为空"],"v":"1.1"}

把 Cookie 也带上

//经过测试,只需要这两个 Cookie
//不要直接用这个 cookie,原因同上
$cookie = "_m_h5_tk=5244eaea528c0c41bfdcea84251eb1ab_1566446442446; _m_h5_tk_enc=789e5077a464542c59b8825eaaa7823e; Domain=youku.com";

//......

curl_setopt($ch, CURLOPT_COOKIE, $cookie);

刷新,换了个错误:“客户端无权播放”

{"ret":["SUCCESS::调用成功"],"data":{"cost":0.009000000543892384,"data":{"error":{"note":"客户端无权播放,201","code":-6004}},"e":{"code":0,"provider":"hsfprovider","desc":""}},"v":"1.1","api":"mtop.youku.play.ups.appinfo.get"}

再带上 UA

curl_setopt($ch, CURLOPT_USERAGENT, "Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.96 Safari/537.36"); //设置 UA

结果还是不行??

{"ret":["SUCCESS::调用成功"],"data":{"cost":0.009000000543892384,"data":{"error":{"note":"客户端无权播放,201","code":-6004}},"e":{"code":0,"provider":"hsfprovider","desc":""}},"v":"1.1","api":"mtop.youku.play.ups.appinfo.get"}

Referer 也带上

curl_setopt($ch, CURLOPT_REFERER, "https://v.youku.com/v_show/id_XNDMxODgxNTA5Mg==.html");  

这次调用成功,返回的 json 很长
【2019】优酷视频地址 分析(一)_第18张图片
说明 data 里只需要改 vid 参数就可以


返回结果分析

其中 data.data.preview.thumb_hd[0] 貌似是视频各个时间点的截图
【2019】优酷视频地址 分析(一)_第19张图片
图片内容:

data.data.ad 下是广告地址
【2019】优酷视频地址 分析(一)_第20张图片
data.data.video 下是视频信息
【2019】优酷视频地址 分析(一)_第21张图片
data.data.stream[n] 下面就是各个清晰度的视频地址
【2019】优酷视频地址 分析(一)_第22张图片
其中 mp4hd3v2 就是 1080P 的地址
【2019】优酷视频地址 分析(一)_第23张图片


错误信息

一些错误信息的解决方法

信息 解决方法/原因
账号异常,请重新登录 大概是请求频率太快,尝试清除/更换 Cookie,稍后重试
令牌为空/过期 你的 Cookie 没传/过期了
非法请求 某个参数错了(比如 sign 算错了)
http响应缺少参数api data 里缺少了某个参数

完整代码(PHP)

点这里

你可能感兴趣的:(前端,php,前端,优酷,js,php,优酷视频)