当前位置: 首页 > news >正文

Websocket获取B站直播间弹幕教程——第二篇、解包/拆包

教程一、Websocket获取B站直播间弹幕教程 — 哔哩哔哩直播开放平台

1、封包

我们连接上B站Websocket成功后,要做两件事情:

  • 第一、发送鉴权包。
  • 第二、发送心跳包,每30秒一次,维持websocket连接。

这两个包不是直接发送过去,而是要创建byte数组,将一些数据 按B站协议格式 用大端序写入到byte数组

协议

在这里插入图片描述

  • 1、(4 byte)Packet Length:整个Packet的长度,包含Header。
  • 2、(2 byte)Header Length:Header的长度,固定为16。
  • 3、(2 byte)Version
    • 如果Version=0,Body中就是实际发送的数据。
    • 如果Version=2,Body中是经过压缩后的数据,请使用zlib解压,然后按照Proto协议去解析。
  • 4、(4 byte)Operation:消息的类型:
    • Operation == 2,客户端发送的心跳包(30秒发送一次)
    • Operation == 3 ,服务器收到心跳包的回复
    • Operation == 5 ,服务器推送的弹幕消息包
    • Operation == 7 ,客户端发送的鉴权包(客户端发送的第一个包)
    • Operation == 8 ,服务器收到鉴权包后的回复
  • 5、(4 byte)Sequence ID:保留字段,可以忽略。
  • 6、(? byte)Body:消息体
    • body为json格式字符串 --> 转Byte数组
    • 如果是心跳包body就为空

例子

这边以JAVA代码为例。
代码依赖了FastJson2,用于将Json(Map)转Json字符串。

public static byte[] pack(String jsonStr, short code){byte[] contentBytes = new byte[0];//如果是鉴权包,那一定带有jsonStrif(7 == code){contentBytes = jsonStr.getBytes();}try(ByteArrayOutputStream data = new ByteArrayOutputStream();DataOutputStream stream = new DataOutputStream(data)){stream.writeInt(contentBytes.length + 16);//封包总大小stream.writeShort(16);//头部长度 header的长度,固定为16stream.writeShort(0);//Version, 客户端一般发送的是普通数据。stream.writeInt(code);//操作码(封包类型)stream.writeInt(1);//保留字段,可以忽略。if(7 == code){stream.writeBytes(jsonStr);}return data.toByteArray();}
}

这样封包的方法就写好了,jsonStr为要发的数据,code为包的类型。

定义生成鉴权包的方法:
public byte[] generateAuthPack(String jsonStr) throws IOException {return pack(jsonStr, 7);
}

如果你是非官方开放API接口调用,那jsonStr得自己生成。

public byte[] generateAuthPack(String uid, String buvid,String token, int roomid){JSONObject jo = new JSONObject();jo.put("uid", uid);jo.put("buvid", buvid);jo.put("roomid", roomid);jo.put("protover", 0);jo.put("platform", "web");jo.put("type", 2);jo.put("key", token);return pack(jo.toString(), 7);
}
  • 参数
    • uid : 你Cookie的DedeUserID
    • buvid : 你Cookie的buvid3
    • token : 鉴于是否登录token
    • roomid : 直播间ID

如何获取Token?
----> 【JAVA版本】最新websocket获取B站直播弹幕——非官方API

定义生成心跳包的方法:
public static byte[] generateHeartBeatPack() throws IOException {return pack(null, 2);
}

2、解包

成功鉴权后,我们获取到B站数据也都是byte数组,格式跟上面一样,按上面的格式来读取就行了。
不过如果是Zip包那稍微麻烦点。
获得zip包的body后还得进行解压。请添加图片描述

先来个流程图
Created with Raphaël 2.3.0 开始解析byte数组 从 下标0 开始读取 4byte , 这是包长度(body长度+header长度)。 从 下标4 开始读取 2byte , 这是header长度。 从 下标6 开始读取 2byte , Version:0、普通数据,2、zip数据 从 下标8 开始读取 4byte , Operation:消息的类型。 从 下标12 开始读取 4byte , 这是保留字段,可以忽略。 判断Version是否为2,zip包 解压Zip数组 从下标16到读取到“body长度” (body长度 = 包长度 - header长度) 判断是否读完byte数组 结束解析 yes no yes no
代码实现

同样以JAVA代码为例
代码依赖了hutool-core,用于zip数组解压

