This commit is contained in:
2024-10-28 18:27:16 +08:00
parent d6fbe6b59b
commit e6568480b7
38 changed files with 445 additions and 221 deletions

View File

@@ -48,22 +48,22 @@ public class Main {
outputStream.write(new byte[]{0, 0, 1, 68, 0, 16, 0, 1, 0, 0, 0, 7, 0, 0, 0, 1});
outputStream.write(json.toJSONString().getBytes(StandardCharsets.UTF_8));
outputStream.flush();
System.out.println("\n\n\n");
Log.i("\n\n\n");
String str = DatatypeConverter.printHexBinary(outputStream.toByteArray());
for (int i = 0; i < str.length(); i = i + 4) {
if (i % 32 == 0 && i != 0) {
System.out.println();
Log.i();
}
if (str.length() - i > 4) {
System.out.print(str.substring(i, i + 4) + " ");
} else {
System.out.println(str.substring(i));
Log.i(str.substring(i));
}
}
System.out.println("\n\n\n");
Log.i("\n\n\n");
} catch (Exception e) {
e.printStackTrace();
Log.e(e);
}
}
@@ -97,27 +97,27 @@ public class Main {
// WebSocketManager.getInstance().addRoom(config);
//
// /*String url = codec.getUrlInfo().get(0).getHost() + codec.getBaseUrl() + codec.getUrlInfo().get(0).getExtra();
// System.out.println("下载url = " + url);
// Log.i("下载url = " + url);
// api.downloadLive(url).enqueue(new FileCallback<>(response) {
// @Override
// public void onStart(LiveRoomPlayInfo bean) {
// System.out.println("开始下载");
// Log.i("开始下载");
// }
//
// @Override
// public boolean onDownload(Headers headers, LiveRoomPlayInfo bean, long len, long total) {
// System.out.println("下载中:"+len+"|"+total);
// Log.i("下载中:"+len+"|"+total);
// return true;
// }
//
// @Override
// public void onFinish(LiveRoomPlayInfo bean) {
// System.out.println("下载结束");
// Log.i("下载结束");
// }
//
// @Override
// public void onFailure(LiveRoomPlayInfo bean, Throwable throwable) {
// System.out.println("下载失败");
// Log.i("下载失败");
// }
// });*/
//
@@ -141,7 +141,7 @@ public class Main {
BiliLoginNetApiManager.getInstance().login(new HttpCallback<LoginCookieDatabaseBean>() {
@Override
public void onResponse(Headers headers, int code, String status, LoginCookieDatabaseBean response, String rawResponse) {
System.out.println("二维码地址: "+rawResponse);
Log.i("二维码地址: "+rawResponse);
if (code == BiliLoginNetApiManager.LOGIN_SUCCESS) {
Response<HttpBody<UserInfoBean>> execute = null;
try {

View File

@@ -1,14 +1,19 @@
package com.yutou.biliapi.bean.live.database;
import com.alibaba.fastjson2.annotation.JSONField;
import com.alibaba.fastjson2.util.DateUtils;
import com.yutou.common.databases.AbsDatabasesBean;
import lombok.Data;
import lombok.EqualsAndHashCode;
import java.io.File;
import java.math.BigInteger;
import java.util.Calendar;
import java.util.Date;
import java.util.List;
import static com.alibaba.fastjson2.util.DateUtils.DateTimeFormatPattern.DATE_FORMAT_10_DASH;
@EqualsAndHashCode(callSuper = true)
@Data
public class LiveConfigDatabaseBean extends AbsDatabasesBean {
@@ -27,52 +32,55 @@ public class LiveConfigDatabaseBean extends AbsDatabasesBean {
@JSONField(name = "keyword")
private List<String> keywordList;
@JSONField(name = "recordPath")
private String recordPath="live";
private String recordPath = "live";
@JSONField(name = "recordUid")
private String recordUid;
@JSONField(name = "recordLiveModel")
private int recordLiveModel;//0 - ffmpeg 1 - java
@JSONField(name = "recordDanmuDate")
private String recordDanmuDate="* * *";// * * * 分 时 星期 | 周日是1
private String recordDanmuDate = "* * *";// * * * 分 时 星期 | 周日是1
@JSONField(name = "recordLiveDate")
private String recordLiveDate="* * *";// * * * 分 时 星期 | 周日是1
private String recordLiveDate = "* * *";// * * * 分 时 星期 | 周日是1
public LiveConfigDatabaseBean() {
super("live_config",System.currentTimeMillis());
super("live_config", System.currentTimeMillis());
}
public boolean checkRecordDanmuTime(){
public boolean checkRecordDanmuTime() {
return checkRecordTime(recordDanmuDate);
}
public boolean checkRecordLiveTime(){
public boolean checkRecordLiveTime() {
return checkRecordTime(recordLiveDate);
}
private boolean checkRecordTime(String recordDate){
private boolean checkRecordTime(String recordDate) {
int _length = recordDate.length();
boolean isFullDate=(_length-recordDate.replace("*","").length())==3;
if(isFullDate){
boolean isFullDate = (_length - recordDate.replace("*", "").length()) == 3;
if (isFullDate) {
return true;
}
String[] split=recordDate.split(" ");
String minute=split[0];
String hour=split[1];
String day=split[2];
boolean isFullMinute= "*".equals(minute);
boolean isFullHour= "*".equals(hour);
boolean isFullDay= "*".equals(day);
Calendar today=Calendar.getInstance();
if(!isFullDay){
if(today.get(Calendar.DAY_OF_WEEK)!=Integer.parseInt(day)){
String[] split = recordDate.split(" ");
String minute = split[0];
String hour = split[1];
String day = split[2];
boolean isFullMinute = "*".equals(minute);
boolean isFullHour = "*".equals(hour);
boolean isFullDay = "*".equals(day);
Calendar today = Calendar.getInstance();
if (!isFullDay) {
if (today.get(Calendar.DAY_OF_WEEK) != Integer.parseInt(day)) {
return false;
}
}
if(!isFullHour) {
if (!isFullHour) {
if (today.get(Calendar.HOUR_OF_DAY) != Integer.parseInt(hour)) {
return false;
}
}
if(!isFullMinute){
if(today.get(Calendar.MINUTE)!=Integer.parseInt(minute)) {
if (!isFullMinute) {
if (today.get(Calendar.MINUTE) != Integer.parseInt(minute)) {
return false;
}
}

View File

@@ -4,6 +4,7 @@ import com.alibaba.fastjson2.JSONObject;
import com.alibaba.fastjson2.annotation.JSONField;
import com.yutou.biliapi.bean.live.LiveRoomInfo;
import com.yutou.common.databases.AbsDatabasesBean;
import com.yutou.common.utils.Log;
import lombok.Data;
import lombok.EqualsAndHashCode;
@@ -49,7 +50,7 @@ public class LiveInfoDatabaseBean extends AbsDatabasesBean {
public static void main(String[] args) {
List<Field> list = new LiveInfoDatabaseBean().getFields();
for (Field field : list) {
System.out.println(field.getName());
Log.i(field.getName());
}

View File

@@ -1,6 +1,7 @@
package com.yutou.biliapi.bean.websocket;
import com.alibaba.fastjson2.JSONObject;
import com.yutou.common.utils.Log;
import lombok.Data;
import java.util.ArrayList;
@@ -27,7 +28,7 @@ public class WebSocketBody {
try {
bodyList.add(JSONObject.parseObject(new String(data)));
} catch (Exception e) {
System.out.println(header + "|" + new String(data));
Log.i(header + "|" + new String(data));
}
addBody(bytes, offset + header.dataSize);
}

View File

@@ -1,6 +1,7 @@
package com.yutou.biliapi.bean.websocket.live;
import com.alibaba.fastjson2.JSONObject;
import com.yutou.common.utils.Log;
import lombok.Data;
import lombok.EqualsAndHashCode;
@@ -22,7 +23,7 @@ public class WSDmInteraction extends WSData{
public static void main(String[] args) {
JSONObject json=JSONObject.parseObject("{\"cmd\":\"DM_INTERACTION\",\"data\":{\"data\":\"{\\\"fade_duration\\\":10000,\\\"cnt\\\":5,\\\"card_appear_interval\\\":0,\\\"suffix_text\\\":\\\"人正在点赞\\\",\\\"reset_cnt\\\":1,\\\"display_flag\\\":1}\",\"dmscore\":36,\"id\":53793047788032,\"status\":4,\"type\":106}}");
WSDmInteraction wsDmInteraction=new WSDmInteraction(json);
System.out.println(wsDmInteraction);
Log.i(wsDmInteraction);
}
public WSDmInteraction(JSONObject json) {
super(json);

View File

@@ -1,6 +1,7 @@
package com.yutou.biliapi.bean.websocket.live;
import com.alibaba.fastjson2.JSONObject;
import com.yutou.common.utils.Log;
import lombok.Data;
import lombok.EqualsAndHashCode;
@@ -24,7 +25,7 @@ public class WSGuardBuy extends WSData{
public static void main(String[] args) {
JSONObject json=JSONObject.parseObject("{\"cmd\":\"GUARD_BUY\",\"data\":{\"uid\":5427372,\"username\":\"李湜渰\",\"guard_level\":3,\"num\":1,\"price\":198000,\"gift_id\":10003,\"gift_name\":\"舰长\",\"start_time\":1724985039,\"end_time\":1724985039}}");
WSGuardBuy wsguardBuy = new WSGuardBuy(json);
System.out.println(wsguardBuy);
Log.i(wsguardBuy);
}
public WSGuardBuy(JSONObject json) {
super(json);

View File

@@ -1,6 +1,7 @@
package com.yutou.biliapi.bean.websocket.live;
import com.alibaba.fastjson2.JSONObject;
import com.yutou.common.utils.Log;
import lombok.Data;
import lombok.EqualsAndHashCode;
@@ -25,7 +26,7 @@ public class WSSuperChatMessage extends WSData{
public static void main(String[] args) {
JSONObject json=JSONObject.parseObject("{\"cmd\":\"SUPER_CHAT_MESSAGE\",\"data\":{\"background_bottom_color\":\"#2A60B2\",\"background_color\":\"#EDF5FF\",\"background_color_end\":\"#405D85\",\"background_color_start\":\"#3171D2\",\"background_icon\":\"\",\"background_image\":\"\",\"background_price_color\":\"#7497CD\",\"color_point\":0.7,\"dmscore\":616,\"end_time\":1724997230,\"gift\":{\"gift_id\":12000,\"gift_name\":\"醒目留言\",\"num\":1},\"group_medal\":{\"is_lighted\":0,\"medal_id\":0,\"name\":\"\"},\"id\":10427329,\"is_mystery\":false,\"is_ranked\":0,\"is_send_audit\":1,\"medal_info\":{\"anchor_roomid\":81004,\"anchor_uname\":\"艾尔莎_Channel\",\"guard_level\":0,\"icon_id\":0,\"is_lighted\":1,\"medal_color\":\"#1a544b\",\"medal_color_border\":1725515,\"medal_color_end\":5414290,\"medal_color_start\":1725515,\"medal_level\":21,\"medal_name\":\"艾薯条\",\"special\":\"\",\"target_id\":1521415},\"message\":\"莎莎,想安利你个植物大战僵尸的改版叫植物大战僵尸:肉鸽,具体情况私信你了,辛苦了\",\"message_font_color\":\"#A3F6FF\",\"message_trans\":\"サーシャ、あなたのPlantsvs.Zombiesの改版をPlantsvs.Zombiesと言いたい肉鳩、具体的な状況は私的にあなたを信じて、お疲れ様でした\",\"price\":30,\"rate\":1000,\"start_time\":1724997170,\"time\":60,\"token\":\"9925C118\",\"trans_mark\":0,\"ts\":1724997170,\"uid\":100002175,\"uinfo\":{\"base\":{\"face\":\"https://i1.hdslb.com/bfs/face/b5ec3b1f7025b5546225ae0f36941d55ddef405b.jpg\",\"is_mystery\":false,\"name\":\"中吴同学\",\"name_color\":0,\"name_color_str\":\"#666666\",\"official_info\":{\"desc\":\"\",\"role\":0,\"title\":\"\",\"type\":-1},\"origin_info\":{\"face\":\"https://i1.hdslb.com/bfs/face/b5ec3b1f7025b5546225ae0f36941d55ddef405b.jpg\",\"name\":\"中吴同学\"}},\"guard\":{\"expired_str\":\"\",\"level\":0},\"medal\":{\"color\":1725515,\"color_border\":1725515,\"color_end\":5414290,\"color_start\":1725515,\"guard_icon\":\"\",\"guard_level\":0,\"honor_icon\":\"\",\"id\":0,\"is_light\":1,\"level\":21,\"name\":\"艾薯条\",\"ruid\":1521415,\"score\":50001980,\"typ\":0,\"user_receive_count\":0,\"v2_medal_color_border\":\"#5FC7F4FF\",\"v2_medal_color_end\":\"#43B3E3CC\",\"v2_medal_color_level\":\"#00308C99\",\"v2_medal_color_start\":\"#43B3E3CC\",\"v2_medal_color_text\":\"#FFFFFFFF\"},\"title\":{\"old_title_css_id\":\"\",\"title_css_id\":\"\"},\"uid\":100002175},\"user_info\":{\"face\":\"https://i1.hdslb.com/bfs/face/b5ec3b1f7025b5546225ae0f36941d55ddef405b.jpg\",\"face_frame\":\"\",\"guard_level\":0,\"is_main_vip\":1,\"is_svip\":0,\"is_vip\":0,\"level_color\":\"#5896de\",\"manager\":0,\"name_color\":\"#666666\",\"title\":\"\",\"uname\":\"中吴同学\",\"user_level\":25}},\"is_report\":true,\"msg_id\":\"19106780029655552:1000:1000\",\"p_is_ack\":true,\"p_msg_type\":1,\"send_time\":1724997170767}");
WSSuperChatMessage message=new WSSuperChatMessage(json);
System.out.println(message);
Log.i(message);
}
public WSSuperChatMessage(JSONObject json) {
super(json);

View File

@@ -8,6 +8,7 @@ import com.yutou.bilibili.Tools.DateFormatUtils;
import com.yutou.common.databases.AbsDatabasesBean;
import com.yutou.common.databases.SQLiteManager;
import com.yutou.common.okhttp.HttpDownloadUtils;
import com.yutou.common.utils.Log;
import org.apache.poi.ss.usermodel.DataFormat;
import java.io.File;
@@ -26,13 +27,12 @@ public class BiliLiveDatabase extends SQLiteManager {
public BiliLiveDatabase(LiveRoomConfig roomConfig, String path) {
this.config = roomConfig;
rootPath = new File(path).getParentFile();
fileName =path;
fileName = path + File.separator + "live.db";
init();
}
public BiliLiveDatabase(LiveRoomConfig roomConfig) {
String time = DateUtils.format(new Date().getTime(), DATE_FORMAT_10_DASH);
rootPath = new File(roomConfig.getRootPath() + File.separator + roomConfig.getAnchorName() + File.separator + time + File.separator + roomConfig.getRoomInfo().getTitle());
rootPath = new File(roomConfig.getRootPath() + File.separator + roomConfig.getAnchorName());
config = roomConfig;
if (!rootPath.exists()) {
rootPath.mkdirs();
@@ -44,7 +44,7 @@ public class BiliLiveDatabase extends SQLiteManager {
@Override
public void init() {
super.init();
if(config.getRoomInfo()!=null) {
if (config.getRoomInfo() != null) {
HttpDownloadUtils.download(new HttpDownloadUtils.Builder().setUrl(config.getRoomInfo().getUserCover())
.setPath(rootPath.getAbsolutePath())
.setFileName("poster.jpg"));
@@ -95,7 +95,7 @@ public class BiliLiveDatabase extends SQLiteManager {
}
public void addSource(WSData bean) {
System.out.println("BiliLiveDatabase.addSource");
Log.i("BiliLiveDatabase.addSource");
add(new LiveSourceDatabaseBean(bean));
addData(bean);
}
@@ -137,7 +137,7 @@ public class BiliLiveDatabase extends SQLiteManager {
public static void main(String[] args) {
/* List<LiveDanmuDatabaseBean> list = getInstance().get(-1, 1727515148800L, LiveDanmuDatabaseBean.class);
for (LiveDanmuDatabaseBean bean : list) {
System.out.println(bean.getSql_time() + "|" + bean);
Log.i(bean.getSql_time() + "|" + bean);
}*/
}
}

View File

@@ -3,6 +3,7 @@ package com.yutou.biliapi.net;
import com.yutou.biliapi.bean.login.CheckCookieBean;
import com.yutou.common.inter.IHttpApiCheckCallback;
import com.yutou.common.okhttp.HttpCallback;
import com.yutou.common.utils.Log;
import com.yutou.common.utils.RSAUtils;
import okhttp3.Headers;
@@ -82,7 +83,7 @@ public class BiliCookieManager {
// Convert the encrypted bytes to a Base64-encoded string
String encrypted = new BigInteger(1, encryptedBytes).toString(16);
}catch (Exception e){
e.printStackTrace();
Log.e(e);
}
}

View File

@@ -90,7 +90,7 @@ public class BiliLoginNetApiManager extends BaseApi {
for (String cookie : list) {
String[] split = cookie.split(";");
for (String string : split) {
if (!ck.containsKey(string) && !StringUtils.isEmpty(string) && string.contains("=")) {
if (!ck.containsKey(string) && StringUtils.hasText(string) && string.contains("=")) {
String key = string.split("=")[0].trim();
String value = string.split("=")[1].trim();
if (key.contains("Expires")) {

View File

@@ -17,8 +17,10 @@ import com.yutou.biliapi.databases.BiliBiliLoginDatabase;
import com.yutou.biliapi.databases.BiliLiveDatabase;
import com.yutou.biliapi.utils.BiliUserUtils;
import com.yutou.biliapi.utils.BytesUtils;
import com.yutou.bilibili.Tools.Tools;
import com.yutou.common.okhttp.HttpBody;
import com.yutou.common.okhttp.HttpCallback;
import com.yutou.common.utils.ConfigTools;
import com.yutou.common.utils.Log;
import okhttp3.Headers;
import org.java_websocket.client.WebSocketClient;
@@ -77,12 +79,12 @@ public class WebSocketManager {
}
DanmuTask task = new DanmuTask(roomConfig);
roomMap.put(roomConfig, task);
System.out.println("添加websocket任务");
Log.i("添加websocket任务");
executor.execute(task);
}
public void stopRoom(String roomId, boolean isUser) {
LiveRoomConfig roomConfig=new LiveRoomConfig();
LiveRoomConfig roomConfig = new LiveRoomConfig();
roomConfig.setRoomId(new BigInteger(roomId));
if (checkRoom(roomConfig)) {
roomMap.get(roomConfig).close();
@@ -118,7 +120,7 @@ public class WebSocketManager {
@Override
public void onResponse(Headers headers, int code, String status, LiveDanmuInfo response, String rawResponse) {
if (!response.getHostList().isEmpty()) {
LiveDanmuInfo.Host host = response.getHostList().get(0);
LiveDanmuInfo.Host host = response.getHostList().get(new Random().nextInt(response.getHostList().size()));
String url = "wss://" + host.getHost() + ":" + host.getWssPort() + "/sub";
// url="ws://127.0.0.1:8765";
try {
@@ -132,7 +134,7 @@ public class WebSocketManager {
@Override
public void onFailure(Throwable throwable) {
throwable.printStackTrace();
Log.e(throwable);
}
});
}
@@ -150,46 +152,48 @@ public class WebSocketManager {
public WebSocketClientTh(URI serverUri, LiveRoomConfig roomId) {
super(serverUri);
System.out.println("WebSocketClientTh.WebSocketClientTh : " + serverUri);
Log.i("WebSocketClientTh.WebSocketClientTh : " + serverUri);
this.roomConfig = roomId;
liveDatabase = new BiliLiveDatabase(roomConfig);
Brotli4jLoader.ensureAvailability();
heartbeatTask = new HeartbeatTask();
addHeader("User-Agent", ConfigTools.getUserAgent());
connect();
}
@Override
public void onOpen(ServerHandshake serverHandshake) {
heartbeatTask.setSocket(this);
heartbeatTask.sendInitAuthData();
new Timer().schedule(heartbeatTask, 1000, 30000);
System.out.println("WebSocketClientTh.onOpen");
Log.i("WebSocketClientTh.onOpen");
}
@Override
public void onMessage(String s) {
System.out.println("s = " + s);
Log.i("s = " + s);
}
@Override
public void onMessage(ByteBuffer bytes) {
System.out.println("WebSocketClientTh.onMessage: " + roomConfig.getAnchorName());
Log.i("WebSocketClientTh.onMessage: " + roomConfig.getAnchorName());
super.onMessage(bytes);
decompress(bytes.array());
}
@Override
public void onClose(int i, String s, boolean b) {
System.out.println("WebSocketClientTh.onClose");
System.out.println("i = " + i + ", s = " + s + ", b = " + b);
Log.i("WebSocketClientTh.onClose");
Log.i("i = " + i + ", s = " + s + ", b = " + b);
WebSocketManager.getInstance().roomMap.remove(roomConfig);
heartbeatTask.cancel();
}
@Override
public void onError(Exception e) {
System.out.println("WebSocketClientTh.onError");
e.printStackTrace();
Log.i("WebSocketClientTh.onError");
Log.e(e);
WebSocketManager.getInstance().roomMap.remove(roomConfig);
heartbeatTask.cancel();
}
@@ -203,7 +207,7 @@ public class WebSocketManager {
byte[] bytes = new byte[data.length - 16];
WebSocketHeader header = new WebSocketHeader(data);
System.arraycopy(data, header.getHeaderSize(), bytes, 0, data.length - header.getHeaderSize());
// System.out.println("数据大小:" + header.getDataSize() + " 协议:" + header.getAgree() + " 头部大小:" + header.getHeaderSize() + " 命令:" + header.getCmdData());
// Log.i("数据大小:" + header.getDataSize() + " 协议:" + header.getAgree() + " 头部大小:" + header.getHeaderSize() + " 命令:" + header.getCmdData());
switch (header.getAgree()) {
case 0:
case 1:
@@ -231,13 +235,13 @@ public class WebSocketManager {
liveDatabase.addSource(parse);
// Log.i("解压:" + parse);
}
// System.out.println();
// System.out.println();
// Log.i();
// Log.i();
} else {
Log.e(new RuntimeException("解压失败"));
}
} catch (Exception e) {
e.printStackTrace();
Log.e(e);
}
}
@@ -259,7 +263,7 @@ public class WebSocketManager {
outputStream.flush();
socket.send(outputStream.toByteArray());
} catch (Exception e) {
e.printStackTrace();
Log.e(e);
}
}
@@ -282,18 +286,18 @@ public class WebSocketManager {
json.put("key", roomConfig.getLiveInfo().getToken());
byte[] bytes = {0, 16, 0, 1, 0, 0, 0, 7, 0, 0, 0, 1};
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
System.out.println("bytes.length = " + bytes.length);
Log.i("bytes.length = " + bytes.length);
Log.i(json);
outputStream.write(BytesUtils.toLH(json.toString().length() + 16));
outputStream.write(bytes);
outputStream.write(json.toJSONString().getBytes(StandardCharsets.UTF_8));
outputStream.flush();
// BytesUtils.printHex(outputStream.toByteArray());
System.out.println(socket.isOpen());
Log.i(socket.isOpen());
socket.send(outputStream.toByteArray());
} catch (Exception e) {
e.printStackTrace();
Log.e(e);
}
}

View File

@@ -15,20 +15,20 @@ public class BytesUtils {
}
public static void printHex(byte[] byteArray) {
System.out.println("\n\n\n");
Log.i("\n\n\n");
String str = DatatypeConverter.printHexBinary(byteArray);
Log.i(str);
for (int i = 0; i < str.length(); i = i + 4) {
if (i % 32 == 0 && i != 0) {
System.out.println();
Log.i();
}
if (str.length() - i > 4) {
System.out.print(str.substring(i, i + 4) + " ");
} else {
System.out.println(str.substring(i));
Log.i(str.substring(i));
}
}
System.out.println("\n\n\n");
Log.i("\n\n\n");
}
public static byte[] toLH(int n) {
byte[] b = new byte[4];