移除轮询直播状态

新增getLiveState来获取直播状态
直播状态检测改成在心跳包里
This commit is contained in:
yutou 2021-05-24 15:45:30 +08:00
parent c64300d76d
commit 5a49fc831a
7 changed files with 74 additions and 112 deletions

View File

@ -17,6 +17,7 @@ import com.yutou.bilibili.mybatis.Bili.mybatis.model.BilibiliLiveData;
import com.yutou.bilibili.mybatis.Bili.mybatis.model.BilibiliLiveInfo;
import com.yutou.bilibili.mybatis.Bili.mybatis.model.BilibiliUpInfo;
import com.yutou.bilibili.sqlite.BiliBiliLiveDatabasesManager;
import lombok.Data;
import org.java_websocket.client.WebSocketClient;
import org.java_websocket.handshake.ServerHandshake;
import org.jetbrains.annotations.NotNull;
@ -37,7 +38,7 @@ public class Live implements ApplicationContextAware {
IBiliBiliLiveService service;
public static Map<Integer,Live> lives = new HashMap<>();
public static Map<Integer, Live> lives = new HashMap<>();
private int roomId;
@ -49,7 +50,15 @@ public class Live implements ApplicationContextAware {
private BilibiliUpInfo upData;
private Timer heartBeattimer;
public BiliBiliLiveDatabasesManager danmuManager = null;
public Timer checkLiveTimer;
private LiveInfo liveInfo;
public LiveInfo getLiveInfo() {
return liveInfo;
}
public void setLiveInfo(LiveInfo liveInfo) {
this.liveInfo = liveInfo;
}
@PostConstruct
public void init() {
@ -74,8 +83,8 @@ public class Live implements ApplicationContextAware {
* @param isLogin 是否登录用户
*/
public void add(int roomId, boolean isLogin) {
if(Live.lives.containsKey(roomId)){
Log.i("已经在统计:"+roomId);
if (Live.lives.containsKey(roomId)) {
Log.i("已经在统计:" + roomId);
return;
}
this.roomId = roomId;
@ -86,16 +95,10 @@ public class Live implements ApplicationContextAware {
info.setGiftuser(0);
info.setVipuserindex(0);
info.setUserindex(0);
Live.lives.put(roomId,this);
Live.lives.put(roomId, this);
updateUpInfo();
com.yutou.bilibili.Tools.Log.i("roomId = " + roomId + ", isLogin = " + isLogin);
checkLiveTimer = new Timer();
checkLiveTimer.schedule(new TimerTask() {
@Override
public void run() {
checkLive();
}
}, 0, 1000);
}
private void updateUpInfo() {
@ -133,7 +136,7 @@ public class Live implements ApplicationContextAware {
stop();
return;
}
startTime=new Date();
startTime = new Date();
HashMap<String, String> header = new HashMap<>();
header.put("Sec-WebSocket-Extensions", "permessage-deflate; client_max_window_bits");
header.put("Sec-WebSocket-Key", "tORCZd8AI6xIyvqvgvI1Vw==");
@ -181,7 +184,7 @@ public class Live implements ApplicationContextAware {
public void onClose(int i, String s, boolean b) {
com.yutou.bilibili.Tools.Log.i("连接时间:" + (System.currentTimeMillis() - time));
if (upData.getOfflinelistening() == 1) {
Log.i(roomId + " 断开连接,重连...");
Log.i(roomId + " 断开连接,重连...");
try {
init = true;
heartBeattimer.cancel();
@ -227,9 +230,6 @@ public class Live implements ApplicationContextAware {
if (SaveLive.getInstance().checkLive(roomId)) {
SaveLive.getInstance().stop(roomId);
}
if (checkLiveTimer != null) {
checkLiveTimer.cancel();
}
Live.lives.remove(roomId);
com.yutou.bilibili.Tools.Log.i("退出" + roomId + "直播间");
}
@ -241,7 +241,7 @@ public class Live implements ApplicationContextAware {
*/
private void likeLive() throws Exception {
JSONObject tmp = LiveUtils.http_get("https://api.bilibili.com/x/web-interface/nav");
if (tmp!=null&&tmp.getInteger("code") == -101) {
if (tmp != null && tmp.getInteger("code") == -101) {
if (isLogin) {
new File("cookies.json").deleteOnExit();
upData.setLive(0);
@ -251,11 +251,11 @@ public class Live implements ApplicationContextAware {
} else {
userId = 0;
}
} else if (tmp!=null&&tmp.getInteger("code") == 0) {
} else if (tmp != null && tmp.getInteger("code") == 0) {
userId = tmp.getJSONObject("data").getInteger("mid");
}
JSONObject http = LiveUtils.http_get("https://api.live.bilibili.com/xlive/web-room/v1/index/getDanmuInfo?id=" + roomId + "&type=0");
if(http==null){
if (http == null) {
stop();
return;
}
@ -289,18 +289,17 @@ public class Live implements ApplicationContextAware {
if (data.length > 32) {
List<String> list = LiveUtils.getMsgList(LiveUtils.dec(bytes), new ArrayList<>(), true);
String tmp="";
for (String str : list) {
processData(str, data);
tmp+=str.substring(0,16)+" | ";
String tmp = "";
for (int i=0;i<list.size();i++) {
processData(list.get(i), data);
tmp +="|||"+i+"[start] "+ list.get(i)+ " [end]||| ";
}
Log.i(AppTools.getToDayTimeToString(startTime),roomId,"list size = "+list.size()+" data = "+tmp);
Log.i(AppTools.getToDayTimeToString(startTime), roomId, "list size = " + list.size() + " data = " + tmp);
} else {
try {
JSONObject json = JSONObject.parseObject(new String(bytes, StandardCharsets.UTF_8));
com.yutou.bilibili.Tools.Log.i(json.toJSONString());
} catch (Exception e) {
checkLive();
int popular = LiveUtils.bytesToInt2(bytes, 0);
info.setPopular(popular);
}
@ -345,7 +344,7 @@ public class Live implements ApplicationContextAware {
switch (json.getString("cmd")) {
case "INTERACT_WORD"://普通用户进直播间
danmu = json.getJSONObject("data").getString("uname") + " 进入到直播间";
Log.i(AppTools.getToDayTimeToString(startTime),roomId,danmu);
Log.i(AppTools.getToDayTimeToString(startTime), roomId, danmu);
liveData.setUid(json.getJSONObject("data").getInteger("uid"));
liveData.setType(LiveData.INTERACT_WORD);
liveData.setMsg(danmu);
@ -371,7 +370,7 @@ public class Live implements ApplicationContextAware {
danmuManager.addDanmu(danmuData);
}
}
Log.i(AppTools.getToDayTimeToString(startTime),roomId,danmu);
Log.i(AppTools.getToDayTimeToString(startTime), roomId, danmu);
break;
case "SEND_GIFT"://送礼
data = json.getJSONObject("data");
@ -398,7 +397,7 @@ public class Live implements ApplicationContextAware {
liveData.setRoomid(roomId);
info.setGiftuser(info.getGiftuser() + 1);
service.addLiveData(liveData);
Log.i(AppTools.getToDayTimeToString(startTime),roomId,danmu);
Log.i(AppTools.getToDayTimeToString(startTime), roomId, danmu);
break;
case "COMBO_SEND"://礼物连击
data = json.getJSONObject("data");
@ -429,7 +428,7 @@ public class Live implements ApplicationContextAware {
liveData.setRoomid(roomId);
info.setGiftuser(info.getGiftuser() + 1);
service.addLiveData(liveData);
Log.i(AppTools.getToDayTimeToString(startTime),roomId,danmu);
Log.i(AppTools.getToDayTimeToString(startTime), roomId, danmu);
break;
case "ENTRY_EFFECT"://舰长进直播间
info.setVipuserindex(info.getVipuserindex() + 1);
@ -440,7 +439,7 @@ public class Live implements ApplicationContextAware {
liveData.setRoomid(roomId);
liveData.setSubtime(new Date());
service.addLiveData(liveData);
Log.i(AppTools.getToDayTimeToString(startTime),roomId,danmu);
Log.i(AppTools.getToDayTimeToString(startTime), roomId, danmu);
break;
case "LIVE_INTERACTIVE_GAME"://彩色弹幕通过游戏弹幕
break;
@ -460,7 +459,7 @@ public class Live implements ApplicationContextAware {
liveData.setSubtime(new Date());
info.setGiftuser(info.getGiftuser() + 1);
service.addLiveData(liveData);
Log.i(AppTools.getToDayTimeToString(startTime),roomId,danmu);
Log.i(AppTools.getToDayTimeToString(startTime), roomId, danmu);
break;
case "USER_TOAST_MSG":
break;
@ -478,29 +477,35 @@ public class Live implements ApplicationContextAware {
liveData.setRoomid(roomId);
info.setGiftuser(info.getGiftuser() + 1);
service.addLiveData(liveData);
Log.i(AppTools.getToDayTimeToString(startTime),roomId,liveData.toString());
Log.i(AppTools.getToDayTimeToString(startTime), roomId, liveData.toString());
break;
case "LIVE"://开始直播,不过有在心跳包上做检测了所以也无所谓
if (upData.getLive() == 1) {
break;
}
upData.setLive(1);
LiveUtils.LiveInfoManager.getInstance().check(roomId);
JSONObject liveInfo = LiveUtils.LiveInfoManager.getInstance().getInfo(roomId);
if(liveInfo==null){
JSONObject liveInfo = LiveUtils.getLiveInfo(roomId);
if (liveInfo == null) {
break;
}
LiveInfo info = new LiveInfo();
info.setTitle(liveInfo.getJSONObject("data").getJSONObject("room_info").getString("title"));
info.setKeyframe(liveInfo.getJSONObject("data").getJSONObject("room_info").getString("keyframe"));
info.setRoomId(liveInfo.getJSONObject("data").getJSONObject("room_info").getInteger("room_id"));
info.setShortId(liveInfo.getJSONObject("data").getJSONObject("room_info").getInteger("short_id"));
info.setInfo(liveInfo);
setLiveInfo(info);
StringBuilder builder = new StringBuilder();
builder.append(upData.getName()).append("开播了!").append("\n");
builder.append(liveInfo.getJSONObject("data").getJSONObject("room_info").getString("title"));
Tools.download(liveInfo.getJSONObject("data").getJSONObject("room_info").getString("keyframe"), new DownloadInterface() {
builder.append(info.getTitle());
Tools.download(info.getKeyframe(), new DownloadInterface() {
@Override
public void onDownload(File file) {
super.onDownload(file);
QQBotManager.getInstance().sendMessage(file, builder.toString());
}
});
Log.i(AppTools.getToDayTimeToString(startTime),roomId,upData.getName()+"开播了!");
Log.i(AppTools.getToDayTimeToString(startTime), roomId, upData.getName() + "开播了!");
break;
case "PREPARING"://
case "SUPER_CHAT_MESSAGE_JPN":
@ -523,7 +528,7 @@ public class Live implements ApplicationContextAware {
//com.yutou.bilibili.Tools.Log.i(msg);
break;
default:
com.yutou.bilibili.Tools.Log.i(msg);
com.yutou.bilibili.Tools.Log.i("["+roomId+"]"+msg);
liveData = new BilibiliLiveData();
liveData.setType(LiveData.UNKNOWN_MESSAGE);
liveData.setUid(-1);
@ -531,24 +536,24 @@ public class Live implements ApplicationContextAware {
liveData.setRoomid(roomId);
liveData.setSubtime(new Date());
service.addLiveData(liveData);
Log.i(AppTools.getToDayTimeToString(startTime),roomId,liveData.toString());
Log.i(AppTools.getToDayTimeToString(startTime), roomId, liveData.toString());
}
} catch (Exception e) {
Log.e(e);
Log.i(AppTools.getToDayTimeToString(startTime),roomId,e.getLocalizedMessage());
Log.i(AppTools.getToDayTimeToString(startTime), roomId, e.getLocalizedMessage());
try {
JSONObject.parseObject(new String(bytes, StandardCharsets.UTF_8));
processData(new String(bytes, StandardCharsets.UTF_8), null);
} catch (Exception e2) {
try {
JSONObject.parseObject(msg);
processData(msg,bytes);
}catch (Exception e3) {
processData(msg, bytes);
} catch (Exception e3) {
Log.e(e2);
com.yutou.bilibili.Tools.Log.i("---------ERROR start-----");
com.yutou.bilibili.Tools.Log.i(msg);
com.yutou.bilibili.Tools.Log.i("---------ERROR end-----");
// LiveUtils.printHex(bytes);
// LiveUtils.printHex(bytes);
}
}
@ -601,8 +606,10 @@ public class Live implements ApplicationContextAware {
return;
}
updateUpInfo();
if (upData.getOfflinelistening() != 1 && !LiveUtils.isLivePlayer(upData.getRoomid())) {
stop();
if (upData.getOfflinelistening() != 1) {
if (!LiveUtils.isLivePlayer(upData.getRoomid())) {
stop();
}
}
try {
// com.yutou.bilibili.Tools.Log.i("-------发送心跳--------");
@ -612,6 +619,7 @@ public class Live implements ApplicationContextAware {
outputStream.write("[object Object]".getBytes(StandardCharsets.UTF_8));
outputStream.flush();
client.send(outputStream.toByteArray());
checkLive();
} catch (Exception e) {
Log.e(e);
com.yutou.bilibili.Tools.Log.i(client.isClosed());
@ -623,7 +631,7 @@ public class Live implements ApplicationContextAware {
}
public GiftData getGiftData(int id) {
JSONObject item=JSONObject.parseObject(RedisTools.get("bili_gift_"+id,2));
JSONObject item = JSONObject.parseObject(RedisTools.get("bili_gift_" + id, 2));
GiftData data = new GiftData();
data.setPrice(item.getInteger("price"));
data.setName(item.getString("name"));
@ -633,4 +641,14 @@ public class Live implements ApplicationContextAware {
data.setDesc(item.getString("desc"));
return data;
}
@Data
public static class LiveInfo {
private String title;
private String keyframe;
private int roomId;
private int shortId;
private JSONObject info;
}
}

View File

@ -346,7 +346,7 @@ public class LiveUtils {
return null;
}
private static JSONObject getLiveInfo(int roomId) {
public static JSONObject getLiveInfo(int roomId) {
return http_get("https://api.live.bilibili.com/xlive/web-room/v1/index/getInfoByRoom?room_id=" + roomId);
}
@ -355,7 +355,7 @@ public class LiveUtils {
}
public static String getLiveTitle(int roomId) {
JSONObject json = LiveInfoManager.getInstance().getInfo(roomId);
JSONObject json =getLiveInfo(roomId);
if (json != null) {
return json.getJSONObject("data").getJSONObject("room_info").getString("title");
}
@ -363,14 +363,11 @@ public class LiveUtils {
}
public static boolean isLivePlayer(int roomId) {
JSONObject json = LiveInfoManager.getInstance().getInfo(roomId);
JSONObject json = getLiveState(roomId);
if (json == null) {
return false;
}
BilibiliUpInfo upData = new BilibiliUpInfo();
upData.setRoomid(roomId);
//Log.i("直播检测:" + roomId + " > " + (json.getJSONObject("data").getJSONObject("room_info").getInteger("live_status") == 1) + " 录播器:" + liveContains(upData));
return json.getJSONObject("data").getJSONObject("room_info").getInteger("live_status") == 1;
return json.getJSONObject("data").getInteger("live_status") == 1;
}
private static void checkLiveSave(int roomId) {
@ -422,55 +419,6 @@ public class LiveUtils {
}
public static class LiveInfoManager {
private static LiveInfoManager manager;
private Map<Integer, JSONObject> infoMap;
public static LiveInfoManager getInstance() {
if (manager == null) {
manager = new LiveInfoManager();
}
return manager;
}
private LiveInfoManager() {
infoMap = new HashMap<>();
}
public synchronized void check(List<BilibiliUpInfo> list) {
for (BilibiliUpInfo upInfo : list) {
JSONObject json = getLiveInfo(upInfo.getRoomid());
if (json != null) {
infoMap.put(upInfo.getRoomid(), json);
}
try {
Thread.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
Log.i("信息map数量:"+infoMap.size());
}
public synchronized void check(int roomId) {
JSONObject json = getLiveInfo(roomId);
if (json != null) {
Log.i("登记直播:"+roomId);
infoMap.put(roomId, json);
}else{
infoMap.remove(roomId);
}
}
public synchronized JSONObject getInfo(int roomId) {
if (!infoMap.containsKey(roomId)) {
//check(roomId);
return null;
}
return infoMap.get(roomId);
}
}
public static void main(String[] args) {
int index=1000;
for (int i = 0; i < index; i++) {

View File

@ -78,7 +78,6 @@ public class SaveLive {
heartbeats.get(roomId).cancel();
heartbeats.remove(roomId);
}
LiveUtils.LiveInfoManager.getInstance().check(roomId);
}
@ -134,7 +133,6 @@ public class SaveLive {
if (!(e instanceof FileNotFoundException)) {
Log.i("录制发生意外:" + e.getMessage());
QQBotManager.getInstance().sendMessage("录制发生意外:" + e.getLocalizedMessage());
LiveUtils.LiveInfoManager.getInstance().check(roomId);
}
}
SaveLive.this.stop(roomId);

View File

@ -13,7 +13,7 @@ import org.springframework.context.annotation.Import;
@SpringBootApplication
public class BilibiliApplication {
public static String version="0.7.1";
public static String version="0.7.4.1";
public static void main(String[] args) {
QQBotManager.getInstance().init();

View File

@ -264,15 +264,15 @@ public class QQBotManager implements ApplicationContextAware {
builder.append("当前正在记录数据的直播间:");
builder.append("\n");
for (Live live : Live.lives.values()) {
JSONObject liveJson = LiveUtils.LiveInfoManager.getInstance().getInfo(live.getInfo().getRoomid());
Live.LiveInfo info=live.getLiveInfo();
if (LiveUtils.isLivePlayer(live.getInfo().getRoomid())) {
builder.append("【直播中】");
}
builder
.append("名字:").append(live.geData().getName()).append(" ")
.append(" roomId:").append(live.geData().getRoomid()).append(" ");
if (liveJson != null) {
builder.append("标题:").append(liveJson.getJSONObject("data").getJSONObject("room_info").getString("title")).append("\n");
if (info != null) {
builder.append("标题:").append(info.getTitle()).append("\n");
} else {
builder.append("\n");
}

View File

@ -90,7 +90,6 @@ public class ApplicationInit implements ApplicationRunner {
saveData(time);
break;
}
LiveUtils.LiveInfoManager.getInstance().check(service.getUpInfo());
}
private void checkLive() {

View File

@ -42,7 +42,6 @@ public class RedisTools {
Jedis jedis = getRedis();
jedis.select(dbIndex);
String ret = jedis.set(key, value);
Log.i("Redis set =" + ret);
jedis.close();
} catch (Exception e) {
// TODO: handle exception