public static void unpack(ByteBuffer byteBuffer){int packageLen = byteBuffer.getInt();short headLength = byteBuffer.getShort();short protVer = byteBuffer.getShort();int optCode = byteBuffer.getInt();int sequence = byteBuffer.getInt();if(3 == optCode){System.out.println("这是服务器心跳回复");}byte[] contentBytes = new byte[packageLen - headLength];byteBuffer.get(contentBytes);//如果是zip包就进行解包if(2 == protVer){unpack(ByteBuffer.wrap(ZipUtil.unZlib(contentBytes)));return;}String content = new String(contentBytes, StandardCharsets.UTF_8);if(8 == optCode){//返回{"code":0}表示成功System.out.println("这是鉴权回复:"+content);}//真正的弹幕消息if(5 == optCode){System.out.println("真正的弹幕消息:"+content);// todo 自定义处理}//只存在ZIP包解压时才有的情况//如果byteBuffer游标 小于 byteBuffer大小,那就证明还有数据if(byteBuffer.position() < byteBuffer.limit()){unpack(byteBuffer);}}

相关文章:

Websocket获取B站直播间弹幕教程——第二篇、解包/拆包

教程一、Websocket获取B站直播间弹幕教程 — 哔哩哔哩直播开放平台 1、封包 我们连接上B站Websocket成功后&#xff0c;要做两件事情&#xff1a; 第一、发送鉴权包。第二、发送心跳包&#xff0c;每30秒一次&#xff0c;维持websocket连接。 这两个包不是直接发送过去&…...

膝关节检测之1设计目标手势与物体交互的动画

原来只用unity自带的IK&#xff0c;发现背部不能动&#xff0c;且手和手指的移动和旋转试了好像没法通过animation实现&#xff08;加入关键帧并修改最终状态的数值后播放没有变化&#xff0c;确定最终关键帧的数值已经改了的&#xff09;。看资料&#xff0c;发现final IK&…...

canvas力导布局

老规矩&#xff0c;先上效果图 <html><head><style>* {margin: 0;padding: 0;}canvas {display: block;width: 100%;height: 100%;background: #000;}</style> </head><body><canvas id"network"></canvas> </…...

【网络安全】「漏洞原理」(二)SQL 注入漏洞之理论讲解

前言 严正声明&#xff1a;本博文所讨论的技术仅用于研究学习&#xff0c;旨在增强读者的信息安全意识&#xff0c;提高信息安全防护技能&#xff0c;严禁用于非法活动。任何个人、团体、组织不得用于非法目的&#xff0c;违法犯罪必将受到法律的严厉制裁。 【点击此处即可获…...

JavaScript中类的学习

一、JavaScript中的类 1.什么是类 类描述了一种代码的组织结构形式&#xff0c;不同的语言中对其实现形式各有差异。JavaScript中的类Class实际是一种描述对象之间引用关系的语法糖。 在Class语法糖出现之前&#xff0c;我们想重用一个功能模块&#xff0c;通常是用一个函数来…...

1600*A. Linova and Kingdom(DFS优先队列贪心)

Problem - 1336A - Codeforces Linova and Kingdom - 洛谷 解析&#xff1a; 开始认为分情况讨论 k 小于等于叶子结点和大于叶子结点的情况&#xff0c;然后选择深度最深的叶子结点和子孙数量最小的结点&#xff0c;但是发现如果把某一个非叶子结点选取&#xff0c;那么其子孙…...

gitlab git lfs的替代软件整理汇总及分析

文章目录 前言替代软件分析git-annexgit-fatgit-symgit-meida 总结 前言 git-lfs科普 Git LFS&#xff08;Large File Storage&#xff09;是一个Git扩展&#xff0c;用于管理大型文件。Git LFS通过将大型文件存储在Git仓库之外&#xff0c;从而加快了Git操作的速度。它使用指…...

IDEA 2023.2.2图文安装教程及下载

IDE 系列的第二个年度更新现已发布&#xff0c;涵盖 IntelliJ IDEA、WebStorm、PyCharm、DataGrip、GoLand、DataSpell 以及 All Products Pack 订阅中包含的其他工具。该版本还包括多项用户体验增强功能&#xff0c;例如 Search Everywhere&#xff08;随处搜索&#xff09;中…...

第六届“中国法研杯”司法人工智能挑战赛

解锁司法科技的未来 “中国法研杯”司法人工智能挑战赛&#xff08;Legal AI Challenge&#xff0c;简称LAIC&#xff09;&#xff0c;是面向法院侧人工智能应用领域唯一权威比赛&#xff0c;大赛愿景是在拥有全球最大规模司法数据的中国&#xff0c;实现法律界、学术界、产业界…...

Springcloud中间件-----分布式搜索引擎 Elasticsearch

该笔记是根据黑马程序员的课来自己写了一遍的,b站有对应教程和资料 第一部分 第二部分 第三部分 预计看完跟着练习5小时足够 1.初识elasticsearch 1.1.了解ES 1.1.1.elasticsearch的作用 elasticsearch是一款非常强大的开源搜索引擎&#xff0c;具备非常多强大功能&#xff…...

基于深度学习的目标检测和语义分割:机器视觉中的最新进展

基于深度学习的目标检测和语义分割是机器视觉领域的两个重要任务&#xff0c;它们在图像处理、自动驾驶、医学影像分析和智能视频监控等应用中发挥着关键作用。以下是这两个领域的最新进展&#xff1a; 目标检测&#xff08;Object Detection&#xff09;&#xff1a; 一阶段检…...

微信小程序报错request:fail -2:net::ERR_FAILED(生成中间证书)

微信小程序报错request:fail -2:net::ERR_FAILED-生成中间证书 前言一、检查网站ssl证书二、生成证书方法1.获取中间证书手动合并1.进入网站&#xff1a;[https://www.myssl.cn/tools/downloadchain.html](https://www.myssl.cn/tools/downloadchain.html)2.点击下一步3.手动合…...

Ubuntu更改时区

sudo apt install tzdata 进行安装时区&#xff0c;有很多时区可供选择。 然后执行:tzselect rootd75c94dcd226:/# date 2023年 10月 11日 星期三 06:25:12 UTC rootd75c94dcd226:/# tzselect Please identify a location so that time zone rules can be set correctly. Ple…...

0144 文件管理

目录 4.文件管理 4.1文件系统基础 4.2目录 4.3文件系统 部分习题 4.文件管理 4.1文件系统基础 4.2目录 4.3文件系统 部分习题 1.UNIX操作系统忠&#xff0c;输入/输出设备视为&#xff08;&#xff09; A.普通文件 B.目录文件 C.索引文件 D.特殊文…...

python psutil库之——获取网络信息(网络接口信息、网络配置信息、以太网接口、ip信息、ip地址信息)

文章目录 使用Python psutil库获取网络信息安装psutil库获取网络连接信息查看所有网络连接过滤特定状态的连接 获取网络接口信息获取网络IO统计信息实例1实例2 总结 使用Python psutil库获取网络信息 Python的psutil库是一个跨平台库&#xff0c;能够方便地获取系统使用情况和…...

uniapp上echarts地图钻取

1: 预期效果 通过切换地图 , 实现地图的钻取效果 2: 实现原理以及核心方法/参数 一开始是想利用更换地图数据的形式进行地图钻取 , 这就意味着我们需要准备全国30多个省份的地图数据 , 由于一开始考虑需要适配小程序端 , 如此多的地图文件增加了程序的体积 , 如果使用接口调…...

scratch保护环境 2023年5月中国电子学会图形化编程 少儿编程 scratch编程等级考试一级真题和答案解析

目录 scratch保护环境 一、题目要求 1、准备工作 2、功能实现 二、案例分析...

RPC分布式网络通信框架项目

文章目录 对比单机聊天服务器、集群聊天服务器以及分布式聊天服务器RPC通信原理使用Protobuf做数据的序列化&#xff0c;相比较于json&#xff0c;有哪些优点&#xff1f;环境配置使用项目代码工程目录vscode远程开发Linux项目muduo网络库编程示例CMake构建项目集成编译环境Lin…...

Navicat如何连接远程服务器的MySQL

参考:https://blog.csdn.net/a648119398/article/details/122420906 1.Navicat for Mysql 2.腾讯云轻量级服务器一台&#xff08;Centos 7&#xff09; 3.Mysql 8.0.24&#xff08;远程服务器内安装的&#xff09; 4.Xshell7&#xff08;连接操作远程服务器&#xff09; 一、修…...

【计算机网络笔记】计算机网络的结构

系列文章目录 什么是计算机网络&#xff1f; 什么是网络协议&#xff1f; 文章目录 系列文章目录网络边缘接入网络数字用户线路 (DSL)电缆网络典型家庭网络的接入机构&#xff08;企业&#xff09;接入网络 (Ethernet)无线接入网络 网络核心Internet结构最后 计算机网络的结构…...

Debian系统简介

目录 Debian系统介绍 Debian版本介绍 Debian软件源介绍 软件包管理工具dpkg dpkg核心指令详解 安装软件包 卸载软件包 查询软件包状态 验证软件包完整性 手动处理依赖关系 dpkg vs apt Debian系统介绍 Debian 和 Ubuntu 都是基于 Debian内核 的 Linux 发行版&#xff…...

LeetCode - 394. 字符串解码

题目 394. 字符串解码 - 力扣&#xff08;LeetCode&#xff09; 思路 使用两个栈&#xff1a;一个存储重复次数&#xff0c;一个存储字符串 遍历输入字符串&#xff1a; 数字处理&#xff1a;遇到数字时&#xff0c;累积计算重复次数左括号处理&#xff1a;保存当前状态&a…...

【C语言练习】080. 使用C语言实现简单的数据库操作

080. 使用C语言实现简单的数据库操作 080. 使用C语言实现简单的数据库操作使用原生APIODBC接口第三方库ORM框架文件模拟1. 安装SQLite2. 示例代码:使用SQLite创建数据库、表和插入数据3. 编译和运行4. 示例运行输出:5. 注意事项6. 总结080. 使用C语言实现简单的数据库操作 在…...

今日学习:Spring线程池|并发修改异常|链路丢失|登录续期|VIP过期策略|数值类缓存

文章目录 优雅版线程池ThreadPoolTaskExecutor和ThreadPoolTaskExecutor的装饰器并发修改异常并发修改异常简介实现机制设计原因及意义 使用线程池造成的链路丢失问题线程池导致的链路丢失问题发生原因 常见解决方法更好的解决方法设计精妙之处 登录续期登录续期常见实现方式特…...

HubSpot推出与ChatGPT的深度集成引发兴奋与担忧

上周三&#xff0c;HubSpot宣布已构建与ChatGPT的深度集成&#xff0c;这一消息在HubSpot用户和营销技术观察者中引发了极大的兴奋&#xff0c;但同时也存在一些关于数据安全的担忧。 许多网络声音声称&#xff0c;这对SaaS应用程序和人工智能而言是一场范式转变。 但向任何技…...

给网站添加live2d看板娘

给网站添加live2d看板娘 参考文献&#xff1a; stevenjoezhang/live2d-widget: 把萌萌哒的看板娘抱回家 (ノ≧∇≦)ノ | Live2D widget for web platformEikanya/Live2d-model: Live2d model collectionzenghongtu/live2d-model-assets 前言 网站环境如下&#xff0c;文章也主…...

pikachu靶场通关笔记19 SQL注入02-字符型注入(GET)

目录 一、SQL注入 二、字符型SQL注入 三、字符型注入与数字型注入 四、源码分析 五、渗透实战 1、渗透准备 2、SQL注入探测 &#xff08;1&#xff09;输入单引号 &#xff08;2&#xff09;万能注入语句 3、获取回显列orderby 4、获取数据库名database 5、获取表名…...

LCTF液晶可调谐滤波器在多光谱相机捕捉无人机目标检测中的作用

中达瑞和自2005年成立以来&#xff0c;一直在光谱成像领域深度钻研和发展&#xff0c;始终致力于研发高性能、高可靠性的光谱成像相机&#xff0c;为科研院校提供更优的产品和服务。在《低空背景下无人机目标的光谱特征研究及目标检测应用》这篇论文中提到中达瑞和 LCTF 作为多…...

机器学习的数学基础:线性模型

线性模型 线性模型的基本形式为&#xff1a; f ( x ) ω T x b f\left(\boldsymbol{x}\right)\boldsymbol{\omega}^\text{T}\boldsymbol{x}b f(x)ωTxb 回归问题 利用最小二乘法&#xff0c;得到 ω \boldsymbol{\omega} ω和 b b b的参数估计$ \boldsymbol{\hat{\omega}}…...

何谓AI编程【02】AI编程官网以优雅草星云智控为例建设实践-完善顶部-建立各项子页-调整排版-优雅草卓伊凡

何谓AI编程【02】AI编程官网以优雅草星云智控为例建设实践-完善顶部-建立各项子页-调整排版-优雅草卓伊凡 背景 我们以建设星云智控官网来做AI编程实践&#xff0c;很多人以为AI已经强大到不需要程序员了&#xff0c;其实不是&#xff0c;AI更加需要程序员&#xff0c;普通人…...