【开源项目】BiliBili推送姬 V1.0.0-alpha

修复BUG

  1. 修复了多群聊推送时,部分群聊弹幕词云无法正常发送的问题
  2. 修复了部分情况,通过弹幕姬API无法正常开启弹幕监控的问题
  3. 修复了查成分用户开启隐私时,无法获取导致后台报错的问题
  4. 修复了动态推送截图时,部分情况截取不全或截取评论区的情况
  5. 修复了首次直播推送时,距离上次直播字段错误的问题

新增功能

  1. 所有链接更新为b23.tv的短链,推送时更简洁
  2. 动态推送:当投稿视频/专栏/音乐时,自动截图其详情页面,直接获取信息
  3. 直播推送:直播间标题修改推送提醒;直播统计升级,显示礼物信息
  4. 粉丝数量监控与推送提醒
  5. 获取表情包:发送表情包,可获得所有B站表情包
  6. 获取Up主大表情:发送大表情,可获得Up主上传的大表情
  7. 获取装扮头图:发送大图,可获取装扮中的大图
  8. 获取B站热词解释,发送热词,可获得详细解释和出处
  9. 获取群内提醒事件并做出回应,包括以下内容:群成员增加群成员减少群内文件上传群内戳一戳群成员禁言或解禁
  10. 设置QQ在线机型
  11. 实时查看系统状态 / 内存占用等

详细信息

1)多群聊推送时,弹幕词云遗漏的问题

上一版本的架构为,框架生成弹幕词云获取链接,发送至QQ客户端,使QQ客户端向词云发起API请求。当多群推送时,短时间大量的请求发至词云接口,使得其无法处理请求,从而造成无法发送的问题。

由于该项改动涉及底层架构的修改,所以花费了大量的精力和时间修改。

首先重构了python工具箱的fastapi构架,目录结构更清晰,并将每个功能分到不同的线程,每个线程中再单独使用异步或同步的方法处理请求。

最初的架构是,框架将API制作请求发至fastapi,制作完毕后,异步回调至框架,返回Base64编码,直接发送至QQ客户端发送

实现细节上,我们对词云这样无法异步处理的功能,单独开放一条线程和监测队列,fastapi收到请求后,生成独立uuid,将请求放置队列,并返回uuid。另一线程检测到队列中的请求,生成弹幕词云,再携带uuid返回至框架,实现推送。

框架上的处理,为了防止异步处理占用协程或开启大量协程占用CPU和内存,我使用了框架的LightCache轻量缓存,用于储存短时间的回调数据,其中,uuid字段存放fastapi返回的数据,并保存需要推送的mid和消息类型,当收到回调时,从LightCache取出数据,从而实现推送。

然而在实际实现中,QQ客户端的Base64编码的兼容性似乎存在未知问题,导致其虽然能够成功发送,但不会向框架同步返回数据,从而导致框架的sendMsg()函数卡住,使HTTP请求彻底超时,再从而卡住fastapi的回调函数,使得整个功能的线程失去作用。

因此,我目前使用的是只返回生成图片的路径,让QQ客户端去路径中取数据,缺点是当多服务器或多docker则将兼容性降低,之后可能会改为另一种方案(下注)。

当然,这也同时解决了另一个问题,框架的http组件收取post时,对于大数据包存在问题,导致高清晰度的词云图片无法接受,因此选用返回路径也可以避免此问题。

2) 弹幕姬可能无法正常开启的问题

这个问题比较低级。

为了减轻服务器负担,我选用的方案是开播时请求弹幕姬开启监听,结束是请求弹幕姬关闭监听。原有的弹幕姬,关闭监听时,虽然关闭了监听,但是不会将其从监听列表中删除,导致下次开启监听时,程序判断正在监听(其实没有),不再开启监听,导致此问题。

3) 截图器截图不全或其他截图器问题

旧有的截图器使用的是phantomjs,虽然具有速度较快,对javaScript兼容较好的有点,但仍然避免不了其稳定性差,与python兼容性差的问题。因此,我彻底更换浏览器,改为微软的playwright处理截图。

playwrightpython兼容性极强,且支持异步处理,也就是说其对fastapi相对兼容性好,著名的Haruka Bot使用的也是playwright

使用时,我通过javaScript隐藏了部分元素,关闭了推荐栏/评论栏/广告栏,再次截图,从而达到极高的稳定性。

但是,视频截图时,等待时间不准确,起初我想改变思路,将视频留在封面进行截图,但是目前我对BiliBili播放器的挖掘还不够深入,等待下一步更新

其他开发时遇到的小问题

  1. 通过装扮商城获取的装扮列表中,没有已下架的装扮,因此导致装扮不全。
  2. python的多线程非常难用,thread-2中没有loop,需要手动创建
  3. fastapi的路由设置和正常的python文件引入有所区别,需要特意按照官方文档引入路由
  4. python作为胶水语言,为什么别的语言调用它,目前只能使用http呢?
点赞

发表评论