【JAVA版本】最新websocket获取B站直播弹幕——非官方API

一、教程

如果只想要代码实现,直接看第二部分。

1、相关依赖

fastjson2用于解析JSON字符串,可自行替换成别的框架。
hutool-core用于解压zip数据,可自行替换成别的框架。

<dependency>
    <groupId>com.alibaba.fastjson2groupId>
    <artifactId>fastjson2artifactId>
    <version>2.0.40version>
dependency>

<dependency>
    <groupId>cn.hutoolgroupId>
    <artifactId>hutool-coreartifactId>
    <version>5.8.21version>
dependency>

2、获取Cookie

2023年9月B站如果不登录,获取到的弹幕消息是经过脱敏的,获取不到用户名和用户ID。
获取方式: 电脑浏览器登录B站,按F12去网络请求里把B站Cookie值全部复制出来。

3、自定义GET方法,让每次请求都带上cookie

private String get(String url) throws IOException, NoSuchAlgorithmException, InvalidKeyException {
   
    String bodyStr = JSONObject.toJSONString(dataMap);
    HttpURLConnection con = (HttpURLConnection) new URL(url).openConnection();
    con.setRequestMethod(method.code);
    /**----------设置请求头------------------------------------------------------------------**/
    con.setRequestProperty("User-Agent", "Mozilla/5.0");
    con.setRequestProperty("Accept", "application/json");application/json。
    con.setRequestProperty("Content-Type", "application/json");
    con.setRequestProperty("Cookie", cookie);
    // 获取响应结果
    try(BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(con.getInputStream(), StandardCharsets.UTF_8))){
   
        // 返回响应结果
        return  bufferedReader.lines().collect(Collectors.joining("\n"));
    }
}

3、定义获取弹幕服务器信息 和 使用

该方法可以获得弹幕服务器信息检验你是否登录的token

public JSONObject getDanmuInfoData(int roomid) throws IOException, NoSuchAlgorithmException, InvalidKeyException {
   
	//获取直播间真实ID ,因为存在短ID
	String result = get("https://api.live.bilibili.com/room/v1/Room/room_init?id="+roomid);
    roomid = JSONObject.parseObject(result).getJSONObject("data").getIntValue("room_id");;
	//获取弹幕服务信息
	result = get("https://api.live.bilibili.com/xlive/web-room/v1/index/getDanmuInfo?type=0&id="+roomid)return JSONObject.parseObject(getDanmuInfo(result )).getJSONObject("data");
}

使用:

//获取弹幕服务器信息
JSONObject danmuInfoData = getDanmuInfoData(直播间ID);
//获取完整弹幕信息的Token
String token = danmuInfoData.getString("token");
//服务器节点列表
JSONArray hostList = danmuInfoData.getJSONArray("host_list");
//选一个服务器节点
JSONObject host = hostList.getJSONObject(0);
//弹幕服务器地址
String wsUrl = String.format("ws://%s:%s/sub", host.getString("host"), host.getString("ws_port"));

4、定义websocket监听类,处理监听到的事件

4.1先新建几个常量,后面方便使用。

public interface Opt{
   
    short HEARTBEAT = 2;//	客户端发送的心跳包(30秒发送一次)
    short HEARTBEAT_REPLY = 3;//	服务器收到心跳包的回复 人气值,数据不是JSON,是4字节整数
    short SEND_SMS_REPLY = 5;//	服务器推送的弹幕消息包
    short AUTH = 7;//客户端发送的鉴权包(客户端发送的第一个包)
    short AUTH_REPLY = 8;//服务器收到鉴权包后的回复
}
public interface Version{
   
    short NORMAL = 0;//Body实际发送的数据——普通JSON数据
    short ZIP = 2; //Body中是经过压缩后的数据,请使用zlib解压,然后按照Proto协议去解析。
}

4.2定义WebsocketListener 监听类

定义变量cookie、roomid、token,需要用他们生成鉴权包。

@ClientEndpoint
public class WebsocketListener {
   
    private String cookie;
    private int roomid;
    private String token;

    public WebsocketListener(String cookie, int roomid, String token) {
   
        this.cookie = cookie;
        this.roomid = roomid;
        this.token = token;
    }

    private Session session;
    @OnOpen
    public void onOpen(Session session) throws IOException {
   
        

    }

    @OnMessage
    public void onMessage(ByteBuffer byteBuffer) {
   
      
    }

    @OnClose
    public void onClose(Session session, CloseReason closeReason) {
   
        System.out.println("服务器断开: " + closeReason);
    }

    @OnError
    public void onError(Session session, Throwable t) {
   
        t.printStackTrace();
    }

定义 封包 / 解包 方法

Websocket发送和接收时使用。

定义WebsocketListener 封包方法
public static byte[] pack(String jsonStr, @NonNull short code) throws IOException {
   
    byte[] contentBytes = new 

你可能感兴趣的:(其他,java,websocket,数据库)