This commit is contained in:
2024-09-28 14:26:59 +08:00
parent 9521e9d5c8
commit 91fe70c1b8
20 changed files with 399 additions and 61 deletions

View File

@@ -4,9 +4,10 @@ import com.alibaba.fastjson2.JSONObject;
import com.yutou.bili.api.LiveApi;
import com.yutou.bili.api.UserApi;
import com.yutou.bili.bean.live.LiveRoomConfig;
import com.yutou.bili.bean.live.LiveRoomInfo;
import com.yutou.bili.bean.live.LiveRoomPlayInfo;
import com.yutou.bili.bean.live.SpiBean;
import com.yutou.bili.bean.login.LoginCookie;
import com.yutou.bili.bean.login.LoginCookieDatabaseBean;
import com.yutou.bili.bean.login.UserInfoBean;
import com.yutou.bili.enums.LiveProtocol;
import com.yutou.bili.enums.LiveVideoCodec;
@@ -32,14 +33,47 @@ public class Main {
HttpLoggingInterceptor.setLog(false);
HttpLoggingInterceptor.setLog(true);
// getPlayUrl();
LiveRoomConfig config=new LiveRoomConfig();
LoginCookie cookie = BiliBiliLoginDatabase.getInstance().get();
/* LiveRoomConfig config=new LiveRoomConfig();
LoginCookieDatabaseBean cookie = BiliBiliLoginDatabase.getInstance().get();
config.setLogin(true);
config.setUid(cookie.getDedeUserID());
config.setRoomId(String.valueOf(855204));
config.setRoomId(String.valueOf(22642754));
config.setRoomId(String.valueOf(81004));
WebSocketManager.getInstance().addRoom(config);
config.setRoomId(String.valueOf(115));
WebSocketManager.getInstance().addRoom(config);*/
BiliLiveNetApiManager
.getInstance()
.getApi(new IHttpApiCheckCallback<LiveApi>() {
@Override
public void onSuccess(LiveApi api) {
api.getRoomInfo("33989")
.enqueue(new HttpCallback<LiveRoomInfo>() {
@Override
public void onResponse(Headers headers, int code, String status, LiveRoomInfo response, String rawResponse) {
LiveRoomConfig config=new LiveRoomConfig();
LoginCookieDatabaseBean cookie = BiliBiliLoginDatabase.getInstance().get();
config.setLogin(true);
config.setUid(cookie.getDedeUserID());
config.setRoomId(String.valueOf(response.getRoomId()));
config.setRoomInfo(response);
WebSocketManager.getInstance().addRoom(config);
}
@Override
public void onFailure(Throwable throwable) {
}
});
}
@Override
public void onError(int code, String error) {
}
});
}
@@ -149,9 +183,9 @@ public class Main {
}
public static void login(String username, String password) {
BiliLoginNetApiManager.getInstance().login(new HttpCallback<LoginCookie>() {
BiliLoginNetApiManager.getInstance().login(new HttpCallback<LoginCookieDatabaseBean>() {
@Override
public void onResponse(Headers headers, int code, String status, LoginCookie response, String rawResponse) {
public void onResponse(Headers headers, int code, String status, LoginCookieDatabaseBean response, String rawResponse) {
System.out.println("headers = " + headers + ", code = " + code + ", status = " + status + ", response = " + response + ", rawResponse = " + rawResponse);
if (code == BiliLoginNetApiManager.LOGIN_SUCCESS) {
BiliBiliLoginDatabase.getInstance().initData(response).close();

View File

@@ -0,0 +1,48 @@
package com.yutou.bili.bean.live;
import com.alibaba.fastjson2.annotation.JSONField;
import com.yutou.bili.bean.websocket.live.WSDanmuData;
import com.yutou.bili.bean.websocket.live.WSData;
import com.yutou.databases.AbsDatabasesBean;
import lombok.Data;
import lombok.EqualsAndHashCode;
@EqualsAndHashCode(callSuper = true)
@Data
public class LiveDanmuDatabaseBean extends AbsDatabasesBean {
@JSONField(name = "id")
int id;
@JSONField(name = "danmu")
private String danmu;
@JSONField(name = "model")
private int model;// 1~3 滚动弹幕 4 底端弹幕 5 顶端弹幕 6 逆向弹幕 7 精准定位 8 高级弹幕
@JSONField(name = "fontSize")
private int fontSize;
@JSONField(name = "color")
private String fontColor;
@JSONField(name = "time")
private long time;
@JSONField(name = "uid")
private long uid;
@JSONField(name = "uname")
private String uname;
@JSONField(name = "json")
private String json;
public LiveDanmuDatabaseBean() {
super("danmu");
}
public LiveDanmuDatabaseBean(WSDanmuData danmu) {
super("danmu");
json = danmu.getJson();
this.danmu = danmu.getDanmu();
model = danmu.getModel();
fontSize = danmu.getFontSize();
fontColor = danmu.getFontColor();
time = danmu.getTime();
uid = danmu.getUid();
uname = danmu.getUname();
}
}

View File

@@ -0,0 +1,18 @@
package com.yutou.bili.bean.live;
import com.yutou.bili.bean.websocket.live.WSSendGift;
import com.yutou.databases.AbsDatabasesBean;
import lombok.Data;
import lombok.EqualsAndHashCode;
@EqualsAndHashCode(callSuper = true)
@Data
public class LiveGiftDatabaseBean extends AbsDatabasesBean {
public LiveGiftDatabaseBean() {
super("gift");
}
public LiveGiftDatabaseBean(WSSendGift tableName) {
super("gift");
}
}

View File

@@ -0,0 +1,50 @@
package com.yutou.bili.bean.live;
import com.alibaba.fastjson2.JSONObject;
import com.alibaba.fastjson2.annotation.JSONField;
import com.yutou.databases.AbsDatabasesBean;
import lombok.Data;
import lombok.EqualsAndHashCode;
import org.springframework.util.StringUtils;
import java.util.List;
@EqualsAndHashCode(callSuper = true)
@Data
public class LiveInfoDatabaseBean extends AbsDatabasesBean {
@JSONField(name = "id")
int id;
@JSONField(name = "roomId")
private String roomId;
@JSONField(name = "anchorUid")
private String anchorUid;
@JSONField(name = "room_mid")
private String title;
@JSONField(name = "record_time_start")
private long recordTimeStart;
@JSONField(name = "record_time_end")
private long recordTimeEnd;
@JSONField(name = "record_keyword")
private String cover;
@JSONField(name = "room_info")
private String roomInfo;
public LiveInfoDatabaseBean(LiveRoomInfo info) {
super("info");
roomId = String.valueOf(info.getRoomId());
roomInfo = JSONObject.toJSONString(info);
recordTimeStart = System.currentTimeMillis();
anchorUid = String.valueOf(info.getUid());
title = info.getTitle();
cover = info.getUserCover();
}
public LiveInfoDatabaseBean() {
super("info");
}
public static void main(String[] args) {
new LiveInfoDatabaseBean().toJson();
}
}

View File

@@ -0,0 +1,34 @@
package com.yutou.bili.bean.live;
import com.yutou.bili.bean.websocket.live.WSInteractWord;
import com.yutou.databases.AbsDatabasesBean;
import lombok.Data;
import lombok.EqualsAndHashCode;
@EqualsAndHashCode(callSuper = true)
@Data
public class LiveInteractWordDatabaseBean extends AbsDatabasesBean {
private long uid;
private int type; //1为进场,2为关注
private long roomId;
private long timer;
private String uname;
private String uname_color;
private String face;
public LiveInteractWordDatabaseBean() {
super("InteractWord");
}
public LiveInteractWordDatabaseBean(WSInteractWord bean) {
super("InteractWord");
uid = bean.getUid();
type = bean.getType();
roomId = bean.getRoomId();
timer = bean.getTimer();
uname = bean.getUname();
uname_color = bean.getUname_color();
face = bean.getFace();
}
}

View File

@@ -9,5 +9,6 @@ public class LiveRoomConfig {
String mid;//真实房间id
boolean isLogin;
LiveDanmuInfo liveInfo;
LiveRoomInfo roomInfo;
}

View File

@@ -0,0 +1,23 @@
package com.yutou.bili.bean.live;
import com.yutou.bili.bean.websocket.live.WSData;
import com.yutou.databases.AbsDatabasesBean;
import lombok.Data;
import lombok.EqualsAndHashCode;
@EqualsAndHashCode(callSuper = true)
@Data
public class LiveSourceDatabaseBean extends AbsDatabasesBean {
private String json;
private long timer;
public LiveSourceDatabaseBean() {
super("source");
}
public LiveSourceDatabaseBean(WSData bean) {
super("source");
this.json = bean.getJson();
timer = bean.getWs_timer();
}
}

View File

@@ -1,14 +1,13 @@
package com.yutou.bili.bean.login;
import com.alibaba.fastjson2.annotation.JSONField;
import com.google.gson.annotations.SerializedName;
import com.yutou.databases.AbsDatabasesBean;
import lombok.Data;
import lombok.EqualsAndHashCode;
@EqualsAndHashCode(callSuper = true)
@Data
public class LoginCookie extends AbsDatabasesBean {
public class LoginCookieDatabaseBean extends AbsDatabasesBean {
@JSONField(name = "SESSDATA")
String sessdta;
@JSONField(name = "Path")
@@ -28,7 +27,7 @@ public class LoginCookie extends AbsDatabasesBean {
@JSONField(name = "gourl")
String gourl;
public LoginCookie() {
setTableName("login_cookie");
public LoginCookieDatabaseBean() {
super("login_cookie");
}
}

View File

@@ -1,10 +1,12 @@
package com.yutou.bili.bean.websocket.live;
import com.alibaba.fastjson2.JSONObject;
import com.yutou.inter.ISqlDatabaseBean;
import lombok.Data;
import java.io.Serializable;
public class WSData implements Serializable {
@Data
public class WSData implements Serializable, ISqlDatabaseBean {
public String cmd;
public String jsonSrc;
public long ws_timer;
@@ -39,4 +41,9 @@ public class WSData implements Serializable {
default -> new WSData(json);
};
}
@Override
public String getJson(){
return jsonSrc;
}
}

View File

@@ -14,14 +14,14 @@ import org.springframework.util.StringUtils;
public class WSInteractWord extends WSData {
public final static int TYPE_ENTER = 1;
public final static int TYPE_FOLLOW = 2;
private long uid;
private int type; //1为进场,2为关注
private long roomId;
private long timer;
private WSUserMedal medal;
private long uid;
private String uname;
private String uname_color;
private String face;
private WSUserMedal medal;
public WSInteractWord(JSONObject json) {

View File

@@ -1,17 +1,18 @@
package com.yutou.bili.databases;
import com.yutou.bili.bean.login.LoginCookie;
import com.yutou.bili.bean.login.LoginCookieDatabaseBean;
import com.yutou.databases.AbsDatabasesBean;
import com.yutou.databases.SQLiteManager;
import java.util.List;
public class BiliBiliLoginDatabase extends SQLiteManager {
LoginCookie cookie;
LoginCookieDatabaseBean cookie;
private static BiliBiliLoginDatabase instance;
private BiliBiliLoginDatabase(Class<LoginCookie> tClass) {
private BiliBiliLoginDatabase(Class<LoginCookieDatabaseBean> tClass) {
try {
cookie = new LoginCookie();
cookie = new LoginCookieDatabaseBean();
} catch (Exception e) {
throw new RuntimeException(e);
}
@@ -20,13 +21,13 @@ public class BiliBiliLoginDatabase extends SQLiteManager {
public static BiliBiliLoginDatabase getInstance() {
if (instance == null) {
instance = new BiliBiliLoginDatabase(LoginCookie.class);
instance = new BiliBiliLoginDatabase(LoginCookieDatabaseBean.class);
}
return instance;
}
public BiliBiliLoginDatabase initData(LoginCookie cookie) {
public BiliBiliLoginDatabase initData(LoginCookieDatabaseBean cookie) {
this.cookie = cookie;
for (BuildSqlTable table : build.getTable()) {
cookie.setTableName(table.getName());
@@ -35,17 +36,22 @@ public class BiliBiliLoginDatabase extends SQLiteManager {
return this;
}
public LoginCookie get() {
List<LoginCookie> list = super.get(cookie.getTableName(), LoginCookie.class);
public LoginCookieDatabaseBean get() {
List<LoginCookieDatabaseBean> list = super.get(cookie.getTableName(), LoginCookieDatabaseBean.class);
if (!list.isEmpty()) {
return list.get(0);
return list.getFirst();
}
return null;
}
@Override
protected LoginCookie getDataBean() {
return new LoginCookie();
public String getFileName() {
return "bilibili_login.db";
}
@Override
protected List<AbsDatabasesBean> getDataBean() {
return List.of(new LoginCookieDatabaseBean());
}
}
/**

View File

@@ -0,0 +1,71 @@
package com.yutou.bili.databases;
import com.yutou.bili.bean.live.*;
import com.yutou.bili.bean.websocket.live.WSDanmuData;
import com.yutou.bili.bean.websocket.live.WSData;
import com.yutou.bili.bean.websocket.live.WSInteractWord;
import com.yutou.bili.bean.websocket.live.WSSendGift;
import com.yutou.databases.AbsDatabasesBean;
import com.yutou.databases.SQLiteManager;
import java.util.List;
public class BiliLiveDatabase extends SQLiteManager {
private static BiliLiveDatabase instance;
LiveInfoDatabaseBean bean;
public static BiliLiveDatabase getInstance() {
if (instance == null) {
instance = new BiliLiveDatabase();
}
return instance;
}
private BiliLiveDatabase() {
init();
}
@Override
public String getFileName() {
return "live.db";
}
@Override
protected List<AbsDatabasesBean> getDataBean() {
return List.of(
new LiveInfoDatabaseBean(),
new LiveDanmuDatabaseBean(),
new LiveGiftDatabaseBean(),
new LiveInteractWordDatabaseBean(),
new LiveSourceDatabaseBean()
);
}
public void addLiveInfo(LiveRoomInfo info) {
this.bean = new LiveInfoDatabaseBean(info);
List<LiveInfoDatabaseBean> infos = get(bean.getTableName(), LiveInfoDatabaseBean.class);
if (infos.isEmpty()) {
createInfo(bean);
}
}
private void addData(WSData bean) {
if (bean instanceof WSDanmuData) {
add(new LiveDanmuDatabaseBean((WSDanmuData) bean));
} else if (bean instanceof WSInteractWord) {
add(new LiveInteractWordDatabaseBean((WSInteractWord) bean));
}else if(bean instanceof WSSendGift){
add(new LiveGiftDatabaseBean((WSSendGift) bean));
}
}
public void addSource(WSData bean) {
add(new LiveSourceDatabaseBean(bean));
addData(bean);
}
private void createInfo(LiveInfoDatabaseBean bean) {
add(bean);
}
}

View File

@@ -2,7 +2,7 @@ package com.yutou.bili.net;
import com.alibaba.fastjson2.JSONObject;
import com.yutou.bili.api.LiveApi;
import com.yutou.bili.bean.login.LoginCookie;
import com.yutou.bili.bean.login.LoginCookieDatabaseBean;
import com.yutou.bili.databases.BiliBiliLoginDatabase;
import com.yutou.inter.IHttpApiCheckCallback;
import com.yutou.okhttp.api.BaseApi;
@@ -24,7 +24,7 @@ public class BiliLiveNetApiManager extends BaseApi {
}
public void getApi(IHttpApiCheckCallback<LiveApi> callback) {
LoginCookie cookie = BiliBiliLoginDatabase.getInstance().get();
LoginCookieDatabaseBean cookie = BiliBiliLoginDatabase.getInstance().get();
if (cookie != null) {
useCookie(JSONObject.parseObject(JSONObject.toJSONString(cookie)));
}

View File

@@ -2,7 +2,7 @@ package com.yutou.bili.net;
import com.alibaba.fastjson2.JSONObject;
import com.yutou.bili.api.LoginApi;
import com.yutou.bili.bean.login.LoginCookie;
import com.yutou.bili.bean.login.LoginCookieDatabaseBean;
import com.yutou.bili.bean.login.LoginInfoBean;
import com.yutou.bili.bean.login.QRCodeGenerateBean;
import com.yutou.bili.databases.BiliBiliLoginDatabase;
@@ -43,7 +43,7 @@ public class BiliLoginNetApiManager extends BaseApi {
public LoginApi getLoginApi(boolean isCookie) {
if (isCookie) {
LoginCookie cookie = BiliBiliLoginDatabase.getInstance().get();
LoginCookieDatabaseBean cookie = BiliBiliLoginDatabase.getInstance().get();
if (cookie != null) {
useCookie(JSONObject.parseObject(JSONObject.toJSONString(cookie)));
}
@@ -51,8 +51,8 @@ public class BiliLoginNetApiManager extends BaseApi {
return loginApi;
}
public void login(HttpCallback<LoginCookie> callback) {
LoginCookie cookie = BiliBiliLoginDatabase.getInstance().get();
public void login(HttpCallback<LoginCookieDatabaseBean> callback) {
LoginCookieDatabaseBean cookie = BiliBiliLoginDatabase.getInstance().get();
if (cookie != null) {
callback.onResponse(null, LOGIN_SUCCESS, null, cookie, null);
return;
@@ -74,7 +74,7 @@ public class BiliLoginNetApiManager extends BaseApi {
});
}
private void waitLogin(String oauthKey, HttpCallback<LoginCookie> callback) {
private void waitLogin(String oauthKey, HttpCallback<LoginCookieDatabaseBean> callback) {
long time = System.currentTimeMillis();
new Timer().schedule(new TimerTask() {
@Override
@@ -110,7 +110,7 @@ public class BiliLoginNetApiManager extends BaseApi {
}
if (!list.isEmpty()) {
ck.put("gourl", bd);
LoginCookie cookie = JSONObject.parseObject(ck.toString(), LoginCookie.class);
LoginCookieDatabaseBean cookie = JSONObject.parseObject(ck.toString(), LoginCookieDatabaseBean.class);
cancel();
callback.onResponse(headers, LOGIN_SUCCESS, "ok", cookie, ck.toString());

View File

@@ -2,13 +2,12 @@ package com.yutou.bili.net;
import com.alibaba.fastjson2.JSONObject;
import com.yutou.bili.api.UserApi;
import com.yutou.bili.bean.login.LoginCookie;
import com.yutou.bili.bean.login.LoginCookieDatabaseBean;
import com.yutou.bili.databases.BiliBiliLoginDatabase;
import com.yutou.inter.IHttpApiCheckCallback;
import com.yutou.okhttp.api.BaseApi;
import java.util.HashMap;
import java.util.List;
public class BiliUserNetApiManager extends BaseApi {
public static final int LOGIN_LOGOUT = 1;
@@ -27,7 +26,7 @@ public class BiliUserNetApiManager extends BaseApi {
}
public void getUserApi(IHttpApiCheckCallback<UserApi> callback) {
LoginCookie cookie = BiliBiliLoginDatabase.getInstance().get();
LoginCookieDatabaseBean cookie = BiliBiliLoginDatabase.getInstance().get();
if (cookie != null) {
HashMap<String, String> headers = new HashMap<>();
JSONObject json = JSONObject.parseObject(JSONObject.toJSONString(cookie));

View File

@@ -10,8 +10,9 @@ import com.yutou.bili.bean.live.LiveDanmuInfo;
import com.yutou.bili.bean.live.LiveRoomConfig;
import com.yutou.bili.bean.websocket.WebSocketBody;
import com.yutou.bili.bean.websocket.WebSocketHeader;
import com.yutou.bili.bean.websocket.live.WSDanmuData;
import com.yutou.bili.bean.websocket.live.WSData;
import com.yutou.bili.databases.BiliBiliLoginDatabase;
import com.yutou.bili.databases.BiliLiveDatabase;
import com.yutou.bili.utils.BiliUserUtils;
import com.yutou.bili.utils.BytesUtils;
import com.yutou.inter.IHttpApiCheckCallback;
@@ -89,6 +90,8 @@ public class WebSocketManager {
super(serverUri);
this.roomConfig = roomId;
heartbeatTask = new HeartbeatTask();
Brotli4jLoader.ensureAvailability();
BiliLiveDatabase.getInstance().addLiveInfo(roomConfig.getRoomInfo());
connect();
}
@@ -156,13 +159,15 @@ public class WebSocketManager {
private void unzipDanmu(byte[] bytes, boolean useHeader) {
try {
Brotli4jLoader.ensureAvailability();
DirectDecompress directDecompress = Decoder.decompress(bytes);
if (directDecompress.getResultStatus() == DecoderJNI.Status.DONE) {
WebSocketBody body = new WebSocketBody(directDecompress.getDecompressedData());
Log.i("3协议:" + useHeader + " 命令数:" + body.getBodyList().size());
for (JSONObject json : body.getBodyList()) {
Log.i("解压:" + WSData.parse(json));
WSData parse = WSData.parse(json);
BiliLiveDatabase.getInstance().addSource(parse);
Log.i("解压:" + parse);
}
System.out.println();
System.out.println();