教程一、Websocket获取B站直播间弹幕教程 — 哔哩哔哩直播开放平台
这两个包不是直接发送过去,而是要创建byte数组,将一些数据 按B站协议格式 用大端序写入到byte数组。
这边以JAVA代码为例。
代码依赖了FastJson2,用于将Json(Map)转Json字符串。
public static byte[] pack(String jsonStr, short code){
byte[] contentBytes = new byte[0];
//如果是鉴权包,那一定带有jsonStr
if(7 == code){
contentBytes = jsonStr.getBytes();
}
try(ByteArrayOutputStream data = new ByteArrayOutputStream();
DataOutputStream stream = new DataOutputStream(data)){
stream.writeInt(contentBytes.length + 16);//封包总大小
stream.writeShort(16);//头部长度 header的长度,固定为16
stream.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);
}
如何获取Token?
----> 【JAVA版本】最新websocket获取B站直播弹幕——非官方API
public static byte[] generateHeartBeatPack() throws IOException {
return pack(null, 2);
}
成功鉴权后,我们获取到B站数据也都是byte数组,格式跟上面一样,按上面的格式来读取就行了。
不过如果是Zip包那稍微麻烦点。
获得zip包的body后还得进行解压。
同样以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);
}
}