从头写了一个 Bilibili 视频下载工具 11/18更新

发布于
从头写了一个 Bilibili 视频下载工具 11/18更新
本文导览

从头写了一个 Bilibili 视频下载工具 11/18更新

  • 11/09更新 增加了简易的用户系统,仅仅只有注册,登陆,登出的功能。
  • 11/10更新 增加了邮箱认证激活的功能
  • 11/11更新 增加了邮箱找回密码的功能
  • 11/14更新 增加了邀请码功能、增加了权限系统、增加了下载60帧视频选项,功能优化,结构重构
  • 11/15更新 全站实现PJAX 包括登陆、登出等操作。优化操作逻辑,对于用户在下载时突然刷新、后退、关闭页面等例外情况进行处理。
  • 11/18更新 强化各类API的安全性,现在只有登陆才能调用API。增加单用户最大缓存限制,增加缓存管理功能。增加弹幕下载和xml弹幕转ass字幕的功能

之前考完雅思闲着没什么事情,在剪完了视频之后就想着写个能获取B站视频信息的网页。通过分析请求发现了很多有意思的API。因为现在B站基本都是通过异步来加载信息的。所有很多网页内容都可以通过API找到。

之前我写了一个Python爬虫,可以爬取视频所有的信息和UP主信息,甚至可以爬到弹幕信息。然后出存在MySQL数据库中。但是我才爬取到2015年,数据库的大小就超过了8GB。(再一次后悔只买了128G的硬盘。。。)总之,检验了一下我的爬虫的稳定性,总体还算不错,但每爬10000条总是莫名其妙的会出错2、3个。有些是因为“超”高级弹幕的关系。我也不知道怎么形容。就比如其中一个用弹幕实现了动画的效果。。。这种就会导致出错。

写网页版本的信息获取页也很简单,主要就是要花时间想用户逻辑和操作逻辑和各种意外的处理。毕竟你总不能希望用户都懂这个程式出错了要怎么处理吧。。。然后尽可能地减少无用的请求数量,优化操作逻辑。可以说有一大半时间就是写完了程序,然后感觉哪里不合理或者有更好的方式实现,于是就重写一遍。

后来突然想着能不能像bilibilijj还是什么网站一下,提供一下下载视频的功能。去看了下bilibilijj发现现在不能随便下载视频了,只有满足一定播放量还是弹幕数量的视频才可以下载,另外貌似这个网站是先下载视频到它的服务器,然后转码然后再提供下载,但是选项少的可怜,貌似也没看到可以下载1080P+的视频。于是我就想自己能不能写一个来下载视频。

一开始并没有在xhr和js请求中找到视频相关的链接(想想也不会这么简单)。后来在网上搜了一下别人有没有发现什么API之类的。没想到还真的有。不过只能下载和播放360P的MP4。这也太low了。其他的基本都是从安卓apk中提取到的,需要Appkey和secret key。私钥的话,貌似只能从2016年某一版本的安卓APK文件中反编译的到,最新的也已经加密了。我自认没有这个技术,于是放弃。还是从网页版本上入手。

网页版的话,需要处理登陆(只有登陆后才能观看720P及以上画质),既然都做了,当然要做最好的。接下来就是要看看B站是怎么验证登陆的。一开始我想通过模拟登陆,就是模拟浏览器去登陆,后来发现B站还有验证码,如果是图片验证码那还好说,竟然是滑块验证码。。又是无法处理。后来在github上发现了一个获取用户key的代码,但是已经失效了,于是我想就从cookie入手,通过不断的try and error,终于发现了是sessdata这个项能保存登陆状态,但是貌似有时间限制,时间限制具体是多少还不确定,有时候过几分钟就失效了,有时候可以保持一天多。最持久的还是通过抓包iOS版本的请求,可以看到失效时间,30天。

获取到了sessdata后访问一下获取登陆信息的APi,确认能否正常登陆,可以的话就继续下一步。选择分P。然后根据分P的Cid来获取视频。这边又是一个大坑。总所周知,B站一开始全站flash,所以视频格式也都是flv,后来才转成MP4。所以我需要判断这个视频是否有MP4版本,是否有flv版本。后来发现,基本上高清晰度的MP4都是只有视频而没有音频,音频是另外的文件。flv倒是音频视频都有。然后较低清晰度下的部分mp4是同时也有音频的。总的来说,感觉B站的API及其混乱(也有可能是因为我猜不透参数的关系)。。。

下载视频到服务器的话有很大的坑,比如要注意到如果下载失败如何处理,如何返回下载进度,又如何在用户刷新页面时取消下载。如果遇到分段的flv视频,就调用ffmpeg来进行合成(非常快,只需几秒),遇到视频和音频分离的MP4,也通过ffmpeg来是视频音频合一(也非常快,只需几秒,因为音频也是mp4格式,无需转码)。

为了节约带宽,缓存完成后会向数据库中记录下载的视频信息,这样再次请求时,就无须重新从b站下载,直接调用本地缓存即可,也不用再调用ffmpeg处理了。

最后生成下载和播放链接即可。

为了能播放弹幕,我试用了开源的ABPlayer,同时提供了浏览器自带的播放器,然后尝鲜了一下blob流。

评论
加载评论模块