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

View File

@ -119,6 +119,12 @@
<artifactId>retrofit</artifactId> <artifactId>retrofit</artifactId>
<version>2.11.0</version> <version>2.11.0</version>
</dependency> </dependency>
<!-- https://mvnrepository.com/artifact/org.apache.logging.log4j/log4j-core -->
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-core</artifactId>
<version>2.24.1</version>
</dependency>
</dependencies> </dependencies>
<build> <build>

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

View File

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

View File

@ -4,6 +4,7 @@ import com.alibaba.fastjson2.JSONObject;
import com.alibaba.fastjson2.annotation.JSONField; import com.alibaba.fastjson2.annotation.JSONField;
import com.yutou.biliapi.bean.live.LiveRoomInfo; import com.yutou.biliapi.bean.live.LiveRoomInfo;
import com.yutou.common.databases.AbsDatabasesBean; import com.yutou.common.databases.AbsDatabasesBean;
import com.yutou.common.utils.Log;
import lombok.Data; import lombok.Data;
import lombok.EqualsAndHashCode; import lombok.EqualsAndHashCode;
@ -49,7 +50,7 @@ public class LiveInfoDatabaseBean extends AbsDatabasesBean {
public static void main(String[] args) { public static void main(String[] args) {
List<Field> list = new LiveInfoDatabaseBean().getFields(); List<Field> list = new LiveInfoDatabaseBean().getFields();
for (Field field : list) { 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; package com.yutou.biliapi.bean.websocket;
import com.alibaba.fastjson2.JSONObject; import com.alibaba.fastjson2.JSONObject;
import com.yutou.common.utils.Log;
import lombok.Data; import lombok.Data;
import java.util.ArrayList; import java.util.ArrayList;
@ -27,7 +28,7 @@ public class WebSocketBody {
try { try {
bodyList.add(JSONObject.parseObject(new String(data))); bodyList.add(JSONObject.parseObject(new String(data)));
} catch (Exception e) { } catch (Exception e) {
System.out.println(header + "|" + new String(data)); Log.i(header + "|" + new String(data));
} }
addBody(bytes, offset + header.dataSize); addBody(bytes, offset + header.dataSize);
} }

View File

@ -1,6 +1,7 @@
package com.yutou.biliapi.bean.websocket.live; package com.yutou.biliapi.bean.websocket.live;
import com.alibaba.fastjson2.JSONObject; import com.alibaba.fastjson2.JSONObject;
import com.yutou.common.utils.Log;
import lombok.Data; import lombok.Data;
import lombok.EqualsAndHashCode; import lombok.EqualsAndHashCode;
@ -22,7 +23,7 @@ public class WSDmInteraction extends WSData{
public static void main(String[] args) { 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}}"); 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); WSDmInteraction wsDmInteraction=new WSDmInteraction(json);
System.out.println(wsDmInteraction); Log.i(wsDmInteraction);
} }
public WSDmInteraction(JSONObject json) { public WSDmInteraction(JSONObject json) {
super(json); super(json);

View File

@ -1,6 +1,7 @@
package com.yutou.biliapi.bean.websocket.live; package com.yutou.biliapi.bean.websocket.live;
import com.alibaba.fastjson2.JSONObject; import com.alibaba.fastjson2.JSONObject;
import com.yutou.common.utils.Log;
import lombok.Data; import lombok.Data;
import lombok.EqualsAndHashCode; import lombok.EqualsAndHashCode;
@ -24,7 +25,7 @@ public class WSGuardBuy extends WSData{
public static void main(String[] args) { 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}}"); 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); WSGuardBuy wsguardBuy = new WSGuardBuy(json);
System.out.println(wsguardBuy); Log.i(wsguardBuy);
} }
public WSGuardBuy(JSONObject json) { public WSGuardBuy(JSONObject json) {
super(json); super(json);

View File

@ -1,6 +1,7 @@
package com.yutou.biliapi.bean.websocket.live; package com.yutou.biliapi.bean.websocket.live;
import com.alibaba.fastjson2.JSONObject; import com.alibaba.fastjson2.JSONObject;
import com.yutou.common.utils.Log;
import lombok.Data; import lombok.Data;
import lombok.EqualsAndHashCode; import lombok.EqualsAndHashCode;
@ -25,7 +26,7 @@ public class WSSuperChatMessage extends WSData{
public static void main(String[] args) { 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}"); 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); WSSuperChatMessage message=new WSSuperChatMessage(json);
System.out.println(message); Log.i(message);
} }
public WSSuperChatMessage(JSONObject json) { public WSSuperChatMessage(JSONObject json) {
super(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.AbsDatabasesBean;
import com.yutou.common.databases.SQLiteManager; import com.yutou.common.databases.SQLiteManager;
import com.yutou.common.okhttp.HttpDownloadUtils; import com.yutou.common.okhttp.HttpDownloadUtils;
import com.yutou.common.utils.Log;
import org.apache.poi.ss.usermodel.DataFormat; import org.apache.poi.ss.usermodel.DataFormat;
import java.io.File; import java.io.File;
@ -26,13 +27,12 @@ public class BiliLiveDatabase extends SQLiteManager {
public BiliLiveDatabase(LiveRoomConfig roomConfig, String path) { public BiliLiveDatabase(LiveRoomConfig roomConfig, String path) {
this.config = roomConfig; this.config = roomConfig;
rootPath = new File(path).getParentFile(); rootPath = new File(path).getParentFile();
fileName =path; fileName = path + File.separator + "live.db";
init(); init();
} }
public BiliLiveDatabase(LiveRoomConfig roomConfig) { public BiliLiveDatabase(LiveRoomConfig roomConfig) {
String time = DateUtils.format(new Date().getTime(), DATE_FORMAT_10_DASH); rootPath = new File(roomConfig.getRootPath() + File.separator + roomConfig.getAnchorName());
rootPath = new File(roomConfig.getRootPath() + File.separator + roomConfig.getAnchorName() + File.separator + time + File.separator + roomConfig.getRoomInfo().getTitle());
config = roomConfig; config = roomConfig;
if (!rootPath.exists()) { if (!rootPath.exists()) {
rootPath.mkdirs(); rootPath.mkdirs();
@ -44,7 +44,7 @@ public class BiliLiveDatabase extends SQLiteManager {
@Override @Override
public void init() { public void init() {
super.init(); super.init();
if(config.getRoomInfo()!=null) { if (config.getRoomInfo() != null) {
HttpDownloadUtils.download(new HttpDownloadUtils.Builder().setUrl(config.getRoomInfo().getUserCover()) HttpDownloadUtils.download(new HttpDownloadUtils.Builder().setUrl(config.getRoomInfo().getUserCover())
.setPath(rootPath.getAbsolutePath()) .setPath(rootPath.getAbsolutePath())
.setFileName("poster.jpg")); .setFileName("poster.jpg"));
@ -95,7 +95,7 @@ public class BiliLiveDatabase extends SQLiteManager {
} }
public void addSource(WSData bean) { public void addSource(WSData bean) {
System.out.println("BiliLiveDatabase.addSource"); Log.i("BiliLiveDatabase.addSource");
add(new LiveSourceDatabaseBean(bean)); add(new LiveSourceDatabaseBean(bean));
addData(bean); addData(bean);
} }
@ -137,7 +137,7 @@ public class BiliLiveDatabase extends SQLiteManager {
public static void main(String[] args) { public static void main(String[] args) {
/* List<LiveDanmuDatabaseBean> list = getInstance().get(-1, 1727515148800L, LiveDanmuDatabaseBean.class); /* List<LiveDanmuDatabaseBean> list = getInstance().get(-1, 1727515148800L, LiveDanmuDatabaseBean.class);
for (LiveDanmuDatabaseBean bean : list) { 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.biliapi.bean.login.CheckCookieBean;
import com.yutou.common.inter.IHttpApiCheckCallback; import com.yutou.common.inter.IHttpApiCheckCallback;
import com.yutou.common.okhttp.HttpCallback; import com.yutou.common.okhttp.HttpCallback;
import com.yutou.common.utils.Log;
import com.yutou.common.utils.RSAUtils; import com.yutou.common.utils.RSAUtils;
import okhttp3.Headers; import okhttp3.Headers;
@ -82,7 +83,7 @@ public class BiliCookieManager {
// Convert the encrypted bytes to a Base64-encoded string // Convert the encrypted bytes to a Base64-encoded string
String encrypted = new BigInteger(1, encryptedBytes).toString(16); String encrypted = new BigInteger(1, encryptedBytes).toString(16);
}catch (Exception e){ }catch (Exception e){
e.printStackTrace(); Log.e(e);
} }
} }

View File

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

View File

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

View File

@ -1,5 +1,6 @@
package com.yutou.bilibili.Controllers; package com.yutou.bilibili.Controllers;
import com.yutou.common.utils.FFmpegUtils;
import org.springframework.stereotype.Controller; import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody; import org.springframework.web.bind.annotation.ResponseBody;
@ -9,6 +10,13 @@ public class TestControllers {
@RequestMapping("/root/test") @RequestMapping("/root/test")
@ResponseBody @ResponseBody
public String test(){ public String test(){
FFmpegUtils.killAll();
return "hello world"; return "hello world";
} }
@RequestMapping("/root/kill")
@ResponseBody
public String kill(String roomId){
FFmpegUtils.kill(roomId);
return FFmpegUtils.check(roomId)+"";
}
} }

View File

@ -6,6 +6,7 @@ import com.yutou.bilibili.Tools.Tools;
import com.yutou.bilibili.datas.ResultData; import com.yutou.bilibili.datas.ResultData;
import com.yutou.bilibili.datas.VideoFilePath; import com.yutou.bilibili.datas.VideoFilePath;
import com.yutou.bilibili.services.LiveVideoService; import com.yutou.bilibili.services.LiveVideoService;
import com.yutou.common.utils.Log;
import jakarta.annotation.Resource; import jakarta.annotation.Resource;
import org.springframework.core.io.FileSystemResource; import org.springframework.core.io.FileSystemResource;
import org.springframework.http.ResponseEntity; import org.springframework.http.ResponseEntity;
@ -39,7 +40,7 @@ public class VideoFileController {
@ResponseBody @ResponseBody
public ResponseEntity<FileSystemResource> getFile(@PathVariable String base64) { public ResponseEntity<FileSystemResource> getFile(@PathVariable String base64) {
File file = FileServerUtils.toFile(base64); File file = FileServerUtils.toFile(base64);
System.out.println(file.getAbsolutePath()); Log.i(file.getAbsolutePath());
return Tools.getFile(file); return Tools.getFile(file);
} }

View File

@ -1,5 +1,7 @@
package com.yutou.bilibili.Tools; package com.yutou.bilibili.Tools;
import com.yutou.common.utils.Log;
import javax.crypto.Cipher; import javax.crypto.Cipher;
import javax.crypto.KeyGenerator; import javax.crypto.KeyGenerator;
import javax.crypto.spec.SecretKeySpec; import javax.crypto.spec.SecretKeySpec;
@ -24,7 +26,7 @@ public class AESTools {
byte[] bytes=cipher.doFinal(value.getBytes(StandardCharsets.UTF_8)); byte[] bytes=cipher.doFinal(value.getBytes(StandardCharsets.UTF_8));
return new String(Base64.getEncoder().encode(bytes)); return new String(Base64.getEncoder().encode(bytes));
} catch (Exception e) { } catch (Exception e) {
e.printStackTrace(); Log.e(e);
} }
return null; return null;
} }
@ -44,7 +46,7 @@ public class AESTools {
byte[] bytes=cipher.doFinal(encodeBytes); byte[] bytes=cipher.doFinal(encodeBytes);
return new String(bytes); return new String(bytes);
} catch (Exception e) { } catch (Exception e) {
e.printStackTrace(); Log.e(e);
} }
return null; return null;
} }

View File

@ -1,6 +1,7 @@
package com.yutou.bilibili.Tools; package com.yutou.bilibili.Tools;
import com.yutou.bilibili.services.SystemService; import com.yutou.bilibili.services.SystemService;
import com.yutou.common.utils.FFmpegUtils;
import com.yutou.common.utils.Log; import com.yutou.common.utils.Log;
import jakarta.annotation.Resource; import jakarta.annotation.Resource;
import org.springframework.context.ApplicationListener; import org.springframework.context.ApplicationListener;
@ -15,5 +16,6 @@ public class ApplicationClose implements ApplicationListener<ContextClosedEvent>
public void onApplicationEvent(ContextClosedEvent contextClosedEvent) { public void onApplicationEvent(ContextClosedEvent contextClosedEvent) {
Log.i("服务结束"); Log.i("服务结束");
systemConfigService.stop(); systemConfigService.stop();
FFmpegUtils.killAll();
} }
} }

View File

@ -1,6 +1,7 @@
package com.yutou.bilibili.Tools; package com.yutou.bilibili.Tools;
import com.yutou.bilibili.datas.DanmuData; import com.yutou.bilibili.datas.DanmuData;
import com.yutou.common.utils.Log;
import java.io.File; import java.io.File;
import java.io.FileWriter; import java.io.FileWriter;
@ -75,7 +76,7 @@ public class AssTools {
* @return 存储结果 * @return 存储结果
*/ */
public boolean saveDanmu(String savePath) { public boolean saveDanmu(String savePath) {
System.out.println("savePath = " + savePath); Log.i("savePath = " + savePath);
File file = new File(savePath); File file = new File(savePath);
try { try {
if (file.exists()) { if (file.exists()) {
@ -97,7 +98,7 @@ public class AssTools {
writer.close(); writer.close();
return true; return true;
} catch (IOException e) { } catch (IOException e) {
e.printStackTrace(); Log.e(e);
} }
return false; return false;
} }

View File

@ -42,7 +42,7 @@ public class FFmpegUtils {
file.getAbsolutePath(), file.getAbsolutePath(),
out.getAbsolutePath() + File.separator + file.getName()); out.getAbsolutePath() + File.separator + file.getName());
Log.i(exec); Log.i(exec);
Process process= AppTools.exec(exec); Process process= ProcessUtils.exec(exec);
InputStream inputStream = process.getErrorStream(); InputStream inputStream = process.getErrorStream();
byte[] bytes = new byte[1024]; byte[] bytes = new byte[1024];
while (inputStream.read(bytes) > -1) { while (inputStream.read(bytes) > -1) {

View File

@ -0,0 +1,82 @@
package com.yutou.bilibili.Tools;
import com.alibaba.fastjson2.JSONObject;
import com.yutou.biliapi.bean.live.LiveRoomConfig;
import com.yutou.biliapi.bean.live.LiveRoomInfo;
import com.yutou.biliapi.bean.live.database.LiveVideoDatabaseBean;
import com.yutou.biliapi.databases.BiliLiveDatabase;
import org.w3c.dom.CDATASection;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Text;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
import java.io.File;
public class LiveInfoNfoTools {
public static void saveLiveInfoNfo(LiveRoomInfo info, String path,String xmlName) {
try {
LiveRoomConfig config = LiveRoomConfig.buildConfig(info.getRoomId().toString());
DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance();
DocumentBuilder dBuilder = null;
dBuilder = dbFactory.newDocumentBuilder();
Document doc = dBuilder.newDocument();
Element movie = doc.createElement("movie");
Element plot = doc.createElement("plot");
CDATASection section = doc.createCDATASection(info.getDescription());
plot.appendChild(section);
movie.appendChild(plot);
Element title = doc.createElement("title");
title.setTextContent(info.getTitle());
movie.appendChild(title);
Element actor = doc.createElement("actor");
Element name = doc.createElement("name");
Element role = doc.createElement("role");
name.setTextContent("UID:" + info.getUid().toString());
role.setTextContent(config.getAnchorName());
actor.appendChild(name);
actor.appendChild(role);
movie.appendChild(actor);
Element year = doc.createElement("year");
year.setTextContent(info.getLiveTime().split("-")[0]);
movie.appendChild(year);
Element aired = doc.createElement("aired");
aired.setTextContent(info.getLiveTime().split(" ")[0]);
movie.appendChild(aired);
movie.appendChild(createTag(doc,info.getParentAreaName()));
movie.appendChild(createTag(doc,info.getAreaName()));
doc.appendChild(movie);
TransformerFactory transformerFactory = TransformerFactory.newInstance();
Transformer transformer = transformerFactory.newTransformer();
DOMSource source = new DOMSource(doc);
StreamResult result = new StreamResult(new File(path, xmlName));
transformer.transform(source, result);
} catch (Exception e) {
e.printStackTrace();
}
}
private static Element createTag(Document doc,String tag){
Element genre = doc.createElement("genre");
genre.setTextContent(tag);
return genre;
}
public static void main(String[] args) {
}
}

View File

@ -0,0 +1,71 @@
package com.yutou.bilibili.Tools;
import com.yutou.common.utils.AppTools;
import java.io.BufferedReader;
import java.io.InputStreamReader;
public class ProcessUtils {
public static boolean isRuntimeSystemOfWindow(){
return System.getProperty ("os.name").contains("Windows");
}
public static void killProcess(Long pid) throws Exception {
if(pid==null) {
return;
}
if (isRuntimeSystemOfWindow()) {
// 对于 Windows 系统
Process process = exec("taskkill /F /PID " + pid);
process.waitFor();
} else {
// 对于 Linux macOS 系统
Process process = exec("kill -9 " + pid);
process.waitFor();
}
}
public static boolean isProcessRunning(Long pid) throws Exception {
if(pid==null) {
return false;
}
String command;
if (isRuntimeSystemOfWindow()) {
// Windows 操作系统
command = "tasklist /FI \"PID eq " + pid + "\"";
} else {
// Unix/Linux 操作系统
command = "ps -p " + pid;
}
Process process = exec(command);
BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream()));
String line;
while ((line = reader.readLine()) != null) {
if (line.contains(Long.toString(pid))) {
return true;
}
}
return false;
}
public static Process exec(String exec)throws Exception{
if(isRuntimeSystemOfWindow()) {
return Runtime.getRuntime().exec(new String[]{
"cmd",
"/c",
exec
}
);
}else{
return Runtime.getRuntime().exec(new String[]{
"sh",
"-c",
exec
}
);
}
}
public static void main(String[] args) throws Exception {
}
}

View File

@ -15,7 +15,7 @@ import java.util.List;
@Service @Service
public class LiveConfigService { public class LiveConfigService {
BiliLiveConfigDatabase database=new BiliLiveConfigDatabase(); BiliLiveConfigDatabase database = new BiliLiveConfigDatabase();
public LiveConfigDatabaseBean addConfig(String url, LiveConfigDatabaseBean bean) { public LiveConfigDatabaseBean addConfig(String url, LiveConfigDatabaseBean bean) {
if (!StringUtils.hasText(url)) { if (!StringUtils.hasText(url)) {
@ -30,6 +30,7 @@ public class LiveConfigService {
LiveRoomInfo body = BiliLiveNetApiManager.getInstance().getApi(null).getRoomInfo(String.valueOf(bean.getRoomId())).execute().body().getData(); LiveRoomInfo body = BiliLiveNetApiManager.getInstance().getApi(null).getRoomInfo(String.valueOf(bean.getRoomId())).execute().body().getData();
MasterInfoBean infoBean = BiliLiveNetApiManager.getInstance().getApi(null).getMasterInfo(String.valueOf(body.getUid())).execute().body().getData(); MasterInfoBean infoBean = BiliLiveNetApiManager.getInstance().getApi(null).getMasterInfo(String.valueOf(body.getUid())).execute().body().getData();
bean.setAnchorUid(body.getUid()); bean.setAnchorUid(body.getUid());
bean.setRoomId(body.getRoomId());
bean.setAnchorFace(infoBean.getInfo().getFace()); bean.setAnchorFace(infoBean.getInfo().getFace());
bean.setAnchorName(infoBean.getInfo().getUname()); bean.setAnchorName(infoBean.getInfo().getUname());
database.setConfig(bean); database.setConfig(bean);

View File

@ -12,6 +12,7 @@ import com.yutou.bilibili.Tools.AssTools;
import com.yutou.bilibili.Tools.DateFormatUtils; import com.yutou.bilibili.Tools.DateFormatUtils;
import com.yutou.bilibili.Tools.Tools; import com.yutou.bilibili.Tools.Tools;
import com.yutou.common.utils.FFmpegUtils; import com.yutou.common.utils.FFmpegUtils;
import com.yutou.common.utils.Log;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import java.io.File; import java.io.File;
@ -34,9 +35,6 @@ public class LiveDanmuService {
} }
private BiliLiveDatabase getDatabase(String roomId, File file) {
return new BiliLiveDatabase(LiveRoomConfig.buildConfig(roomId), file.getParent() + File.separator + "live.db");
}
public List<File> getDanmuFileList(String roomId) { public List<File> getDanmuFileList(String roomId) {
BiliLiveConfigDatabase configDatabase=new BiliLiveConfigDatabase(); BiliLiveConfigDatabase configDatabase=new BiliLiveConfigDatabase();
LiveConfigDatabaseBean bean = configDatabase.getConfig(new BigInteger(roomId)); LiveConfigDatabaseBean bean = configDatabase.getConfig(new BigInteger(roomId));
@ -47,12 +45,12 @@ public class LiveDanmuService {
public void saveDanmuXML(LiveVideoDatabaseBean videoDatabaseBean, BiliLiveDatabase database) { public void saveDanmuXML(LiveVideoDatabaseBean videoDatabaseBean, BiliLiveDatabase database) {
File videoFile = new File(videoDatabaseBean.getPath()); File videoFile = new File(videoDatabaseBean.getPath());
long videoTime = FFmpegUtils.getVideoTime(videoFile) + videoDatabaseBean.getStartTime().getTime(); long videoTime = FFmpegUtils.getVideoTime(videoFile) + videoDatabaseBean.getStartTime().getTime();
System.out.println("开始时间:" + videoDatabaseBean.getStartTime().getTime()); Log.i("开始时间:" + videoDatabaseBean.getStartTime().getTime());
System.out.println("结束时间:" + videoTime); Log.i("结束时间:" + videoTime);
String startTime = DateFormatUtils.format(videoDatabaseBean.getStartTime()); String startTime = DateFormatUtils.format(videoDatabaseBean.getStartTime());
String endTime = DateFormatUtils.format(videoTime); String endTime = DateFormatUtils.format(videoTime);
List<LiveDanmuDatabaseBean> danmus = database.getOfTime(startTime, endTime, LiveDanmuDatabaseBean.class); List<LiveDanmuDatabaseBean> danmus = database.getOfTime(startTime, endTime, LiveDanmuDatabaseBean.class);
System.out.println("弹幕数量:" + danmus.size()); Log.i("弹幕数量:" + danmus.size());
AssTools assTools = new AssTools(videoFile.getName().replace(".flv", ""), videoDatabaseBean.getStartTime()); AssTools assTools = new AssTools(videoFile.getName().replace(".flv", ""), videoDatabaseBean.getStartTime());
for (LiveDanmuDatabaseBean dm : danmus) { for (LiveDanmuDatabaseBean dm : danmus) {
assTools.addDanmu(dm.createDanmuData()); assTools.addDanmu(dm.createDanmuData());
@ -74,7 +72,7 @@ public class LiveDanmuService {
LiveDanmuService service = new LiveDanmuService(); LiveDanmuService service = new LiveDanmuService();
List<File> files = service.getDanmuFileList("22047448"); List<File> files = service.getDanmuFileList("22047448");
for (File file : files) { for (File file : files) {
System.out.println(file); Log.i(file);
} }
} }

View File

@ -21,6 +21,7 @@ import com.yutou.biliapi.net.BiliLiveNetApiManager;
import com.yutou.biliapi.net.WebSocketManager; import com.yutou.biliapi.net.WebSocketManager;
import com.yutou.bilibili.Tools.DateFormatUtils; import com.yutou.bilibili.Tools.DateFormatUtils;
import com.yutou.bilibili.Tools.FileServerUtils; import com.yutou.bilibili.Tools.FileServerUtils;
import com.yutou.bilibili.Tools.LiveInfoNfoTools;
import com.yutou.bilibili.Tools.Tools; import com.yutou.bilibili.Tools.Tools;
import com.yutou.bilibili.datas.VideoFilePath; import com.yutou.bilibili.datas.VideoFilePath;
import com.yutou.bilibili.interfaces.DownloadInterface; import com.yutou.bilibili.interfaces.DownloadInterface;
@ -28,6 +29,7 @@ import com.yutou.common.okhttp.HttpCallback;
import com.yutou.common.okhttp.HttpDownloadUtils; import com.yutou.common.okhttp.HttpDownloadUtils;
import com.yutou.common.utils.ConfigTools; import com.yutou.common.utils.ConfigTools;
import com.yutou.common.utils.FFmpegUtils; import com.yutou.common.utils.FFmpegUtils;
import com.yutou.common.utils.Log;
import okhttp3.Headers; import okhttp3.Headers;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils; import org.springframework.util.StringUtils;
@ -50,7 +52,7 @@ public class LiveVideoService {
public LiveVideoService() { public LiveVideoService() {
System.out.println("初始化下载服务"); Log.i("初始化下载服务");
executor = new ThreadPoolExecutor(2, 4, Long.MAX_VALUE, TimeUnit.SECONDS, new ArrayBlockingQueue<Runnable>(100)); executor = new ThreadPoolExecutor(2, 4, Long.MAX_VALUE, TimeUnit.SECONDS, new ArrayBlockingQueue<Runnable>(100));
} }
@ -64,7 +66,7 @@ public class LiveVideoService {
if (liveVideoMap.containsKey(bean)) { if (liveVideoMap.containsKey(bean)) {
return; return;
} }
System.out.println("添加下载任务:" + liveVideoMap.keySet().size()); Log.i("添加下载任务:" + liveVideoMap.keySet().size());
liveVideoMap.put(bean, null); liveVideoMap.put(bean, null);
BiliLiveNetApiManager.getInstance().getApi(bean.getRecordUid()).getRoomInfo(bean.getRoomId().toString()).enqueue(new HttpCallback<LiveRoomInfo>() { BiliLiveNetApiManager.getInstance().getApi(bean.getRecordUid()).getRoomInfo(bean.getRoomId().toString()).enqueue(new HttpCallback<LiveRoomInfo>() {
@Override @Override
@ -75,14 +77,14 @@ public class LiveVideoService {
liveVideoMap.put(bean, task); liveVideoMap.put(bean, task);
} else { } else {
liveVideoMap.remove(bean); liveVideoMap.remove(bean);
System.out.println("移除下载"); Log.i("移除下载");
} }
} }
@Override @Override
public void onFailure(Throwable throwable) { public void onFailure(Throwable throwable) {
liveVideoMap.remove(bean); liveVideoMap.remove(bean);
System.out.println("移除下载"); Log.i("移除下载");
} }
}); });
@ -97,7 +99,7 @@ public class LiveVideoService {
if (entry.getKey().getRoomId().toString().equals(roomId)) { if (entry.getKey().getRoomId().toString().equals(roomId)) {
entry.getValue().isDownload = false; entry.getValue().isDownload = false;
liveVideoMap.remove(entry.getKey()); liveVideoMap.remove(entry.getKey());
System.out.println("移除下载"); Log.i("移除下载");
break; break;
} }
} }
@ -130,6 +132,7 @@ public class LiveVideoService {
boolean isDownload = true; boolean isDownload = true;
LiveApi api; LiveApi api;
String savePath; String savePath;
File rootPath;
LiveConfigDatabaseBean config; LiveConfigDatabaseBean config;
BiliLiveDatabase database; BiliLiveDatabase database;
LiveVideoDatabaseBean videoDatabaseBean; LiveVideoDatabaseBean videoDatabaseBean;
@ -146,10 +149,13 @@ public class LiveVideoService {
public void run() { public void run() {
if (roomInfo.getLiveStatus() == 1) { if (roomInfo.getLiveStatus() == 1) {
String time = DateUtils.format(new Date().getTime(), DATE_FORMAT_10_DASH); String time = DateUtils.format(new Date().getTime(), DATE_FORMAT_10_DASH);
savePath = new File(bean.getRecordPath() + File.separator + bean.getAnchorName() + File.separator + time + File.separator + roomInfo.getTitle()).getAbsolutePath(); rootPath = new File(bean.getRecordPath() + File.separator + bean.getAnchorName() + File.separator + time + File.separator + roomInfo.getTitle());
savePath += File.separator + "[" + savePath = rootPath.getAbsolutePath() + File.separator + "[" +
DateUtils.format(new Date(), DateUtils.format(new Date(),
"yyyy-MM-dd HH-mm-ss") + "]" + roomInfo.getTitle() + ".flv"; "yyyy-MM-dd HH-mm-ss") + "]" + roomInfo.getTitle() + ".flv";
if (!rootPath.exists()) {
rootPath.mkdirs();
}
record(bean, roomInfo); record(bean, roomInfo);
} else { } else {
stop(); stop();
@ -157,6 +163,7 @@ public class LiveVideoService {
} }
private void stop() { private void stop() {
liveVideoMap.remove(bean);
api.getRoomInfo(config.getRoomId().toString()).enqueue(new HttpCallback<LiveRoomInfo>() { api.getRoomInfo(config.getRoomId().toString()).enqueue(new HttpCallback<LiveRoomInfo>() {
@Override @Override
public void onResponse(Headers headers, int code, String status, LiveRoomInfo response, String rawResponse) { public void onResponse(Headers headers, int code, String status, LiveRoomInfo response, String rawResponse) {
@ -186,6 +193,11 @@ public class LiveVideoService {
config.setRoomInfo(roomInfo); config.setRoomInfo(roomInfo);
config.setRootPath(bean.getRecordPath()); config.setRootPath(bean.getRecordPath());
database = new BiliLiveDatabase(config); database = new BiliLiveDatabase(config);
HttpDownloadUtils.download(new HttpDownloadUtils.Builder().setUrl(roomInfo.getKeyframe())
.setPath(rootPath.getAbsolutePath())
.setFileName("poster.jpg"));
LiveInfoNfoTools.saveLiveInfoNfo(roomInfo,rootPath.getAbsolutePath(),new File(savePath).getName().replace(".flv",".nfo"));
saveLiveInfo(roomInfo);
api.getLiveRoomPlayInfo( api.getLiveRoomPlayInfo(
bean.getRoomId().toString(), bean.getRoomId().toString(),
LiveProtocol.getAll(), LiveProtocol.getAll(),
@ -206,7 +218,7 @@ public class LiveVideoService {
@Override @Override
public void onFailure(Throwable throwable) { public void onFailure(Throwable throwable) {
throwable.printStackTrace(); Log.e(throwable);
} }
}); });
} }
@ -258,8 +270,8 @@ public class LiveVideoService {
.withNotSymbolParam("-threads", "8") .withNotSymbolParam("-threads", "8")
.withNotSymbolParam("-c:v", "copy") .withNotSymbolParam("-c:v", "copy")
.withNotSymbolParam("-y", "") .withNotSymbolParam("-y", "")
.build(ffmpegPath, url, savePath); .build(config.getRoomId().toString(),ffmpegPath, url, savePath);
System.out.println(command); Log.i(command.getCommand());
try { try {
command.start(new DownloadInterface() { command.start(new DownloadInterface() {
@Override @Override
@ -279,7 +291,7 @@ public class LiveVideoService {
@Override @Override
public void onDownload(File file) { public void onDownload(File file) {
super.onDownload(file); super.onDownload(file);
System.err.println("下载完成 "); Log.e("下载完成 ");
stop(); stop();
} }
}); });
@ -299,6 +311,10 @@ public class LiveVideoService {
} }
} }
private void saveLiveInfo(LiveRoomInfo roomInfo) {
}
public List<VideoFilePath> getAllVideoPath() { public List<VideoFilePath> getAllVideoPath() {
BiliLiveConfigDatabase configDatabase = new BiliLiveConfigDatabase(); BiliLiveConfigDatabase configDatabase = new BiliLiveConfigDatabase();
List<LiveConfigDatabaseBean> list = configDatabase.getAllConfig(); List<LiveConfigDatabaseBean> list = configDatabase.getAllConfig();
@ -323,21 +339,12 @@ public class LiveVideoService {
File recordDir = new File(recordPath); File recordDir = new File(recordPath);
if (recordDir.exists()) { if (recordDir.exists()) {
List<File> files = Tools.scanFile(recordDir).stream() BiliLiveDatabase database = new BiliLiveDatabase(LiveRoomConfig.buildConfig(configBean.getRoomId().toString()), recordDir.getAbsolutePath());
.filter(file -> "live.db".equals(file.getName())) VideoFilePath path = createVideoRootFilePath(configBean, recordDir);
.toList(); List<LiveVideoDatabaseBean> infos = database.getLiveInfos();
database.close();
if (!files.isEmpty()) { path.setChildren(getVideoInfo(infos));
for (File db : files) { filePathList.add(path);
VideoFilePath path = createVideoRootFilePath(configBean, db);
BiliLiveDatabase database = new BiliLiveDatabase(LiveRoomConfig.buildConfig(configBean.getRoomId().toString()), db.getAbsolutePath());
List<LiveVideoDatabaseBean> infos = database.getLiveInfos();
database.close();
path.setChildren(getVideoInfo(infos));
filePathList.add(path);
}
}
} }
return filePathList; return filePathList;
} }
@ -360,7 +367,7 @@ public class LiveVideoService {
path.setRoomId(roomInfo.getRoomId().toString()); path.setRoomId(roomInfo.getRoomId().toString());
path.setName(roomInfo.getTitle()); path.setName(roomInfo.getTitle());
path.setPath(DateFormatUtils.format(bean.getSql_time())); path.setPath(DateFormatUtils.format(bean.getSql_time()));
path.setCover(FileServerUtils.toUrl(new File(bean.getPath()).getParent() + File.separator + "poster.jpg")); path.setCover(roomInfo.getKeyframe());
path.setParent(false); path.setParent(false);
path.setChildren(null); path.setChildren(null);
filePathList.add(path); filePathList.add(path);
@ -371,7 +378,7 @@ public class LiveVideoService {
public static void main(String[] args) { public static void main(String[] args) {
LiveVideoService service = new LiveVideoService(); LiveVideoService service = new LiveVideoService();
List<VideoFilePath> path = service.getAllVideoPath(); List<VideoFilePath> path = service.getAllVideoPath();
System.out.println("path.size() = " + path.size()); Log.i("path.size() = " + path.size());
System.out.println(JSONArray.toJSONString(path)); Log.i(JSONArray.toJSONString(path));
} }
} }

View File

@ -10,6 +10,7 @@ import com.yutou.biliapi.net.WebSocketManager;
import com.yutou.bilibili.databases.SystemConfigDatabases; import com.yutou.bilibili.databases.SystemConfigDatabases;
import com.yutou.bilibili.datas.SystemConfigDatabaseBean; import com.yutou.bilibili.datas.SystemConfigDatabaseBean;
import com.yutou.common.okhttp.HttpBody; import com.yutou.common.okhttp.HttpBody;
import com.yutou.common.utils.Log;
import jakarta.annotation.Resource; import jakarta.annotation.Resource;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils; import org.springframework.util.StringUtils;
@ -48,21 +49,26 @@ public class SystemService {
if (timer == null) { if (timer == null) {
timer = Executors.newScheduledThreadPool(1); timer = Executors.newScheduledThreadPool(1);
} }
System.out.println("执行任务"); Log.i("执行任务");
if (scheduled != null) { if (scheduled != null) {
scheduled.cancel(true); scheduled.cancel(true);
} }
scheduled = timer.scheduleAtFixedRate(() -> { scheduled = timer.scheduleAtFixedRate(() -> {
List<LiveConfigDatabaseBean> list = liveConfigDatabase.getAllConfig(); List<LiveConfigDatabaseBean> list = liveConfigDatabase.getAllConfig();
System.out.println("循环任务:" + list.size()); Log.i("循环任务:" + list.size());
for (LiveConfigDatabaseBean bean : list) { for (LiveConfigDatabaseBean bean : list) {
if (bean.isRecordDanmu() && bean.checkRecordDanmuTime()) { try {
recordDanmu(bean); if (bean.isRecordDanmu() && bean.checkRecordDanmuTime()) {
} recordDanmu(bean);
if (bean.isRecordLive() && bean.checkRecordLiveTime()) { }
recordVideo(bean); if (bean.isRecordLive() && bean.checkRecordLiveTime()) {
recordVideo(bean);
}
} catch (Exception e) {
Log.e(e);
} }
} }
}, 0, getLoopTimer(), TimeUnit.MILLISECONDS); }, 0, getLoopTimer(), TimeUnit.MILLISECONDS);
} }
@ -73,7 +79,7 @@ public class SystemService {
// 录制弹幕 // 录制弹幕
private void recordDanmu(LiveConfigDatabaseBean bean) { private void recordDanmu(LiveConfigDatabaseBean bean) {
danmuService.start(bean.getRoomId().toString(),false); danmuService.start(bean.getRoomId().toString(), false);
} }
// 录制视频 // 录制视频
@ -83,10 +89,10 @@ public class SystemService {
public static void main(String[] args) throws InterruptedException { public static void main(String[] args) throws InterruptedException {
SystemService service = new SystemService(); SystemService service = new SystemService();
System.out.println(new Date()); Log.i(new Date());
service.start(); service.start();
Thread.sleep(15000); Thread.sleep(15000);
System.out.println(new Date()); Log.i(new Date());
service.start(); service.start();
} }

View File

@ -40,7 +40,7 @@ public class AbsDatabasesBean {
json.put(key,""); json.put(key,"");
} }
} }
//System.out.println("创建" + tableName + "表 json:" + json); //Log.i("创建" + tableName + "表 json:" + json);
return json; return json;
} }

View File

@ -146,8 +146,8 @@ public abstract class SQLiteManager {
statement.execute(); statement.execute();
statement.close(); statement.close();
} catch (SQLException e) { } catch (SQLException e) {
e.printStackTrace(); Log.e(e);
System.err.println(sb); Log.e(sb);
throw new RuntimeException(e); throw new RuntimeException(e);
} }
} }
@ -177,7 +177,7 @@ public abstract class SQLiteManager {
statement.executeUpdate(sb.toString()); statement.executeUpdate(sb.toString());
statement.close(); statement.close();
} catch (Exception e) { } catch (Exception e) {
e.printStackTrace(); Log.e(e);
throw new RuntimeException(e); throw new RuntimeException(e);
} }
@ -219,7 +219,7 @@ public abstract class SQLiteManager {
resultSet.close(); resultSet.close();
statement.closeOnCompletion(); statement.closeOnCompletion();
} catch (Exception e) { } catch (Exception e) {
e.printStackTrace(); Log.e(e);
throw new RuntimeException(e); throw new RuntimeException(e);
} }
return list; return list;
@ -236,7 +236,7 @@ public abstract class SQLiteManager {
statement.close(); statement.close();
return ret != 0; return ret != 0;
} catch (Exception e) { } catch (Exception e) {
e.printStackTrace(); Log.e(e);
throw new RuntimeException(e); throw new RuntimeException(e);
} }
} }
@ -285,7 +285,7 @@ public abstract class SQLiteManager {
sql.append(builder.toString()); sql.append(builder.toString());
} }
sql.append(");"); sql.append(");");
System.out.println("创建表 > " + sql.toString()); Log.i("创建表 > " + sql.toString());
statement.execute(sql.toString().replace(",);", ");")); statement.execute(sql.toString().replace(",);", ");"));
statement.closeOnCompletion(); statement.closeOnCompletion();
} catch (Exception e) { } catch (Exception e) {
@ -327,7 +327,7 @@ public abstract class SQLiteManager {
bean.setRecordLive(true); bean.setRecordLive(true);
bean.setKeywordList(List.of("111", "22")); bean.setKeywordList(List.of("111", "22"));
JSONObject json = bean.toJson(); JSONObject json = bean.toJson();
System.out.println("json = " + json); Log.i("json = " + json);
} }
@Data @Data

View File

@ -1,5 +1,6 @@
package com.yutou.common.okhttp; package com.yutou.common.okhttp;
import com.yutou.common.utils.Log;
import okhttp3.Headers; import okhttp3.Headers;
import okhttp3.HttpUrl; import okhttp3.HttpUrl;
import retrofit2.Call; import retrofit2.Call;
@ -45,12 +46,12 @@ public abstract class FileCallback<T> implements Callback<FileBody<T>> {
@Override @Override
public void run() { public void run() {
try { try {
System.out.println("开始下载"); Log.i("开始下载");
File file = new File(savePath); File file = new File(savePath);
onStart(bean); onStart(bean);
if (!file.exists()) { if (!file.exists()) {
boolean mkdirs = file.getParentFile().mkdirs(); boolean mkdirs = file.getParentFile().mkdirs();
System.out.println("mkdirs = " + mkdirs); Log.i("mkdirs = " + mkdirs);
} }
FileOutputStream outputStream = new FileOutputStream(file); FileOutputStream outputStream = new FileOutputStream(file);
int len; int len;
@ -64,17 +65,17 @@ public abstract class FileCallback<T> implements Callback<FileBody<T>> {
outputStream.flush(); outputStream.flush();
isDownload = onDownload(headers, bean, total, available); isDownload = onDownload(headers, bean, total, available);
} }
System.out.println("下载完成"); Log.i("下载完成");
outputStream.close(); outputStream.close();
} catch (Exception e) { } catch (Exception e) {
e.printStackTrace(); Log.e(e);
onFailure(bean,e); onFailure(bean,e);
} finally { } finally {
onFinish(bean); onFinish(bean);
try { try {
inputStream.close(); inputStream.close();
} catch (IOException e) { } catch (IOException e) {
e.printStackTrace(); Log.e(e);
} }
} }
@ -96,7 +97,7 @@ public abstract class FileCallback<T> implements Callback<FileBody<T>> {
try { try {
executor.execute(new DownloadTask(bean, response.headers(), call.request().url(), response.body().getInputStream())); executor.execute(new DownloadTask(bean, response.headers(), call.request().url(), response.body().getInputStream()));
} catch (Exception e) { } catch (Exception e) {
e.printStackTrace(); Log.e(e);
onFailure(bean,e); onFailure(bean,e);
call.cancel(); call.cancel();
} }

View File

@ -68,7 +68,7 @@ public class HttpDownloadUtils {
} }
fileOutputStream.flush(); fileOutputStream.flush();
} catch (IOException e) { } catch (IOException e) {
Log.getLogger("download").log(Level.FINE, "download error:" + builder.url, e); Log.e("download error:" + builder.url, e);
} finally { } finally {
if (builder.downloadInterface != null) { if (builder.downloadInterface != null) {
builder.downloadInterface.onDownload(target); builder.downloadInterface.onDownload(target);

View File

@ -2,6 +2,7 @@ package com.yutou.common.okhttp;
import com.alibaba.fastjson2.JSONObject; import com.alibaba.fastjson2.JSONObject;
import com.yutou.common.utils.Log;
import okhttp3.*; import okhttp3.*;
import java.net.URLEncoder; import java.net.URLEncoder;
@ -46,7 +47,7 @@ public class PostRequestParams implements IRequestParam {
try { try {
string.append("&").append(key).append("=").append(URLEncoder.encode(json.getString(key), "UTF-8")); string.append("&").append(key).append("=").append(URLEncoder.encode(json.getString(key), "UTF-8"));
} catch (Exception e) { } catch (Exception e) {
e.printStackTrace(); Log.e(e);
try { try {
string.append("&").append(URLEncoder.encode(key, "UTF-8")).append("="); string.append("&").append(URLEncoder.encode(key, "UTF-8")).append("=");
// string += "&" + key + "="; // string += "&" + key + "=";

View File

@ -6,6 +6,7 @@ import com.google.gson.Gson;
import com.google.gson.TypeAdapter; import com.google.gson.TypeAdapter;
import com.yutou.common.okhttp.FileBody; import com.yutou.common.okhttp.FileBody;
import com.yutou.common.okhttp.HttpBody; import com.yutou.common.okhttp.HttpBody;
import com.yutou.common.utils.Log;
import okhttp3.ResponseBody; import okhttp3.ResponseBody;
import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.Nullable;
import retrofit2.Converter; import retrofit2.Converter;
@ -36,7 +37,7 @@ public class JsonResponseBodyConverter<T> implements Converter<ResponseBody, T>
body.setSrc(string); body.setSrc(string);
return (T) body; return (T) body;
} catch (Exception e) { } catch (Exception e) {
e.printStackTrace(); Log.e(e);
body = new HttpBody(); body = new HttpBody();
body.setSrc(string); body.setSrc(string);
} }

View File

@ -259,10 +259,10 @@ public class AppTools {
File srcFile = new File(srcFileName); File srcFile = new File(srcFileName);
// 判断源文件是否存在 // 判断源文件是否存在
if (!srcFile.exists()) { if (!srcFile.exists()) {
System.err.println("源文件不存在:"+srcFile.getAbsolutePath()+" > "+destFileName); Log.e("源文件不存在:"+srcFile.getAbsolutePath()+" > "+destFileName);
return false; return false;
} else if (!srcFile.isFile()) { } else if (!srcFile.isFile()) {
System.err.println("源文件是目录:"+srcFile.getAbsolutePath()); Log.e("源文件是目录:"+srcFile.getAbsolutePath());
return false; return false;
} }
@ -273,7 +273,7 @@ public class AppTools {
// 目标文件所在目录不存在 // 目标文件所在目录不存在
if (!destFile.mkdirs()) { if (!destFile.mkdirs()) {
// 复制文件失败创建目标文件所在目录失败 // 复制文件失败创建目标文件所在目录失败
System.err.println("创建文件夹失败:"+destFile.getAbsolutePath()); Log.e("创建文件夹失败:"+destFile.getAbsolutePath());
return false; return false;
} }
@ -311,25 +311,4 @@ public class AppTools {
} }
} }
public static boolean isRuntimeSystemOfWindow(){
return System.getProperty ("os.name").contains("Windows");
}
public static Process exec(String exec)throws Exception{
if(AppTools.isRuntimeSystemOfWindow()) {
return Runtime.getRuntime().exec(new String[]{
"cmd",
"/c",
exec
}
);
}else{
return Runtime.getRuntime().exec(new String[]{
"sh",
"-c",
exec
}
);
}
}
} }

View File

@ -25,7 +25,7 @@ public class Base64Tools {
byte[] fileContent = Files.readAllBytes(Paths.get(file.getAbsolutePath())); byte[] fileContent = Files.readAllBytes(Paths.get(file.getAbsolutePath()));
return encode(fileContent); return encode(fileContent);
} catch (IOException e) { } catch (IOException e) {
e.printStackTrace(); Log.e(e);
} }
return null; return null;
} }

View File

@ -1,21 +1,52 @@
package com.yutou.common.utils; package com.yutou.common.utils;
import com.yutou.bilibili.Tools.ProcessUtils;
import com.yutou.bilibili.interfaces.DownloadInterface; import com.yutou.bilibili.interfaces.DownloadInterface;
import lombok.Getter;
import java.io.*; import java.io.*;
import java.nio.charset.StandardCharsets; import java.nio.charset.StandardCharsets;
import java.util.LinkedHashMap; import java.util.*;
import java.util.Map;
public class FFmpegUtils { public class FFmpegUtils {
private static final Map<String, Long> pidMap = new HashMap<>();
@Getter
private String command; private String command;
private String uid;
InputStream inputStream; InputStream inputStream;
OutputStream outputStream; OutputStream outputStream;
private FFmpegUtils() { private FFmpegUtils() {
} }
public static boolean check(String anchorUid) {
try {
return ProcessUtils.isProcessRunning(pidMap.get(anchorUid));
} catch (Exception e) {
Log.e(e);
throw new RuntimeException(e);
}
}
public static void kill(String anchorUid) {
try {
ProcessUtils.killProcess(pidMap.get(anchorUid));
} catch (Exception e) {
Log.e(e);
throw new RuntimeException(e);
}
}
public static void killAll() {
for (Long pid : pidMap.values()) {
try {
ProcessUtils.killProcess(pid);
} catch (Exception e) {
Log.e(e);
}
}
}
public static class Builder { public static class Builder {
private final Map<String, String> params = new LinkedHashMap<>(); private final Map<String, String> params = new LinkedHashMap<>();
private final Map<String, String> paramsNotSymbol = new LinkedHashMap<>(); private final Map<String, String> paramsNotSymbol = new LinkedHashMap<>();
@ -57,9 +88,10 @@ public class FFmpegUtils {
} }
public FFmpegUtils build(String ffmpegPath, String inputUrl, String outputPath) { public FFmpegUtils build(String uid, String ffmpegPath, String inputUrl, String outputPath) {
FFmpegUtils ffmpeg = new FFmpegUtils(); FFmpegUtils ffmpeg = new FFmpegUtils();
ffmpeg.command = getCommand(ffmpegPath, inputUrl, outputPath); ffmpeg.command = getCommand(ffmpegPath, inputUrl, outputPath);
ffmpeg.uid = uid;
return ffmpeg; return ffmpeg;
} }
} }
@ -67,22 +99,29 @@ public class FFmpegUtils {
public void start(DownloadInterface downloadInterface) { public void start(DownloadInterface downloadInterface) {
new Thread(() -> { new Thread(() -> {
try { try {
Process process = AppTools.exec(command); if (check(uid)) {
kill(uid);
}
Process process = ProcessUtils.exec(command);
long pid = process.toHandle().pid();
Log.i("进程id "+pid);
inputStream = process.getErrorStream(); inputStream = process.getErrorStream();
outputStream = process.getOutputStream(); outputStream = process.getOutputStream();
byte[] bytes = new byte[2048]; byte[] bytes = new byte[2048];
if (downloadInterface != null) { if (downloadInterface != null) {
downloadInterface.onDownloadStart(); downloadInterface.onDownloadStart();
} }
pidMap.put(uid, pid);
while (inputStream.read(bytes) > -1) { while (inputStream.read(bytes) > -1) {
if (downloadInterface != null) { if (downloadInterface != null) {
downloadInterface.onDownloading(0, 0); downloadInterface.onDownloading(0, 0);
} }
} }
pidMap.remove(uid);
//获取视频时长ffprobe -v error -show_entries format=duration -of default=noprint_wrappers=1:nokey=1 input.mp4 //获取视频时长ffprobe -v error -show_entries format=duration -of default=noprint_wrappers=1:nokey=1 input.mp4
//获取到结果:5372.432000 //获取到结果:5372.432000
if (downloadInterface != null) { if (downloadInterface != null) {
System.out.println("触发下载完成"); Log.i("触发下载完成");
downloadInterface.onDownload(null); downloadInterface.onDownload(null);
} }
} catch (Exception e) { } catch (Exception e) {
@ -102,6 +141,7 @@ public class FFmpegUtils {
/** /**
* 获取视频时长 * 获取视频时长
*
* @param video 视频文件 * @param video 视频文件
* @return 毫秒 * @return 毫秒
*/ */
@ -109,8 +149,8 @@ public class FFmpegUtils {
String ffprobe = ConfigTools.load(ConfigTools.CONFIG, "ffprobe", String.class); String ffprobe = ConfigTools.load(ConfigTools.CONFIG, "ffprobe", String.class);
String exec = ffprobe + " -v error -show_entries format=duration -of default=noprint_wrappers=1:nokey=1 \"" + video.getAbsolutePath() + "\""; String exec = ffprobe + " -v error -show_entries format=duration -of default=noprint_wrappers=1:nokey=1 \"" + video.getAbsolutePath() + "\"";
try { try {
System.out.println(exec); Log.i(exec);
Process process = AppTools.exec(exec); Process process = ProcessUtils.exec(exec);
InputStream inputStream = process.getInputStream(); InputStream inputStream = process.getInputStream();
byte[] bytes = new byte[2048]; byte[] bytes = new byte[2048];
String data; String data;
@ -119,9 +159,9 @@ public class FFmpegUtils {
inputStream.close(); inputStream.close();
process.destroy(); process.destroy();
process.exitValue(); process.exitValue();
return (long) (Double.parseDouble(data)*1000); return (long) (Double.parseDouble(data) * 1000);
} catch (Exception e) { } catch (Exception e) {
e.printStackTrace(); Log.e(e);
throw new RuntimeException(e); throw new RuntimeException(e);
} }
} }

View File

@ -1,14 +1,15 @@
package com.yutou.common.utils; package com.yutou.common.utils;
import java.io.File; import org.slf4j.Logger;
import java.io.IOException; import org.slf4j.LoggerFactory;
import java.util.logging.FileHandler;
import java.util.logging.Level;
import java.util.logging.Logger;
public class Log { public class Log {
private static Logger logger=Logger.getLogger("Biliob"); private static Logger logger = LoggerFactory.getLogger("Biliob");
public static void i() {
i("\n");
}
public static void i(String tag, Object log) { public static void i(String tag, Object log) {
i('[' + tag + ']' + log); i('[' + tag + ']' + log);
@ -18,48 +19,44 @@ public class Log {
if (!((boolean) ConfigTools.load(ConfigTools.CONFIG, "logcat"))) { if (!((boolean) ConfigTools.load(ConfigTools.CONFIG, "logcat"))) {
return; return;
} }
// logger.log(Level.INFO, log.toString()); logger.info(log.toString());
System.out.printf("[%s]%s%n",
AppTools.getToDayNowTimeToString(),
log
);
} }
public static void e(Exception e) { public static void e(Object log) {
if (!ConfigTools.load(ConfigTools.CONFIG, "logcat", Boolean.class)){ if (!ConfigTools.load(ConfigTools.CONFIG, "logcat", Boolean.class)) {
return; return;
} }
i(e.getMessage()); logger.error(getStackTrace(),log);
e.printStackTrace();
} }
public static void i(String timer, int roomId, Object log) { public static void e(Throwable e) {
String logFlag = RedisTools.get("live-log", 1); if (!ConfigTools.load(ConfigTools.CONFIG, "logcat", Boolean.class)) {
if (logFlag != null && logFlag.startsWith("true")) { return;
if (logFlag.contains("|")) { }
if (log.toString().contains(logFlag.split("\\|")[1])) { logger.error(getStackTrace(), e);
getLogger("[" + timer.replace(":", "_") + "]" + roomId).log(Level.INFO, log.toString()); }
}
} else { public static void e(String tag, Throwable e) {
getLogger("[" + timer.replace(":", "_") + "]" + roomId).log(Level.INFO, log.toString()); logger.error("{}\n{}", tag, getStackTrace(), e);
} }
public static void d(Object... log) {
if (!ConfigTools.load(ConfigTools.CONFIG, "logcat", Boolean.class)) {
return;
}
if (log.length > 1) {
logger.debug(log[0].toString(), log);
} else {
logger.debug(log[0].toString());
} }
} }
public static Logger getLogger(String fileName) { private static String getStackTrace() {
if (logger == null) { StackTraceElement[] stackTrace = new Throwable().getStackTrace();
try { if (stackTrace.length > 3) {
if (!new File("logs").exists()) { StackTraceElement element = stackTrace[3];
new File("logs").mkdirs(); return " " + element.getClassName() + "." + element.getMethodName() + "#" + element.getLineNumber();
}
logger = Logger.getLogger("Live-Log");
FileHandler handler = new FileHandler("logs" + File.separator + fileName + ".log");
logger.addHandler(handler);
} catch (IOException e) {
e.printStackTrace();
}
} }
return logger; return "";
} }
} }

View File

@ -42,7 +42,7 @@ public class RedisTools {
jedis.close(); jedis.close();
} catch (Exception e) { } catch (Exception e) {
// TODO: handle exception // TODO: handle exception
e.printStackTrace(); Log.e(e);
return false; return false;
} }
return true; return true;
@ -66,7 +66,7 @@ public class RedisTools {
jedis.close(); jedis.close();
} catch (Exception e) { } catch (Exception e) {
// TODO: handle exception // TODO: handle exception
e.printStackTrace(); Log.e(e);
return false; return false;
} }
return true; return true;
@ -83,7 +83,7 @@ public class RedisTools {
jedis.close(); jedis.close();
} catch (Exception e) { } catch (Exception e) {
// TODO: handle exception // TODO: handle exception
// e.printStackTrace(); // Log.e(e);
} }
return value; return value;
} }
@ -155,7 +155,7 @@ public class RedisTools {
} }
properties.load(is); properties.load(is);
} catch (IOException e) { } catch (IOException e) {
e.printStackTrace(); Log.e(e);
} }
return properties; return properties;
} }

View File

@ -1,5 +1,6 @@
package com.yutou.qqbot; package com.yutou.qqbot;
import com.yutou.common.utils.Log;
import com.yutou.qqbot.handle.MessageHandleBuild; import com.yutou.qqbot.handle.MessageHandleBuild;
import com.yutou.qqbot.handle.Text; import com.yutou.qqbot.handle.Text;
import com.yutou.qqbot.http.NapCatApi; import com.yutou.qqbot.http.NapCatApi;
@ -38,12 +39,12 @@ public class NapCatQQ {
).enqueue(new HttpCallback<SendMessageResponse>() { ).enqueue(new HttpCallback<SendMessageResponse>() {
@Override @Override
public void onResponse(Headers headers, int code, String status, SendMessageResponse response, String rawResponse) { public void onResponse(Headers headers, int code, String status, SendMessageResponse response, String rawResponse) {
System.out.println("code = " + code + ", status = " + status + ", response = " + response + ", rawResponse = " + rawResponse); Log.i("code = " + code + ", status = " + status + ", response = " + response + ", rawResponse = " + rawResponse);
} }
@Override @Override
public void onFailure(Throwable throwable) { public void onFailure(Throwable throwable) {
throwable.printStackTrace(); Log.e(throwable);
} }
}); });
} }

View File

@ -3,6 +3,7 @@ package com.yutou.qqbot.event;
import com.alibaba.fastjson2.JSONArray; import com.alibaba.fastjson2.JSONArray;
import com.alibaba.fastjson2.JSONObject; import com.alibaba.fastjson2.JSONObject;
import com.alibaba.fastjson2.annotation.JSONField; import com.alibaba.fastjson2.annotation.JSONField;
import com.yutou.common.utils.Log;
import com.yutou.qqbot.QQDatabase; import com.yutou.qqbot.QQDatabase;
import com.yutou.qqbot.enums.MessageEnum; import com.yutou.qqbot.enums.MessageEnum;
import com.yutou.qqbot.handle.*; import com.yutou.qqbot.handle.*;
@ -135,7 +136,7 @@ public class MessageEvent {
} }
} }
} catch (Exception e) { } catch (Exception e) {
e.printStackTrace(); Log.e(e);
} }
return tmp; return tmp;
} }