472 lines
18 KiB
Java
472 lines
18 KiB
Java
package com.yutou.bilibili.BiliBili;
|
|
|
|
import com.yutou.bilibili.BiliBili.Datas.BiliBiliUpData;
|
|
import com.yutou.bilibili.BiliBili.Datas.GiftData;
|
|
import com.alibaba.fastjson.JSON;
|
|
import com.alibaba.fastjson.JSONArray;
|
|
import com.alibaba.fastjson.JSONObject;
|
|
import com.yutou.bilibili.BiliBili.Services.IBiliBiliLiveService;
|
|
import com.yutou.bilibili.BiliBili.Tools.SaveLive;
|
|
import com.yutou.bilibili.Tools.AppTools;
|
|
import com.yutou.bilibili.Tools.Log;
|
|
import com.yutou.bilibili.mybatis.Bili.mybatis.model.BilibiliUpInfo;
|
|
import org.springframework.util.StringUtils;
|
|
|
|
import javax.annotation.Resource;
|
|
import javax.xml.bind.DatatypeConverter;
|
|
import java.io.*;
|
|
import java.net.HttpURLConnection;
|
|
import java.net.URL;
|
|
import java.nio.ByteBuffer;
|
|
import java.nio.charset.StandardCharsets;
|
|
import java.util.*;
|
|
import java.util.zip.Inflater;
|
|
|
|
public class LiveUtils {
|
|
private static String cookie = null;
|
|
|
|
public LiveUtils() {
|
|
|
|
}
|
|
|
|
|
|
public static String getLiveUrl(int roomId) {
|
|
JSONObject json = http_get("https://api.live.bilibili.com/xlive/web-room/v1/index/getDanmuInfo?id=" + roomId + "&type=0");
|
|
if (json != null)
|
|
return "wss://" + json.getJSONObject("data").getJSONArray("host_list").getJSONObject(0).getString("host") + "/sub";
|
|
return null;
|
|
}
|
|
|
|
public static void printHex(byte[] bytes) {
|
|
String str = DatatypeConverter.printHexBinary(bytes);
|
|
for (int i = 0; i < str.length(); i = i + 4) {
|
|
if (i % 32 == 0 && i != 0) {
|
|
com.yutou.bilibili.Tools.Log.i("\n");
|
|
}
|
|
if (str.length() - i > 4) {
|
|
com.yutou.bilibili.Tools.Log.i(str.substring(i, i + 4));
|
|
} else {
|
|
com.yutou.bilibili.Tools.Log.i(str.substring(i));
|
|
}
|
|
}
|
|
}
|
|
|
|
public static byte[] dec(byte[] data) {
|
|
byte[] output = new byte[0];
|
|
|
|
Inflater decompresser = new Inflater();
|
|
decompresser.reset();
|
|
decompresser.setInput(data);
|
|
|
|
ByteArrayOutputStream o = new ByteArrayOutputStream(data.length);
|
|
try {
|
|
byte[] buf = new byte[1024];
|
|
while (!decompresser.finished()) {
|
|
int i = decompresser.inflate(buf);
|
|
o.write(buf, 0, i);
|
|
}
|
|
output = o.toByteArray();
|
|
} catch (Exception e) {
|
|
// com.yutou.bilibili.Tools.Log.e(e);
|
|
try {
|
|
JSONObject json = JSONObject.parseObject(new String(data, StandardCharsets.UTF_8));
|
|
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
|
|
// outputStream.write(toLH(json.toJSONString().length() + 16));
|
|
//outputStream.write(new byte[]{0, 16, 0, 1, 0, 0, 0, 5, 0, 0, 0, 1});
|
|
outputStream.write(json.toJSONString().getBytes(StandardCharsets.UTF_8));
|
|
output = outputStream.toByteArray();
|
|
} catch (Exception e1) {
|
|
output = data;
|
|
}
|
|
} finally {
|
|
try {
|
|
o.close();
|
|
} catch (IOException e) {
|
|
com.yutou.bilibili.Tools.Log.e(e);
|
|
}
|
|
}
|
|
|
|
decompresser.end();
|
|
return output;
|
|
}
|
|
|
|
public static List<String> getMsgList(byte[] bytes, List<String> list, boolean isOne) {
|
|
int len = 16;
|
|
ByteBuffer datas = ByteBuffer.allocate(bytes.length - len);
|
|
byte[] heads = new byte[4];
|
|
//获取到头信息
|
|
System.arraycopy(bytes, 0, heads, 0, 4);
|
|
int size = bytesToInt2(heads, 0) - 16;
|
|
|
|
//datas=MainApp.dec(datas);
|
|
if (size == datas.array().length) {
|
|
System.arraycopy(bytes, len, datas.array(), 0, bytes.length - len);
|
|
list.add(new String(datas.array(), StandardCharsets.UTF_8));
|
|
} else {
|
|
try {
|
|
// com.yutou.bilibili.Tools.Log.i("datas size = " + size);
|
|
if (size > 1000000000) {
|
|
try {
|
|
JSONObject.parseObject(new String(bytes));
|
|
list.add(new String(bytes, StandardCharsets.UTF_8));
|
|
return list;
|
|
} catch (Exception e) {
|
|
com.yutou.bilibili.Tools.Log.e(e);
|
|
}
|
|
}
|
|
datas.clear();
|
|
datas = ByteBuffer.allocate(size);
|
|
System.arraycopy(bytes, len, datas.array(), 0, size);
|
|
list.add(new String(datas.array(), StandardCharsets.UTF_8));
|
|
byte[] tmps = new byte[bytes.length - size - 16];
|
|
int length = bytes.length - (size + len);
|
|
System.arraycopy(bytes, size + (len), tmps, 0, length);
|
|
|
|
getMsgList(tmps, list, false);
|
|
} catch (Exception e) {
|
|
list.add(new String(bytes, StandardCharsets.UTF_8));
|
|
}
|
|
|
|
}
|
|
return list;
|
|
}
|
|
|
|
public static byte[] toLH(int n) {
|
|
byte[] b = new byte[4];
|
|
b[3] = (byte) (n & 0xff);
|
|
b[2] = (byte) (n >> 8 & 0xff);
|
|
b[1] = (byte) (n >> 16 & 0xff);
|
|
b[0] = (byte) (n >> 24 & 0xff);
|
|
return b;
|
|
}
|
|
|
|
public static int bytesToInt2(byte[] src, int offset) {
|
|
int value;
|
|
value = (int) (((src[offset] & 0xFF) << 24)
|
|
| ((src[offset + 1] & 0xFF) << 16)
|
|
| ((src[offset + 2] & 0xFF) << 8)
|
|
| (src[offset + 3] & 0xFF));
|
|
return value;
|
|
}
|
|
|
|
public static String getCookie() {
|
|
if (StringUtils.isEmpty(getFile("cookies.json"))) {
|
|
|
|
return "";
|
|
}
|
|
JSONObject json = JSONObject.parseObject(getFile("cookies.json"));
|
|
StringBuilder builder = new StringBuilder();
|
|
for (String s : json.keySet()) {
|
|
builder.append(s).append("=").append(json.getString(s)).append(";");
|
|
|
|
}
|
|
return builder.toString();
|
|
}
|
|
|
|
/* public static String createCookie(){
|
|
String bid="AUTO"+AppTools.randomString(16,new String[]{AppTools.numbers});
|
|
bid="AUTO6616152607312876";
|
|
return String.format("LIVE_BUVID=%s; _uuid=%sinfoc; buvid3=%sinfoc; sid=%s; fingerprint=%s; buvid_fp=%sinfoc; buvid_fp_plain=%sinfoc; PVID=%d;"
|
|
,bid
|
|
,UUID.randomUUID().toString()
|
|
,UUID.randomUUID().toString()
|
|
,"bm3byv4p"
|
|
,"074eae35a01a56c40558a54ab33179e5"
|
|
,UUID.randomUUID().toString()
|
|
,UUID.randomUUID().toString()
|
|
,AppTools.randomCommon(0,9,1)[0]);
|
|
}*/
|
|
private static long oldBiliBiliHttpTime = 0;
|
|
|
|
public synchronized static JSONObject http_get(String url) {
|
|
try {
|
|
Log.i("调用url = "+url);
|
|
HttpURLConnection connection = getBiliHttpGet(url, getCookie());
|
|
BufferedInputStream stream = new BufferedInputStream(connection.getInputStream());
|
|
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
|
|
byte[] bytes = new byte[1024];
|
|
int len = 0, size;
|
|
while ((len = stream.read(bytes)) != -1) {
|
|
outputStream.write(bytes, 0, len);
|
|
outputStream.flush();
|
|
}
|
|
String str = new String(outputStream.toByteArray(), StandardCharsets.UTF_8);
|
|
outputStream.close();
|
|
try {
|
|
JSONObject json = JSON.parseObject(str);
|
|
return json;
|
|
} catch (Exception e) {
|
|
JSONObject json = new JSONObject();
|
|
json.put("html", str);
|
|
return json;
|
|
} finally {
|
|
|
|
stream.close();
|
|
connection.disconnect();
|
|
}
|
|
|
|
} catch (IOException e) {
|
|
//com.yutou.bilibili.Tools.Log.e(e);
|
|
Log.e(e);
|
|
Log.i("412 in " + url);
|
|
}
|
|
return null;
|
|
}
|
|
|
|
public static JSONObject http_post(String url, String body) {
|
|
try {
|
|
if (System.currentTimeMillis() - oldBiliBiliHttpTime < 1000) {
|
|
try {
|
|
Thread.sleep(500);
|
|
} catch (InterruptedException e) {
|
|
com.yutou.bilibili.Tools.Log.e(e);
|
|
}
|
|
oldBiliBiliHttpTime = System.currentTimeMillis();
|
|
}
|
|
HttpURLConnection connection = getBiliHttpPost(url, getCookie());
|
|
OutputStream connectionOutputStream = null;
|
|
if (!StringUtils.isEmpty(body)) {
|
|
connectionOutputStream = connection.getOutputStream();
|
|
connectionOutputStream.write(body.getBytes(StandardCharsets.UTF_8));
|
|
connectionOutputStream.flush();
|
|
}
|
|
BufferedInputStream stream = new BufferedInputStream(connection.getInputStream());
|
|
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
|
|
byte[] bytes = new byte[1024];
|
|
int len = 0, size;
|
|
while ((len = stream.read(bytes)) != -1) {
|
|
outputStream.write(bytes, 0, len);
|
|
outputStream.flush();
|
|
}
|
|
String str = new String(outputStream.toByteArray(), StandardCharsets.UTF_8);
|
|
outputStream.close();
|
|
try {
|
|
JSONObject json = JSON.parseObject(str);
|
|
json.put("cookie", connection.getHeaderField("Set-Cookie"));
|
|
return json;
|
|
} catch (Exception e) {
|
|
JSONObject json = new JSONObject();
|
|
json.put("html", str);
|
|
json.put("cookie", connection.getHeaderField("Set-Cookie"));
|
|
return json;
|
|
} finally {
|
|
stream.close();
|
|
if (connectionOutputStream != null)
|
|
connectionOutputStream.close();
|
|
connection.disconnect();
|
|
}
|
|
|
|
} catch (Exception e) {
|
|
com.yutou.bilibili.Tools.Log.e(e);
|
|
}
|
|
return new JSONObject();
|
|
}
|
|
|
|
public static HttpURLConnection getBiliHttpPost(String url, String cookie) throws Exception {
|
|
if (System.currentTimeMillis() - oldBiliBiliHttpTime < 1000) {
|
|
try {
|
|
Thread.sleep(500);
|
|
} catch (InterruptedException e) {
|
|
com.yutou.bilibili.Tools.Log.e(e);
|
|
}
|
|
oldBiliBiliHttpTime = System.currentTimeMillis();
|
|
}
|
|
HttpURLConnection connection = (HttpURLConnection) new URL(url).openConnection();
|
|
connection.setRequestMethod("POST");
|
|
connection.setDoOutput(true);
|
|
connection.setDoInput(true);
|
|
connection.setRequestProperty("Accept", "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8");
|
|
connection.setRequestProperty("Accept-Language", "zh-CN,zh;q=0.8");
|
|
connection.setRequestProperty("Cache-Control", "max-age=0");
|
|
connection.setRequestProperty("Referer", "https://live.bilibili.com");
|
|
connection.setRequestProperty("Connection", "keep-alive");
|
|
connection.setRequestProperty("Upgrade-Insecure-Requests", "1");
|
|
connection.setRequestProperty("Cookie", cookie);
|
|
connection.setRequestProperty("User-Agent", "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/44.0.2403.157 Safari/537.36");
|
|
return connection;
|
|
}
|
|
|
|
public static HttpURLConnection getBiliHttpGet(String url, String cookie) throws IOException {
|
|
if (System.currentTimeMillis() - oldBiliBiliHttpTime < 1000) {
|
|
try {
|
|
Thread.sleep(500);
|
|
} catch (InterruptedException e) {
|
|
com.yutou.bilibili.Tools.Log.e(e);
|
|
}
|
|
oldBiliBiliHttpTime = System.currentTimeMillis();
|
|
}
|
|
HttpURLConnection connection = (HttpURLConnection) new URL(url).openConnection();
|
|
connection.setRequestProperty("Accept", "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8");
|
|
connection.setRequestProperty("Accept-Language", "zh-CN,zh;q=0.8");
|
|
connection.setRequestProperty("Cache-Control", "max-age=0");
|
|
connection.setRequestProperty("Referer", "https://live.bilibili.com");
|
|
connection.setRequestProperty("Connection", "keep-alive");
|
|
connection.setRequestProperty("Upgrade-Insecure-Requests", "1");
|
|
connection.setRequestProperty("Cookie", cookie);
|
|
connection.setRequestProperty("User-Agent", "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/44.0.2403.157 Safari/537.36");
|
|
connection.setReadTimeout(5000);
|
|
connection.setConnectTimeout(5000);
|
|
return connection;
|
|
}
|
|
|
|
|
|
public static String getFile(String filePath) {
|
|
File file = new File(filePath);
|
|
try {
|
|
BufferedReader reader = new BufferedReader(new FileReader(file));
|
|
String str = "", tmp;
|
|
while ((tmp = reader.readLine()) != null) {
|
|
str += tmp;
|
|
}
|
|
reader.close();
|
|
return str;
|
|
} catch (Exception e) {
|
|
|
|
}
|
|
return null;
|
|
}
|
|
|
|
|
|
public static JSONObject getUserLoginInfo() {
|
|
return LiveUtils.http_get("https://api.bilibili.com/x/web-interface/nav");
|
|
}
|
|
|
|
public static Live liveContains(BilibiliUpInfo data) {
|
|
for (Live live : Live.lives) {
|
|
if (live.getInfo().getRoomid().equals(data.getRoomid())) {
|
|
return live;
|
|
}
|
|
}
|
|
return null;
|
|
}
|
|
|
|
private static JSONObject getLiveInfo(int roomId) {
|
|
return http_get("https://api.live.bilibili.com/xlive/web-room/v1/index/getInfoByRoom?room_id=" + roomId);
|
|
|
|
}
|
|
|
|
public static String getLiveTitle(int roomId) {
|
|
JSONObject json = LiveInfoManager.getInstance().getInfo(roomId);
|
|
if (json != null) {
|
|
return json.getJSONObject("data").getJSONObject("room_info").getString("title");
|
|
}
|
|
return null;
|
|
}
|
|
|
|
public static boolean isLivePlayer(int roomId) {
|
|
JSONObject json = LiveInfoManager.getInstance().getInfo(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;
|
|
}
|
|
|
|
private static void checkLiveSave(int roomId) {
|
|
BilibiliUpInfo upData = new BilibiliUpInfo();
|
|
upData.setRoomid(roomId);
|
|
Live live = liveContains(upData);
|
|
if (live == null) {
|
|
live = new Live();
|
|
live.add(roomId, !StringUtils.isEmpty(AppTools.readFile(new File("cookies.json"))));
|
|
try {
|
|
live.start();
|
|
} catch (Exception e) {
|
|
com.yutou.bilibili.Tools.Log.e(e);
|
|
}
|
|
}
|
|
if (!SaveLive.getInstance().checkLive(roomId)) {
|
|
SaveLive.getInstance().addLive(roomId);
|
|
}
|
|
|
|
}
|
|
|
|
public static class LiveGiftConfig {
|
|
@Resource
|
|
IBiliBiliLiveService service;
|
|
private static LiveGiftConfig config;
|
|
public static List<GiftData> giftDataList = new ArrayList<>();
|
|
|
|
public static LiveGiftConfig getInstance() {
|
|
if (config == null) {
|
|
config = new LiveGiftConfig();
|
|
}
|
|
return config;
|
|
}
|
|
|
|
private LiveGiftConfig() {
|
|
init();
|
|
}
|
|
|
|
public void init() {
|
|
giftDataList = new ArrayList<>();
|
|
JSONObject json = http_get("https://api.live.bilibili.com/xlive/web-room/v1/giftPanel/giftConfig?platform=pc");
|
|
JSONArray list = json.getJSONObject("data").getJSONArray("list");
|
|
for (Object o : list) {
|
|
JSONObject item = (JSONObject) o;
|
|
GiftData data = new GiftData();
|
|
data.setPrice(item.getInteger("price"));
|
|
data.setName(item.getString("name"));
|
|
data.setId(item.getInteger("id"));
|
|
data.setRights(item.getString("rights"));
|
|
data.setIcon(item.getString("img_basic"));
|
|
data.setDesc(item.getString("desc"));
|
|
giftDataList.add(data);
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
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);
|
|
}
|
|
}
|
|
|
|
}
|