B站黑科技是怎么做到的?

B站黑科技是怎么做到的?

首先是bilibili的播放器。

bilibili的播放器主要有两个,一个内站播放器

https://static-s.bilibili.tv/play.swf?cid={cid}&aid={aid}

另一个是外站播放器

http://static.hdslb.com/miniloader.swf?aid={aid}&pid={pid}

其中aid就是article id的意思,或者说就是视频的av号;

而pid是page id的意思,也就是说视频的第几个分页;

而cid是chat id的意思,每个chat id对应一组弹幕池和。

然后我们先说第一个内站的播放器。播放器要播放视频显然要先找到视频的内容的地址,这是我们最为关心的。

无论你是靠反编译还是截取网络数据包,都可以看到这个播放器访问了

http://interface.bilibili.cn/playurl?cid={cid}

以获取视频内容的地址,然后加载这些视频并播放。

我们再看后面那个外站播放器。参数里面没有cid,那他是怎么加载视频内容的地址的呢?

如果你再用同样的方法进行分析,你会发现他实际上还是访问了上面说到的那个地址。

那他是怎么获取cid的呢?他获取cid是通过

http://api.bilibili.cn/view?type=json&id={aid}......

的一个链接获取到的。

所以到现在我们基本可以明白bilibili视频的播放,主要依赖于cid和上面提到的那个playurl的链接。

----

然后我们要讨论的问题是关于手机客户端的了。

众所周知地,那些其他视频网站的播放器折腾半天也只是在网页上,而手机客户端上看来这些视频和其他的别无两样。

而分析数据包可以轻松地知道手机客户端访问的还是上面提到的那个playurl的链接。

最后我们回到问题本身。

----

所以问题就简化为了,只要找到最上面提到的内站播放器需要的cid,那么就可以用那个播放器播放视频了。

于是问题变成了如何查找cid。

之前我们说过了,cid被用来表示某个视频对应那组弹幕池。所以只要有弹幕的视频就肯定有一个cid。

事实上,那些其他视频网站的播放器的视频也需要一个cid才能加载弹幕。所以我们可以轻松地从给flash的参数里面找到cid。

当然,除了这个方法外,还有其他很多方法,比如:

通过api获取:请参考http://docs.bilibili.cn/wiki/API.view

通过下载弹幕页面的链接获取:http://www.bilibili.tv/ass/{aid}.html(下载弹幕页面已死)

通过iOS用网页端接口获取:http://www.bilibili.tv/html5?aid={aid}&page={pid} (挂掉过一段时间,现在又恢复了)

当然,还有一些脚本是访问了脚本作者搭建的服务器以获取cid。只有你可以放心该脚本的行为时使用这样的脚本。

然后只要把flash换成上面说的那个内站播放器的就好了。

---

但是有些视频是不能替换的,这些视频一般都是因为在playurl那一步无法获取视频的内容所导致的。

所以这导致的结果就是,一般来说,某站点的视频都是转天转投新浪后才可以看的,不过最近似乎转投视频源从sina变成local了,别问我为什么。

---

最后是一些替换之后的善后工作。在加载

http://static.hdslb.com/js/page.arc.js

脚本时,会根据当前是不是原生播放器而做一些事情,所以替换后需要再手工执行相应的函数。