diff --git a/Web/html/body/user.html b/Web/html/body/user.html index 8cc055f..169d37e 100644 --- a/Web/html/body/user.html +++ b/Web/html/body/user.html @@ -41,9 +41,11 @@ }); } function refresh(data) { + var loadIndex = showLoadingDialog(); refreshCookie(data) .then(data => { console.log(data) + layer.close(loadIndex) layer.msg(data.message) }) } diff --git a/Web/index.html b/Web/index.html index ec55e72..3746362 100644 --- a/Web/index.html +++ b/Web/index.html @@ -158,10 +158,7 @@ var listMax = pageMax; var initPage = true; function initCard() { - var loadIndex = layer.msg('加载中', { - icon: 16, - shade: 0.4 - }); + var loadIndex = showLoadingDialog(); getAllLive(pageIndex, pageMax) .then(data => { listCount = data.count; diff --git a/Web/js/CommonConfig.js b/Web/js/CommonConfig.js index dab9d9a..31056bc 100644 --- a/Web/js/CommonConfig.js +++ b/Web/js/CommonConfig.js @@ -57,4 +57,10 @@ function formatDate(timestamp) { const seconds = padZero(date.getSeconds()); return `${year}-${month}-${day} ${hours}:${minutes}:${seconds}`; +} +function showLoadingDialog(){ + return layer.msg('加载中', { + icon: 16, + shade: 0.4 + }) } \ No newline at end of file diff --git a/src/main/java/com/yutou/biliapi/api/LoginApi.java b/src/main/java/com/yutou/biliapi/api/LoginApi.java index 4d758bb..02e7af9 100644 --- a/src/main/java/com/yutou/biliapi/api/LoginApi.java +++ b/src/main/java/com/yutou/biliapi/api/LoginApi.java @@ -37,4 +37,11 @@ public interface LoginApi { , @Field("source") String source , @Field("refresh_token") String refresh_token ); + @POST("/x/passport-login/web/confirm/refresh") + @FormUrlEncoded + Call<HttpBody<LoginInfoBean>> confirmRefreshCookie( + @Field("csrf") String refresh_csrf + , @Field("refresh_token") String old_token + ); + } diff --git a/src/main/java/com/yutou/biliapi/net/BiliCookieManager.java b/src/main/java/com/yutou/biliapi/net/BiliCookieManager.java index 2edf9e0..4a36d45 100644 --- a/src/main/java/com/yutou/biliapi/net/BiliCookieManager.java +++ b/src/main/java/com/yutou/biliapi/net/BiliCookieManager.java @@ -1,26 +1,32 @@ package com.yutou.biliapi.net; +import com.alibaba.fastjson2.JSONObject; import com.yutou.biliapi.api.LoginApi; import com.yutou.biliapi.bean.login.LoginCookieDatabaseBean; import com.yutou.biliapi.bean.login.LoginInfoBean; import com.yutou.biliapi.databases.BiliBiliLoginDatabase; -import com.yutou.common.okhttp.FileBody; import com.yutou.common.okhttp.HttpBody; import com.yutou.common.okhttp.HttpLoggingInterceptor; +import com.yutou.common.utils.ConfigTools; import com.yutou.common.utils.Log; +import okhttp3.OkHttpClient; +import okhttp3.Request; import org.apache.commons.io.IOUtils; import retrofit2.Response; import javax.crypto.Cipher; import javax.crypto.spec.OAEPParameterSpec; import javax.crypto.spec.PSource; +import java.io.IOException; import java.math.BigInteger; +import java.net.URLDecoder; import java.nio.charset.StandardCharsets; import java.security.KeyFactory; import java.security.PublicKey; import java.security.spec.MGF1ParameterSpec; import java.security.spec.X509EncodedKeySpec; import java.util.Base64; +import java.util.Iterator; public class BiliCookieManager { public static final int COOKIE_INVALID = -101; @@ -66,7 +72,7 @@ public class BiliCookieManager { } private static String getRefreshCsrf(String htmlContent) { - htmlContent=htmlContent.split("<div id=\"1-name\">")[1].split("</div>")[0]; + htmlContent = htmlContent.split("<div id=\"1-name\">")[1].split("</div>")[0]; return htmlContent; } @@ -74,28 +80,65 @@ public class BiliCookieManager { try { LoginApi api = BiliLoginNetApiManager.getInstance().getLoginApi(cookie.getDedeUserID()); String correspondPath = getCorrespondPath(String.format("refresh_%d", System.currentTimeMillis())); - System.out.println("correspondPath = " + correspondPath); - Thread.sleep(300); - Response<FileBody<String>> body = api.getCorrespond(correspondPath).execute(); - if(body.code()==404){ - System.out.println("返回404"); - return false; - } - System.out.println("body.code() = " + body.code()); - String string = IOUtils.toString(body.body().getInputStream(), StandardCharsets.UTF_8); - String refreshCsrf = getRefreshCsrf(string); - System.out.println("body = " + refreshCsrf); + Log.i("correspondPath = " + correspondPath); + var body = okhttp(correspondPath, cookie); + String refreshCsrf = getRefreshCsrf(body); + Log.i("body = " + refreshCsrf); + String oldCsrf = cookie.getRefreshToken(); Response<HttpBody<LoginInfoBean>> newCookie = api.refreshCookie(cookie.getBiliJct(), refreshCsrf, "main_web", cookie.getRefreshToken()).execute(); LoginCookieDatabaseBean nc = BiliLoginNetApiManager.getInstance().getCookie(newCookie.headers(), newCookie.body()); nc.setGourl(cookie.getGourl()); nc.setSql_time(cookie.getSql_time()); BiliBiliLoginDatabase.getInstance().updateLoginCookie(nc); - System.out.println("返回正确"); + api.confirmRefreshCookie(refreshCsrf, oldCsrf).execute(); + Log.i("返回正确"); return true; } catch (Exception e) { Log.e(e); - System.out.println("返回错误"); return false; } } + + + public static String okhttp(String correspondPath, LoginCookieDatabaseBean cookie) { + JSONObject json = JSONObject.parseObject(JSONObject.toJSONString(cookie)); + StringBuilder ck = new StringBuilder(); + json.remove("sql_time"); + json.remove("gourl"); + json.remove("Expires"); + json.remove("path"); + json.remove("refresh_token"); + json.put("SESSDATA", URLDecoder.decode(json.getString("SESSDATA"), StandardCharsets.UTF_8)); + + // 构建Cookie字符串,去掉最后一个分号 + Iterator<String> keys = json.keySet().iterator(); + while (keys.hasNext()) { + String key = keys.next(); + ck.append(key).append("=").append(json.getString(key)); + if (keys.hasNext()) { + ck.append(";"); + } + } + OkHttpClient client = new OkHttpClient(); + + Request request = new Request.Builder() + .url("https://www.bilibili.com/correspond/1/" + correspondPath) + .method("GET", null) // GET请求不带body + .addHeader("Cookie", ck.toString()) + .addHeader("User-Agent", ConfigTools.getUserAgent()) + .addHeader("Accept", "*/*") + .addHeader("Host", "www.bilibili.com") + .addHeader("Connection", "keep-alive") + .build(); + + try { + okhttp3.Response execute = client.newCall(request).execute(); + while (execute.code() == 404) { + execute = client.newCall(request).execute(); + } + return IOUtils.toString(execute.body().byteStream(), StandardCharsets.UTF_8); + } catch (IOException e) { + throw new RuntimeException("Failed to execute HTTP request", e); + } + } } diff --git a/src/main/java/com/yutou/biliapi/net/BiliLoginNetApiManager.java b/src/main/java/com/yutou/biliapi/net/BiliLoginNetApiManager.java index bb4249c..2c49aa8 100644 --- a/src/main/java/com/yutou/biliapi/net/BiliLoginNetApiManager.java +++ b/src/main/java/com/yutou/biliapi/net/BiliLoginNetApiManager.java @@ -23,11 +23,9 @@ public class BiliLoginNetApiManager extends BaseApi { public static final int LOGIN_SUCCESS = 101; private static BiliLoginNetApiManager instance; - LoginApi loginApi; private BiliLoginNetApiManager() { super("https://passport.bilibili.com"); - loginApi = createApi(LoginApi.class); } public static BiliLoginNetApiManager getInstance() { @@ -48,11 +46,11 @@ public class BiliLoginNetApiManager extends BaseApi { useCookie(JSONObject.parseObject(JSONObject.toJSONString(cookie))); } } - return loginApi; + return createApi(LoginApi.class); } public void login(HttpCallback<LoginCookieDatabaseBean> callback) { - loginApi.getQRCodeGenerate().enqueue(new HttpCallback<QRCodeGenerateBean>() { + getLoginApi().getQRCodeGenerate().enqueue(new HttpCallback<QRCodeGenerateBean>() { @Override public void onResponse(Headers headers, int code, String status, QRCodeGenerateBean response, String rawResponse) { String oauthKey = response.getQrcode_key(); @@ -81,7 +79,7 @@ public class BiliLoginNetApiManager extends BaseApi { } try { - Response<HttpBody<LoginInfoBean>> response = loginApi.loginQRCode(oauthKey).execute(); + Response<HttpBody<LoginInfoBean>> response = getLoginApi().loginQRCode(oauthKey).execute(); LoginCookieDatabaseBean cookie = getCookie(response.headers(), response.body()); if (cookie != null) { cookie.setGourl(bd); diff --git a/src/main/java/com/yutou/bilibili/services/LiveService.java b/src/main/java/com/yutou/bilibili/services/LiveService.java index 89f3b29..3aa929e 100644 --- a/src/main/java/com/yutou/bilibili/services/LiveService.java +++ b/src/main/java/com/yutou/bilibili/services/LiveService.java @@ -120,7 +120,7 @@ public class LiveService { long videoTime = FFmpegUtils.getVideoTime(videoFile); long startTime = Long.parseLong(videoId); long endTime = Long.parseLong(videoId) + videoTime; - if(endTime==0){ + if(videoTime==0){ endTime=System.currentTimeMillis(); } return database.getGiftInfo(startTime, endTime); diff --git a/src/main/java/com/yutou/bilibili/services/LiveVideoDownloadService.java b/src/main/java/com/yutou/bilibili/services/LiveVideoDownloadService.java index a8ffc0f..e6383f9 100644 --- a/src/main/java/com/yutou/bilibili/services/LiveVideoDownloadService.java +++ b/src/main/java/com/yutou/bilibili/services/LiveVideoDownloadService.java @@ -278,21 +278,17 @@ public class LiveVideoDownloadService { public void onDownloadStart() { super.onDownloadStart(); VideoTask.this.onStart(); + Log.i("启动录制:" + playInfo.getRoomId()); } @Override public boolean onDownloading(double soFarBytes, double totalBytes) { - if (!isDownload) { - command.stop(); - } return super.onDownloading(soFarBytes, totalBytes); } @Override public void onDownload(File file) { super.onDownload(file); - Log.d("下载完成 "); - stop(); } }); diff --git a/src/main/java/com/yutou/common/databases/SQLiteManager.java b/src/main/java/com/yutou/common/databases/SQLiteManager.java index bed87a2..07a6049 100644 --- a/src/main/java/com/yutou/common/databases/SQLiteManager.java +++ b/src/main/java/com/yutou/common/databases/SQLiteManager.java @@ -15,7 +15,6 @@ import org.sqlite.SQLiteConfig; import java.io.File; import java.lang.reflect.Field; -import java.math.BigInteger; import java.sql.*; import java.util.*; import java.util.Date; @@ -92,7 +91,7 @@ public abstract class SQLiteManager { try { conn.close(); } catch (SQLException throwables) { - throwables.printStackTrace(); + Log.e(throwables); } } @@ -106,6 +105,7 @@ public abstract class SQLiteManager { protected <T extends AbsDatabasesBean> void add(T t) { StringBuilder sb = new StringBuilder(); + PreparedStatement statement = null; try { StringBuilder value = new StringBuilder(); @@ -127,14 +127,14 @@ public abstract class SQLiteManager { value.append(")"); sb.append(") VALUES "); sb.append(value); - PreparedStatement statement = getConnection().prepareStatement(sb.toString()); + statement = getConnection().prepareStatement(sb.toString()); int i = 1; for (String key : keySet) { if ("id".equals(key)) { continue; } - if("sql_time".equals(key)){ - statement.setLong(i++,json.getDate(key).getTime()); + if ("sql_time".equals(key)) { + statement.setLong(i++, json.getDate(key).getTime()); continue; } if (json.get(key) instanceof String) { @@ -145,21 +145,29 @@ public abstract class SQLiteManager { statement.setLong(i++, json.getLong(key)); } else if (json.get(key) instanceof Boolean) { statement.setBoolean(i++, json.getBoolean(key)); - } else if(json.get(key) instanceof Date){ + } else if (json.get(key) instanceof Date) { statement.setLong(i++, json.getDate(key).getTime()); } else { statement.setObject(i++, json.get(key)); } } statement.execute(); - statement.close(); } catch (SQLException e) { Log.e(e, sb); throw new RuntimeException(e); + } finally { + try { + if (statement != null) { + statement.closeOnCompletion(); + } + } catch (SQLException e) { + Log.e(e); + } } } protected <T extends AbsDatabasesBean> void update(T t) { + PreparedStatement statement = null; try { StringBuilder sb = new StringBuilder(); StringBuilder setPart = new StringBuilder(); @@ -180,7 +188,7 @@ public abstract class SQLiteManager { sb.append("SET ").append(setPart); sb.append(" WHERE `sql_time` = ?"); - PreparedStatement statement = getConnection().prepareStatement(sb.toString()); + statement = getConnection().prepareStatement(sb.toString()); int i = 1; for (String key : keySet) { @@ -196,7 +204,7 @@ public abstract class SQLiteManager { statement.setLong(i++, json.getLong(key)); } else if (json.get(key) instanceof Boolean) { statement.setBoolean(i++, json.getBoolean(key)); - } else if(json.get(key) instanceof Date){ + } else if (json.get(key) instanceof Date) { statement.setLong(i++, json.getDate(key).getTime()); } else { statement.setObject(i++, json.get(key)); @@ -208,11 +216,18 @@ public abstract class SQLiteManager { statement.setLong(i, id); statement.executeUpdate(); - statement.close(); } catch (SQLException e) { Log.e(e); throw new RuntimeException(e); + } finally { + try { + if (statement != null) { + statement.closeOnCompletion(); + } + } catch (SQLException e) { + Log.e(e); + } } } @@ -222,21 +237,32 @@ public abstract class SQLiteManager { protected JSONArray getJSONArray(String table, String where) { JSONArray array = new JSONArray(); + ResultSet resultSet = null; + Statement statement = null; try { - Statement statement = getConnection().createStatement(); + statement = getConnection().createStatement(); String sql = "SELECT * FROM `" + table + "`"; if (where != null) { sql += " WHERE " + where; } - ResultSet resultSet = statement.executeQuery(sql); + resultSet = statement.executeQuery(sql); while (resultSet.next()) { array.add(getSQL(resultSet)); } - resultSet.close(); - statement.closeOnCompletion(); } catch (Exception e) { Log.e(e); throw new RuntimeException(e); + } finally { + try { + if (resultSet != null) { + resultSet.close(); + } + if (statement != null) { + statement.closeOnCompletion(); + } + } catch (SQLException e) { + Log.e(e); + } } return array; } @@ -267,7 +293,9 @@ public abstract class SQLiteManager { } protected int getCount(String table) { - try (PreparedStatement preparedStatement = getConnection().prepareStatement("SELECT count(*) FROM " + table)) { + PreparedStatement preparedStatement = null; + try { + preparedStatement = getConnection().prepareStatement("SELECT count(*) FROM " + table); try (ResultSet resultSet = preparedStatement.executeQuery()) { if (resultSet.next()) { return resultSet.getInt(1); @@ -277,6 +305,14 @@ public abstract class SQLiteManager { } catch (SQLException e) { Log.e(e); throw new RuntimeException("Error executing SQL query", e); + } finally { + try { + if (preparedStatement != null) { + preparedStatement.close(); + } + } catch (SQLException e) { + Log.e(e); + } } return 0; @@ -284,54 +320,84 @@ public abstract class SQLiteManager { protected <T extends AbsDatabasesBean> List<T> get(String table, String where, Class<T> tClass) { List<T> list = new ArrayList<>(); + Statement statement = null; + ResultSet resultSet=null; try { - Statement statement = getConnection().createStatement(); + statement = getConnection().createStatement(); String sql = "SELECT * FROM `" + table + "`"; if (where != null) { sql += " WHERE " + where; } - ResultSet resultSet = statement.executeQuery(sql); + resultSet = statement.executeQuery(sql); while (resultSet.next()) { list.add(getSQL(resultSet).to(tClass)); } - resultSet.close(); - statement.closeOnCompletion(); } catch (Exception e) { Log.e(e); throw new RuntimeException(e); + } finally { + try { + if (statement != null) { + statement.closeOnCompletion(); + } + if(resultSet!=null){ + resultSet.close(); + } + } catch (SQLException e) { + Log.e(e); + } } return list; } protected JSONArray get(String sql) { JSONArray json = new JSONArray(); + ResultSet resultSet = null; + Statement statement=null; try { - ResultSet resultSet; - Statement statement = getConnection().createStatement(); + statement = getConnection().createStatement(); resultSet = statement.executeQuery(sql); while (resultSet.next()) { json.add(getSQL(resultSet)); } - statement.closeOnCompletion(); } catch (Exception e) { throw new RuntimeException(e); + } finally { + try { + if (resultSet != null) { + resultSet.close(); + } + if(statement!=null){ + statement.closeOnCompletion(); + } + } catch (SQLException e) { + Log.e(e); + } } return json; } protected <T extends AbsDatabasesBean> boolean delete(T t) { + Statement statement = null; try { String id = DateUtils.format(t.getSql_time(), "yyyy-MM-dd HH:mm:ss.SSS"); - Statement statement = getConnection().createStatement(); + statement = getConnection().createStatement(); StringBuilder sb = new StringBuilder(); sb.append("DELETE FROM `").append(t.getTableName()).append("` "); sb.append(" WHERE `sql_time` = ").append("'").append(id).append("'"); int ret = statement.executeUpdate(sb.toString()); - statement.close(); return ret != 0; } catch (Exception e) { Log.e(e); throw new RuntimeException(e); + } finally { + try { + if (statement != null) { + statement.closeOnCompletion(); + } + } catch (SQLException e) { + Log.e(e); + } } } @@ -372,8 +438,9 @@ public abstract class SQLiteManager { private void createSqlOfTable(BuildSqlTable table) { String tableName = table.getName(); + Statement statement = null; try { - Statement statement = getConnection().createStatement(); + statement = getConnection().createStatement(); List<BuildSqlItem> items = table.getItem(); StringBuilder sql = new StringBuilder(); sql.append("CREATE TABLE `") @@ -399,9 +466,15 @@ public abstract class SQLiteManager { sql.append(");"); Log.i("创建表 > " + sql.toString()); statement.execute(sql.toString().replace(",);", ");")); - statement.closeOnCompletion(); } catch (Exception e) { Log.e(e); + try { + if (statement != null) { + statement.closeOnCompletion(); + } + } catch (SQLException e1) { + Log.e(e1); + } } } diff --git a/src/main/java/com/yutou/common/okhttp/api/BaseApi.java b/src/main/java/com/yutou/common/okhttp/api/BaseApi.java index ff82369..25bacf3 100644 --- a/src/main/java/com/yutou/common/okhttp/api/BaseApi.java +++ b/src/main/java/com/yutou/common/okhttp/api/BaseApi.java @@ -46,8 +46,10 @@ public class BaseApi { } public void useCookie(JSONObject json){ StringBuilder ck = new StringBuilder(); + json.remove("sql_time"); + json.remove("gourl"); for (String key : json.keySet()) { - ck.append(key).append("=").append(json.getString(key)).append("; "); + ck.append(key).append("=").append(json.getString(key)).append(";"); } headers.put("Cookie", ck.toString()); setHeaders(headers); diff --git a/src/main/java/com/yutou/common/utils/FFmpegUtils.java b/src/main/java/com/yutou/common/utils/FFmpegUtils.java index 3d0dd7a..21d69c2 100644 --- a/src/main/java/com/yutou/common/utils/FFmpegUtils.java +++ b/src/main/java/com/yutou/common/utils/FFmpegUtils.java @@ -31,7 +31,7 @@ public class FFmpegUtils extends AbsVideoRecord { @Override public boolean check(String roomId) { try { - if(!pidMap.containsKey(roomId)){ + if (!pidMap.containsKey(roomId)) { return false; } return ProcessUtils.isProcessRunning(pidMap.get(roomId).pid); @@ -46,7 +46,7 @@ public class FFmpegUtils extends AbsVideoRecord { try { // ProcessUtils.killProcess(pidMap.get(roomId).pid); Task utils = pidMap.get(roomId); - if(utils != null) { + if (utils != null) { utils.kill(); } } catch (Exception e) { @@ -155,7 +155,6 @@ public class FFmpegUtils extends AbsVideoRecord { * @param video 视频文件 * @return 毫秒 */ - @Deprecated public static long getVideoTime(File video) { 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() + "\""; @@ -167,6 +166,9 @@ public class FFmpegUtils extends AbsVideoRecord { String data; inputStream.read(bytes); data = new String(bytes); + if (!StringUtils.hasText(data)) { + data = "0"; + } inputStream.close(); process.destroy(); process.exitValue(); @@ -204,9 +206,10 @@ public class FFmpegUtils extends AbsVideoRecord { downloadInterface.onDownloadStart(); } pidMap.put(uid, this); + long startTimer = System.currentTimeMillis(); while (inputStream.read(bytes) > -1) { if (downloadInterface != null) { - downloadInterface.onDownloading(0, 0); + downloadInterface.onDownloading(System.currentTimeMillis() - startTimer, 0); } } pidMap.remove(uid); diff --git a/src/main/java/com/yutou/common/utils/WebClient.java b/src/main/java/com/yutou/common/utils/WebClient.java index 0e3bfef..15561cb 100644 --- a/src/main/java/com/yutou/common/utils/WebClient.java +++ b/src/main/java/com/yutou/common/utils/WebClient.java @@ -25,13 +25,16 @@ public class WebClient { } public WebDriver getWebDriver() { - if (driver == null) { - driver = new ChromeDriver(getOptions()); + if(driver!=null){ + driver.quit(); + driver.close(); } + driver = new ChromeDriver(getOptions()); return driver; } public void quit() { + driver.close(); driver.quit(); driver = null; } @@ -86,6 +89,7 @@ public class WebClient { public ChromeOptions getOptions() { ChromeOptions options = new ChromeOptions(); options.addArguments("--remote-allow-origins=*"); + options.addArguments("--auto-open-devtools-for-tabs"); // options.addArguments("--disable-gpu"); // options.addArguments("blink-settings=imagesEnabled=false"); String headless = RedisTools.get("chromedrive_headless");