user
从头写了一个 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 流。

微信小程序码
网站网页 介绍网页技术和有意思的网站
——
Total Comments(Loading)
New to Old
defaultimg
Input Your Information to Comment
Loading