腾讯视频加载方案

背景

其实这个需求挺蛋疼的。项目里允许让用户插入一个视频,目前国内做的比较好的就是土豆、优酷和腾讯。由于土豆和优酷提供了良好的API,所以第一期的目标就自然而然地是先加载土豆、优酷视频。

视频加载目前来说有三种方案,除去video标签加载,一种是嵌入链接,一种是嵌入flash。由于众所周知的iOS不支持flash原因,所以最后是以iframe的形式把视频嵌入到网页中。由于有SDK接口,所以可以直接把视频网址传到服务器由服务器返回视频信息并加载。

虽然iframe还有很多不为人知的兼容问题,但本来也算是活的好好的。随后就说要兼容https,而优酷土豆竟然不支持。当务之急,就是把在页面内加载视频的方案取消了,改成引导用户去别的页面观看视频。

此时,腾讯视频后来居上,因为它支持https……加上腾讯视频也是有个前端接口,所以新的一期任务就是支持在页面内直接播放腾讯视频。

腾讯视频接口文档

腾讯的接口文档其实是公开的,也没什么好说的,提供了创建Player的接口,传入链接就可以帮你把所有事情搞定,包括兼容性问题,比如会在PC上用iframe加载,而在移动端用video加载;当然你也可以自定义。

对于我们的产品,当然是不能满足如此霸道的不提供信息接口的API的,所以……

挖掘腾讯视频API

腾讯视频的API文档,其实就是加载一个js文件,再根据视频链接读取视频的封面、链接地址等。但代码已经被混淆,无法直接查看。在一阵分析之后,最终还是都被我拿到了,直接提供给后台,不修改原来的请求逻辑就接入了。

接下来也不想分析如何获得,就是总结几个API。

初始信息

假设我们拿到一个小鲜肉的视频链接:https://v.qq.com/x/cover/x1zn2j3vkb9e2os/n0022eraduw.html 。腾讯视频现在大部分的视频已经满足cover或page这两种格式,即使是旧视频,也会跳转为这些格式,不像优酷土豆,老视频还是老视频的格式。

以上的格式可以视为cover/cid/vids,page/vids,其中cid为这个视频的cover id,vids为视频的video id。cover id指的是这个视频所在的合辑。有些视频是没有cover id的。

所以小鲜肉的视频cid为x1zn2j3vkb9e2os,vids为n0022eraduw。

获取缩略图

1
2
3
4
5
6
7
8
9
10
getVideoSnap = function(a) {
var c, d, e = 1e8;
for (var g = 4294967296, h = 0, i = 0; i < a.length; i++) {
var j = a.charCodeAt(i);
h = 32 * h + h + j,
h >= g && (h %= g)
}
d = h % e;
return c = "http://vpic.video.qq.com/"+d+"/"+a+"_160_90_3.jpg";
}

getVideoSpan传入视频的vids,即可获得视频的封面图,当然要经过一阵计算。目前的缩略图有三种后缀,分别为

1
2
3
http://vpic.video.qq.com/d/a_160_90_3.jpg
http://vpic.video.qq.com/d/a_1.jpg
http://vpic.video.qq.com/d/a.png

分别代表“封面图小图”、“第二张图”、“封面图大图”。一般就是取小图或大图,中间的图可以不管。

由上面vids=n0022eraduw可以得到缩略图链接为

1
http://vpic.video.qq.com/46838682/n0022eraduw.png

其他后缀可以自己主动修改。

获取信息

除了缩略图,可能还需要视频描述等。抱着凡是能看到的信息必定也可以抓取到的原则,拿到了获取信息的接口。

1
http://h5vv.video.qq.com/getinfo?otype=json&cid=COVERID&vids=VIDEOID

代入得到:

1
2
3
...
"ti":"王俊凯北电艺考“万人追捕” 比大甩卖血拼的场景都火爆"
...

由于信息有点多,这里就不一一展示了,里面很多信息都是不知其意的,不过一眼就能看到这些中文字……一下子就拿到视频描述了。

获取视频mp4链接

不管你信不信,我是拿到了。原因很简单,腾讯视频有个bug(后面会说到),导致我一度想拿它的视频链接,自己来嵌入video,当然最后链接也拿到了,bug最后用另一种方案解决了。

现在来看看video的url格式:

1
http://183.214.128.91/vlive.qqvideo.tc.qq.com/n0022eraduw.m1.mp4?vkey=FAC3E342447ADE8EF171DF625B52B6B1C3986EF6B37A3E5ED73F0519758E3F3A22987A7B5ABBDFC4E967DB8B34494B00DAA3B8C3E4890836AC6DC967ACA9858A470B2811B69353D1A05E3415B847600DCF35D2ADB2DF33FE

其实就是

1
IP/vlive.qqvideo.tc.qq.com/VIDEOID.m1.mp4?vkey=FVKEY

这里面的ip(包含整个前缀)、VIDEOID和FVKEY都是可以从刚才的getinfo接口获取,我们把它套进去,发现视频显示不出来……

好了,其实我也不知道怎么回事,但我后来知道怎么解决了。就是在getinfo的时候加多一个参数 platform=11001,即可,得到的fvkey就是可用于mp4的。

1
http://h5vv.video.qq.com/getinfo?otype=json&cid=COVERID&vids=VIDEOID&platform=11001

我猜测因为腾讯的API其实只是针对移动端做了video的mp4嵌入,除非显示设定,在PC并不会直接显示mp4。所以这个platform大概就是用来识别平台的。如果想从混淆的代码入手,可能难度有点大。

好了,拿到了mp4链接:

1
http://183.214.128.91/vlive.qqvideo.tc.qq.com/n0022eraduw.m1.mp4?vkey=FAC3E342447ADE8EF171DF625B52B6B1C3986EF6B37A3E5ED73F0519758E3F3A22987A7B5ABBDFC4E967DB8B34494B00DAA3B8C3E4890836AC6DC967ACA9858A470B2811B69353D1A05E3415B847600DCF35D2ADB2DF33FE

本来一切都好好的,但测试却报来了一个BUG,移动端有某些功能缺失。我想不可能啊,都没动过,怎么会有问题,不会是腾讯视频的问题吧。

最后发现,确实是,因为腾讯视频居然改写了触摸手势……大概就是重新转发了触发手势,但原来的手势已经触发一遍了,导致触发了两遍。

最后的解决方案是用一个新的iframe来包裹腾讯视频,以避免其JS代码对原项目的污染,而项目与iframe的传输目前也比较简单,直接通过url传数据进去即可。

总结

作为一个API文档,其实腾讯视频应对普通的需求已经足够的,当你想要更多的定制时,就会面对更多的问题,也只是一步一步解决。

需求总是奇葩的。方案总是会有的。BUG也总是会有的。