add 新增了批量订阅 add

This commit is contained in:
2024-11-21 18:29:19 +08:00
parent b15d1c917f
commit 35b014c585
39 changed files with 1871 additions and 280 deletions

View File

@@ -4,34 +4,22 @@ import com.alibaba.fastjson2.JSONArray;
import com.alibaba.fastjson2.JSONObject;
import com.yutou.biliapi.api.LoginApi;
import com.yutou.biliapi.bean.login.CheckCookieBean;
import com.yutou.biliapi.bean.login.LoginCookieDatabaseBean;
import com.yutou.biliapi.bean.login.LoginUserDatabaseBean;
import com.yutou.biliapi.bean.login.UserInfoBean;
import com.yutou.biliapi.databases.BiliBiliLoginDatabase;
import com.yutou.biliapi.net.BiliCookieManager;
import com.yutou.biliapi.net.BiliLoginNetApiManager;
import com.yutou.biliapi.net.BiliUserNetApiManager;
import com.yutou.bilibili.datas.ResultData;
import com.yutou.bilibili.datas.ReturnCode;
import com.yutou.bilibili.services.LiveLoginService;
import com.yutou.common.okhttp.HttpBody;
import com.yutou.common.okhttp.HttpCallback;
import com.yutou.common.okhttp.HttpLoggingInterceptor;
import com.yutou.common.utils.Log;
import com.yutou.common.utils.RedisTools;
import jakarta.annotation.Resource;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import jakarta.servlet.http.HttpSession;
import okhttp3.Headers;
import org.springframework.stereotype.Controller;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import retrofit2.Response;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;
@@ -82,7 +70,7 @@ public class BiliUserController {
} else {
returnCode = ReturnCode.RC300;
}
JSONObject login = login(loginToken.toString());
JSONObject login = loginService.login(loginToken.toString());
if (login != null && login.containsKey("qrcode")) {
return ResultData.success(login, -1, returnCode);
} else if (login != null) {
@@ -92,71 +80,41 @@ public class BiliUserController {
return ResultData.success(loginToken.toString(), -1, returnCode);
}
private JSONObject login(String loginToken) {
String ret = RedisTools.get(loginToken);
if (StringUtils.hasText(ret)) {
JSONObject json = JSONObject.parseObject(ret);
if (json.getIntValue("code") == BiliLoginNetApiManager.LOGIN_SUCCESS) {
RedisTools.remove(loginToken);
}
return json;
@ResponseBody
@RequestMapping("/user/refreshCookie")
public JSONObject refreshCookie(String uid) {
if(!StringUtils.hasText(uid)){
return ResultData.fail(ReturnCode.RC999);
}
if(loginService.refreshUserCookie(uid)){
return ResultData.success(ReturnCode.RC100);
}else{
return ResultData.fail(ReturnCode.RC999);
}
BiliLoginNetApiManager.getInstance().login(new HttpCallback<LoginCookieDatabaseBean>() {
@Override
public void onResponse(Headers headers, int code, String status, LoginCookieDatabaseBean response, String rawResponse) {
JSONObject json = new JSONObject();
json.put("code", code);
if (code == BiliLoginNetApiManager.LOGIN_QRCODE) {
json.put("qrcode", rawResponse);
} else if (code == BiliLoginNetApiManager.LOGIN_SUCCESS) {
Response<HttpBody<UserInfoBean>> execute = null;
try {
execute = BiliUserNetApiManager.getInstance().getUserApi(response).getUserInfo().execute();
if (execute.isSuccessful()) {
if (execute.body() != null) {
UserInfoBean data = execute.body().getData();
LoginUserDatabaseBean userBean = new LoginUserDatabaseBean(data);
BiliBiliLoginDatabase.getInstance().initData(response, userBean).close();
json.put("user", data);
}
}
} catch (IOException e) {
throw new RuntimeException(e);
}
}
RedisTools.set(loginToken, json.toString(), 60);
}
@Override
public void onFailure(Throwable throwable) {
}
});
return null;
}
public static void main(String[] args) {
// LiveLoginService loginService = new LiveLoginService();
/* List<LoginUserDatabaseBean> allUser = loginService.getAllUser();
LiveLoginService loginService = new LiveLoginService();
List<LoginUserDatabaseBean> allUser = loginService.getAllUser();
for (LoginUserDatabaseBean user : allUser) {
System.out.println(user.getUserInfo().getMid());
LoginApi api = BiliLoginNetApiManager.getInstance().getLoginApi(user.getUserInfo().getMid());
try {
CheckCookieBean cookie = api.checkCookie().execute().body().getData();
System.out.println("cookie = " + cookie);
if(cookie.isRefresh()){
BiliCookieManager.resetCookie(loginService.getCookie(user.getUserInfo().getMid()));
if (cookie.isRefresh()) {
boolean flag = BiliCookieManager.refreshCookie(loginService.getCookie(user.getUserInfo().getMid()));
System.out.println("flag = " + flag);
}
} catch (IOException e) {
Log.e(e);
}finally {
return;
} finally {
;
}
}*/
}
// HttpLoggingInterceptor.setLog(true);
// BiliCookieManager.resetCookie(loginService.getCookie("3493115839121644"));
RedisTools.set("test", "test", 10000);
System.out.println(RedisTools.get("test"));
}
}

View File

@@ -3,12 +3,16 @@ package com.yutou.bilibili.Controllers;
import com.alibaba.fastjson2.JSONArray;
import com.alibaba.fastjson2.JSONObject;
import com.yutou.biliapi.bean.live.database.LiveConfigDatabaseBean;
import com.yutou.biliapi.bean.login.LoginUserDatabaseBean;
import com.yutou.biliapi.bean.user.UserFollowingsBean;
import com.yutou.bilibili.Tools.Tools;
import com.yutou.bilibili.datas.ResultData;
import com.yutou.bilibili.datas.ReturnCode;
import com.yutou.bilibili.services.LiveConfigService;
import com.yutou.bilibili.services.LiveLoginService;
import com.yutou.bilibili.services.LiveUserService;
import jakarta.annotation.Resource;
import lombok.val;
import jakarta.servlet.http.HttpServletRequest;
import org.springframework.core.io.FileSystemResource;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Controller;
@@ -17,8 +21,8 @@ import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;
import java.math.BigInteger;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
@Controller
@@ -26,19 +30,99 @@ import java.util.List;
public class LiveConfigController {
@Resource
LiveConfigService configService;
@Resource
LiveUserService userService;
@Resource
LiveLoginService loginService;
@ResponseBody
@RequestMapping("follow")
public JSONObject getFollow(String userId, int page, int limit) {
UserFollowingsBean bean = userService.getUserFollowings(userId, page, limit);
if (bean == null) {
return ResultData.fail(ReturnCode.RC999);
}
return ResultData.success(bean, bean.getTotal());
}
@ResponseBody
@RequestMapping("follow/add")
public JSONObject addFollow(String uid, String anchorId) {
int flag = userService.followAnchor(uid, anchorId);
if (flag == 1) {
return ResultData.success(ReturnCode.RC100);
} else {
return switch (flag) {
case 0 -> ResultData.fail(-flag, "关注失败");
case -1 -> ResultData.fail(-flag, "关注失败,程序异常");
case -2 -> ResultData.fail(-flag, "关注失败UP未开通直播间");
case -3 -> ResultData.fail(-flag, "账号可能被风控,请从配置页手动配置");
case 2 -> ResultData.fail(-flag, "已在关注列表");
default -> ResultData.fail(ReturnCode.RC999);
};
}
}
@ResponseBody
@RequestMapping("follow/addList")
public JSONObject addFollowList(String uid, String array) {
if (!StringUtils.hasText(array)) {
return ResultData.fail(ReturnCode.RC500);
}
JSONArray jsonArray = JSONArray.parseArray(array);
List<UserFollowingsBean.Follow> list = jsonArray.stream()
.map(o -> {
JSONObject jsonObject = (JSONObject) o;
UserFollowingsBean.Follow follow = new UserFollowingsBean.Follow();
follow.setMid(jsonObject.getString("mid"));
follow.setUname(jsonObject.getString("uname"));
return follow;
}).toList();
return ResultData.success(userService.followAll(uid,list));
}
@ResponseBody
@RequestMapping("follow/check")
public JSONObject checkFollow(String userId) {
List<ResultData<String>> list = new ArrayList<>();
if (StringUtils.hasText(userId)) {
list.add(getFollowStatus(userId, userService.checkFollow(userId)));
} else {
for (LoginUserDatabaseBean user : loginService.getAllUser()) {
list.add(getFollowStatus(user.getUserInfo().getMid(), userService.checkFollow(user.getUserInfo().getMid())));
}
}
return ResultData.success(list);
}
@ResponseBody
@RequestMapping("follow/all")
public JSONObject getAllFollow(String userId) {
return ResultData.success(userService.followAll(userId));
}
@ResponseBody
@RequestMapping("follow/confirm")
public JSONObject confirmAllFollow(String userId) {
userService.confirmFollow(userId);
return ResultData.success(ReturnCode.RC100);
}
@RequestMapping(value = "set", method = RequestMethod.POST)
@ResponseBody
public JSONObject setConfig(String url, LiveConfigDatabaseBean bean) {
if(!bean.verifyLiveTimer()){
return ResultData.fail(ReturnCode.RC999.getCode(),"视频录制时间格式错误");
if (!bean.verifyLiveTimer()) {
return ResultData.fail(ReturnCode.RC999.getCode(), "视频录制时间格式错误");
}
if(!bean.verifyDanmuTimer()){
return ResultData.fail(ReturnCode.RC999.getCode(),"弹幕录制时间格式错误");
if (!bean.verifyDanmuTimer()) {
return ResultData.fail(ReturnCode.RC999.getCode(), "弹幕录制时间格式错误");
}
if(!url.startsWith("https://live.bilibili.com/")){
if(!configService.checkUrl(url)){
return ResultData.fail(ReturnCode.RC999.getCode(),"房间地址/房间号错误");
if (!url.startsWith("https://live.bilibili.com/")) {
if (!configService.checkUrl(url)) {
return ResultData.fail(ReturnCode.RC999.getCode(), "房间地址/房间号错误");
}
}
LiveConfigDatabaseBean config = configService.addConfig(url, bean);
@@ -51,11 +135,11 @@ public class LiveConfigController {
@RequestMapping(value = "update", method = RequestMethod.POST)
@ResponseBody
public JSONObject updateConfig(String roomId, LiveConfigDatabaseBean bean) {
if(!bean.verifyLiveTimer()){
return ResultData.fail(ReturnCode.RC999.getCode(),"视频录制时间格式错误");
if (!bean.verifyLiveTimer()) {
return ResultData.fail(ReturnCode.RC999.getCode(), "视频录制时间格式错误");
}
if(!bean.verifyDanmuTimer()){
return ResultData.fail(ReturnCode.RC999.getCode(),"弹幕录制时间格式错误");
if (!bean.verifyDanmuTimer()) {
return ResultData.fail(ReturnCode.RC999.getCode(), "弹幕录制时间格式错误");
}
LiveConfigDatabaseBean config = configService.updateConfig(new String(roomId), bean);
@@ -80,15 +164,15 @@ public class LiveConfigController {
@RequestMapping(value = "all", method = RequestMethod.GET)
@ResponseBody
public JSONObject getAllConfig(int page,int limit) {
List<LiveConfigDatabaseBean> config ;
if(page==-1||limit==-1) {
config=configService.getAllConfig();
}else{
config=configService.getConfigs(page, limit);
public JSONObject getAllConfig(int page, int limit) {
List<LiveConfigDatabaseBean> config;
if (page == -1 || limit == -1) {
config = configService.getAllConfig();
} else {
config = configService.getConfigs(page, limit);
}
if (config != null) {
return ResultData.success(config,configService.getConfigCount());
return ResultData.success(config, configService.getConfigCount());
}
return ResultData.fail(ReturnCode.RC999);
}
@@ -96,7 +180,7 @@ public class LiveConfigController {
@RequestMapping(value = "delete", method = RequestMethod.GET)
@ResponseBody
public JSONObject deleteConfig(String roomId) {
if ("0".equals(roomId)|| !StringUtils.hasText(roomId)) {
if ("0".equals(roomId) || !StringUtils.hasText(roomId)) {
return ResultData.fail(ReturnCode.RC999);
}
boolean flag = configService.deleteConfig(roomId);
@@ -110,4 +194,27 @@ public class LiveConfigController {
public ResponseEntity<FileSystemResource> getFace(String roomId) {
return Tools.getFile(configService.getFace(roomId));
}
private ResultData<String> getFollowStatus(String userId, ResultData<UserFollowingsBean.Follow> follow) {
ResultData<String> resultData = new ResultData<>();
resultData.setData(userId);
if (follow == null) {
resultData.setMessage(userId + ":没有相关任务");
resultData.setStatus(-1);
return resultData;
}
resultData.setCount(follow.getCount());
if (follow.getStatus() == -100) {
resultData.setMessage(userId + ":处理完成");
resultData.setStatus(-100);
} else {
if (follow.getData() == null) {
resultData.setMessage(userId + ":正在等待");
} else {
resultData.setMessage(userId + ":正在处理:" + follow.getData().getUname() + "(" + follow.getStatus() + "/" + follow.getCount() + ")");
}
resultData.setStatus(follow.getStatus());
}
return resultData;
}
}

View File

@@ -25,4 +25,10 @@ public class LiveController {
public JSONObject getLiveList(int page,int limit) {
return ResultData.success(liveService.getLiveList(page,limit), liveService.getConfigCount());
}
@RequestMapping("/live/gift/info")
@ResponseBody
public JSONObject download(String roomId, String videoId) {
return ResultData.success(liveService.getGiftInfo(roomId,videoId));
}
}

View File

@@ -94,10 +94,9 @@ public class VideoFileController {
// 返回带有 MIME 类型的数据 URI
return base64Image;
} catch (Exception e) {
e.printStackTrace();
} catch (Exception ignored) {
return "/assets/def.png";
}
return "";
}
@RequestMapping("/video/play")

View File

@@ -3,52 +3,85 @@ package com.yutou.bilibili.Tools;
import com.yutou.common.utils.Log;
import org.springframework.util.StringUtils;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.time.Duration;
import java.time.LocalDate;
import java.time.LocalTime;
import java.time.format.DateTimeFormatter;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
public class DateFormatUtils {
public static String format(Date date, String format) {
return new SimpleDateFormat(format).format(date);
private final Map<String, ThreadLocal<SimpleDateFormat>> formats = new ConcurrentHashMap<>();
private static volatile DateFormatUtils utils;
public static final String DEFAULT_PATTERN = "yyyy-MM-dd HH:mm:ss.SSS";
private DateFormatUtils() {}
public static DateFormatUtils getInstance() {
if (utils == null) {
synchronized (DateFormatUtils.class) {
if (utils == null) {
utils = new DateFormatUtils();
}
}
}
return utils;
}
public static String format(long time, String format) {
return new SimpleDateFormat(format).format(new Date(time));
public String format(Date date, String format) {
getFormat(format).applyPattern(format);
return getFormat(format).format(date);
}
public static String format(long time) {
return new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS").format(new Date(time));
public String format(long time, String format) {
return getFormat(format).format(new Date(time));
}
public static String format(Date date) {
return new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS").format(date);
public String format(long time) {
if (time < 1000000000) {
time *= 1000;
}
return getFormat().format(new Date(time));
}
public static String format() {
return new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS").format(new Date());
public String format(Date date) {
return getFormat().format(date);
}
public static Date parseTimer(String date) {
public String format() {
return getFormat().format(new Date());
}
public Date parseTimer(String date) {
return parse(date, "HH:mm:ss");
}
public static Date parse(String date, String format) {
public Date parse(String date, String format) {
try {
return new SimpleDateFormat(format).parse(date);
} catch (Exception e) {
Log.e(e);
return getFormat(format).parse(date);
} catch (ParseException e) {
System.err.println("Error parsing date: " + e.getMessage());
return null;
}
}
public static String parseString(String date,String format){
Date time = parse(date, format);
return format(time,format);
}
public static boolean checkTime(List<String> weeks, String recordDate) {
public String parseString(String date, String format) {
Date time = parse(date, format);
return format(time, format);
}
public String formatMillis(long millis) {
Duration duration = Duration.ofMillis(millis);
int seconds = (int) (duration.getSeconds() % 60);
int minutes = (int) ((duration.getSeconds() / 60) % 60);
int hours = (int) (duration.getSeconds() / 3600);
return String.format("%02d:%02d:%02d", hours, minutes, seconds);
}
public boolean checkTime(List<String> weeks, String recordDate) {
if (!StringUtils.hasText(recordDate)) {
recordDate = "00:00:00 - 23:59:59";
}
@@ -78,6 +111,11 @@ public class DateFormatUtils {
(currentTime.isBefore(endTime) || currentTime.equals(endTime));
return isWithinRange && isSpecifiedWeekDay;
}
private SimpleDateFormat getFormat() {
return getFormat(DEFAULT_PATTERN);
}
private SimpleDateFormat getFormat(String format) {
return formats.computeIfAbsent(format, key -> ThreadLocal.withInitial(() -> new SimpleDateFormat(key))).get();
}
}

View File

@@ -13,6 +13,7 @@ public class LiveData extends BaseBean {
private String anchorFace;
private String title;
private String cover;
private String liveTime;
private boolean isLive;
private boolean isDanmu;
private boolean isDownloadVideo;

View File

@@ -62,8 +62,8 @@ public class LiveDanmuService {
long videoTime = FFmpegUtils.getVideoTime(videoFile) + videoDatabaseBean.getStartTime().getTime();
Log.i("开始时间:" + videoDatabaseBean.getStartTime().getTime());
Log.i("结束时间:" + videoTime);
String startTime = DateFormatUtils.format(videoDatabaseBean.getStartTime());
String endTime = DateFormatUtils.format(videoTime);
String startTime = DateFormatUtils.getInstance().format(videoDatabaseBean.getStartTime());
String endTime = DateFormatUtils.getInstance().format(videoTime);
List<LiveDanmuDatabaseBean> danmus = database.getOfTime(startTime, endTime, LiveDanmuDatabaseBean.class);
Log.i("弹幕数量:" + danmus.size());
AssTools assTools = new AssTools(videoFile.getName().replace(".flv", ""), videoDatabaseBean.getStartTime());
@@ -86,14 +86,7 @@ public class LiveDanmuService {
public LiveVideoDanmu getDanmu(String roomId, String videoId) {
LiveVideoDanmu danmus = new LiveVideoDanmu();
BiliLiveDatabase liveDatabase = new BiliLiveDatabase(LiveRoomConfig.buildConfig(roomId));
LiveVideoDatabaseBean videoBean = null;
for (LiveVideoDatabaseBean info : liveDatabase.getLiveInfos()) {
System.out.println(videoId + " " + info.getSql_time().getTime());
if (videoId.trim().equals(String.valueOf(info.getSql_time().getTime()))) {
videoBean = info;
break;
}
}
LiveVideoDatabaseBean videoBean = liveDatabase.getVideo(videoId);
if (videoBean == null) {
return new LiveVideoDanmu();
}
@@ -104,8 +97,8 @@ public class LiveDanmuService {
long videoTime = FFmpegUtils.getVideoTime(videoFile);
long startTime = Long.parseLong(videoId);
long endTime = Long.parseLong(videoId) + videoTime;
List<LiveDanmuDatabaseBean> danmuList = liveDatabase.getOfTime(DateFormatUtils.format(startTime), DateFormatUtils.format(endTime), LiveDanmuDatabaseBean.class);
List<LiveSuperChatDatabaseBean> superChatList = liveDatabase.getOfTime(DateFormatUtils.format(startTime), DateFormatUtils.format(endTime), LiveSuperChatDatabaseBean.class);
List<LiveDanmuDatabaseBean> danmuList = liveDatabase.getOfTime(DateFormatUtils.getInstance().format(startTime), DateFormatUtils.getInstance().format(endTime), LiveDanmuDatabaseBean.class);
List<LiveSuperChatDatabaseBean> superChatList = liveDatabase.getOfTime(DateFormatUtils.getInstance().format(startTime), DateFormatUtils.getInstance().format(endTime), LiveSuperChatDatabaseBean.class);
for (LiveDanmuDatabaseBean bean : danmuList) {
LiveVideoDanmu.Danmu danmu = createDanmu(bean, startTime);
danmus.getDanmu().add(danmu);

View File

@@ -1,17 +1,24 @@
package com.yutou.bilibili.services;
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.bean.login.LoginUserDatabaseBean;
import com.yutou.biliapi.bean.login.QRCodeGenerateBean;
import com.yutou.biliapi.bean.user.UserInfoBean;
import com.yutou.biliapi.databases.BiliBiliLoginDatabase;
import com.yutou.biliapi.net.BiliCookieManager;
import com.yutou.biliapi.net.BiliLoginNetApiManager;
import com.yutou.biliapi.net.BiliUserNetApiManager;
import com.yutou.common.okhttp.HttpBody;
import com.yutou.common.okhttp.HttpCallback;
import com.yutou.common.utils.RedisTools;
import okhttp3.Headers;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;
import retrofit2.Response;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
@Service
@@ -57,10 +64,59 @@ public class LiveLoginService {
return loginDatabase.getAllUser();
}
public List<LoginCookieDatabaseBean> getAllUserCookie(){
public List<LoginCookieDatabaseBean> getAllUserCookie() {
return loginDatabase.getAllCookies();
}
public LoginCookieDatabaseBean getCookie(String userId) {
return loginDatabase.getCookie(userId);
}
public JSONObject login(String loginToken) {
String ret = RedisTools.get(loginToken);
if (StringUtils.hasText(ret)) {
JSONObject json = JSONObject.parseObject(ret);
if (json.getIntValue("code") == BiliLoginNetApiManager.LOGIN_SUCCESS) {
RedisTools.remove(loginToken);
}
return json;
}
BiliLoginNetApiManager.getInstance().login(new HttpCallback<LoginCookieDatabaseBean>() {
@Override
public void onResponse(Headers headers, int code, String status, LoginCookieDatabaseBean response, String rawResponse) {
JSONObject json = new JSONObject();
json.put("code", code);
if (code == BiliLoginNetApiManager.LOGIN_QRCODE) {
json.put("qrcode", rawResponse);
} else if (code == BiliLoginNetApiManager.LOGIN_SUCCESS) {
Response<HttpBody<UserInfoBean>> execute = null;
try {
execute = BiliUserNetApiManager.getInstance().getUserApi(response).getUserInfo().execute();
if (execute.isSuccessful()) {
if (execute.body() != null) {
UserInfoBean data = execute.body().getData();
LoginUserDatabaseBean userBean = new LoginUserDatabaseBean(data);
BiliBiliLoginDatabase.getInstance().initData(response, userBean).close();
json.put("user", data);
}
}
} catch (IOException e) {
throw new RuntimeException(e);
}
}
RedisTools.set(loginToken, json.toString(), 60);
}
@Override
public void onFailure(Throwable throwable) {
}
});
return null;
}
public boolean refreshUserCookie(String uid) {
return BiliCookieManager.refreshCookie(loginDatabase.getCookie(uid));
}
}

View File

@@ -4,24 +4,27 @@ import com.alibaba.fastjson2.JSONArray;
import com.alibaba.fastjson2.JSONObject;
import com.yutou.biliapi.api.LiveApi;
import com.yutou.biliapi.bean.live.LiveAnchorInfo;
import com.yutou.biliapi.bean.live.LiveRoomConfig;
import com.yutou.biliapi.bean.live.LiveRoomInfo;
import com.yutou.biliapi.bean.live.LiveRoomPlayInfo;
import com.yutou.biliapi.bean.live.database.LiveConfigDatabaseBean;
import com.yutou.biliapi.bean.live.database.LiveVideoDatabaseBean;
import com.yutou.biliapi.databases.BiliLiveConfigDatabase;
import com.yutou.biliapi.databases.BiliLiveDatabase;
import com.yutou.biliapi.net.BiliLiveNetApiManager;
import com.yutou.bilibili.Tools.DateFormatUtils;
import com.yutou.bilibili.datas.web.LiveData;
import com.yutou.common.okhttp.BaseBean;
import com.yutou.common.okhttp.HttpLoggingInterceptor;
import com.yutou.common.utils.FFmpegUtils;
import com.yutou.common.utils.Log;
import jakarta.annotation.Resource;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import java.util.Map;
import java.util.*;
@Service
public class LiveService {
@@ -36,26 +39,34 @@ public class LiveService {
liveConfigDatabase = new BiliLiveConfigDatabase();
api = BiliLiveNetApiManager.getInstance().getApi(null);
}
public int getConfigCount(){
public int getConfigCount() {
return liveConfigDatabase.getAllConfig().size();
}
public List<LiveData> getLiveList(int page,int limit) {
public List<LiveData> getLiveList(int page, int limit) {
List<LiveConfigDatabaseBean> allConfig = liveConfigDatabase.getAllConfig();
List<LiveData> liveDataList = new ArrayList<>();
JSONArray uids=new JSONArray();
JSONObject param=new JSONObject();
if (allConfig.isEmpty()) {
return liveDataList;
}
JSONArray uids = new JSONArray();
JSONObject param = new JSONObject();
for (LiveConfigDatabaseBean bean : allConfig) {
uids.add(bean.getAnchorUid());
}
param.put("uids",uids);
param.put("uids", uids);
try {
Map<String, LiveAnchorInfo> map = api.getLiveRoomStatus(param).execute().body().getData();
if (map == null) {
map = new HashMap<>();
}
List<LiveAnchorInfo> onlineList = new ArrayList<>();
List<LiveAnchorInfo> offlineList = new ArrayList<>();
for (LiveAnchorInfo info : map.values()) {
if(info.getLiveStatus()==1){
if (info.getLiveStatus() == 1) {
onlineList.add(info);
}else{
} else {
offlineList.add(info);
}
}
@@ -73,6 +84,11 @@ public class LiveService {
liveData.setAnchorUid(info.getUid());
liveData.setAnchorName(info.getUname());
liveData.setAnchorFace(info.getFace());
if (info.getLiveTime() == 0) {
liveData.setLiveTime("未开播");
} else {
liveData.setLiveTime(DateFormatUtils.getInstance().formatMillis(System.currentTimeMillis() - info.getLiveTime()*1000));
}
liveData.setDownloadVideo(videoDownloadService.checkDownload(info.getRoomId()));
liveData.setDanmu(danmuService.check(info.getRoomId()));
liveData.setTitle(info.getTitle());
@@ -91,9 +107,25 @@ public class LiveService {
return liveDataList;
}
public JSONObject getGiftInfo(String roomId, String videoId) {
BiliLiveDatabase database = new BiliLiveDatabase(LiveRoomConfig.buildConfig(roomId));
LiveVideoDatabaseBean videoBean = database.getVideo(videoId);
if (videoBean == null) {
return null;
}
File videoFile = new File(videoBean.getPath().replace(".flv", ".mp4"));
if (!videoFile.exists()) {
videoFile = new File(videoBean.getPath());
}
long videoTime = FFmpegUtils.getVideoTime(videoFile);
long startTime = Long.parseLong(videoId);
long endTime = Long.parseLong(videoId) + videoTime;
return database.getGiftInfo(startTime, endTime);
}
public static void main(String[] args) {
HttpLoggingInterceptor.setLog(true);
LiveService service=new LiveService();
LiveService service = new LiveService();
List<LiveData> data = service.getLiveList(1, 16);
System.out.println(data.size());
}

View File

@@ -0,0 +1,192 @@
package com.yutou.bilibili.services;
import com.alibaba.fastjson2.JSONObject;
import com.yutou.biliapi.api.UserApi;
import com.yutou.biliapi.bean.live.SpiBean;
import com.yutou.biliapi.bean.live.database.LiveConfigDatabaseBean;
import com.yutou.biliapi.bean.login.LoginCookieDatabaseBean;
import com.yutou.biliapi.bean.user.UserFollowingsBean;
import com.yutou.biliapi.bean.user.UserHomeInfoBean;
import com.yutou.biliapi.bean.user.UserInfoBean;
import com.yutou.biliapi.databases.BiliBiliLoginDatabase;
import com.yutou.biliapi.net.BiliCookieManager;
import com.yutou.biliapi.net.BiliUserNetApiManager;
import com.yutou.biliapi.net.WebSignManager;
import com.yutou.bilibili.datas.ResultData;
import com.yutou.common.okhttp.HttpBody;
import com.yutou.common.utils.Log;
import jakarta.annotation.Resource;
import lombok.Getter;
import lombok.Setter;
import org.springframework.stereotype.Service;
import retrofit2.Response;
import java.io.IOException;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.TreeMap;
@Service
public class LiveUserService {
@Resource
LiveLoginService userLoginService;
@Resource
LiveConfigService configService;
public UserFollowingsBean getUserFollowings(String userId, int page, int num) {
LoginCookieDatabaseBean cookie = userLoginService.getCookie(userId);
UserApi api = BiliUserNetApiManager.getInstance().getUserApi(cookie);
try {
HttpBody<UserFollowingsBean> body = api.getFollowings(cookie.getDedeUserID(), "", num, page).execute().body();
return body.getData();
} catch (IOException e) {
throw new RuntimeException(e);
}
}
public UserHomeInfoBean getUserHome(LoginCookieDatabaseBean cookie, String mid, UserInfoBean userInfo, SpiBean spiBean) {
try {
TreeMap<String, Object> map = new TreeMap<>();
map.put("mid", mid);
// map.put("web_location", "1550101");
// map.put("dm_img_inter", JSONObject.parseObject("{\"ds\":[],\"wh\":[5746,6797,28],\"of\":[276,552,276]}"));
map.put("dm_img_list", "[]");
map.put("dm_img_str", "V2ViR0wgMS4wIChPcGVuR0wgRVMgMi4wIENocm9taXVtKQ");
map.put("dm_cover_img_str", "QU5HTEUgKEFNRCwgQU1EIFJhZGVvbiA3ODBNIEdyYXBoaWNzICgweDAwMDAxNUJGKSBEaXJlY3QzRDExIHZzXzVfMCBwc181XzAsIEQzRDExKUdvb2dsZSBJbmMuIChBTU");
map = WebSignManager.getWebSign(map, userInfo);
HashMap<String, String> tmap = new HashMap<>();
tmap.put("buvid3", spiBean.getB_3());
tmap.put("buvid4", spiBean.getB_4());
Response<HttpBody<UserHomeInfoBean>> execute = BiliUserNetApiManager.getInstance().getUserApi(cookie, tmap).getWbiAccInfo(map).execute();
if (execute.body().getCode() == -352) {
return null;
}
return execute.body().getData();
} catch (Exception e) {
Log.e(e);
}
return null;
}
public int followAnchor(String uid, String anchorUid) {
try {
LoginCookieDatabaseBean cookie = BiliBiliLoginDatabase.getInstance().getCookie(uid);
UserApi api = BiliUserNetApiManager.getInstance().getUserApi(cookie);
UserInfoBean userInfo = api.getUserInfo().execute().body().getData();
SpiBean spiBean = api.getFingerSpi().execute().body().getData();
UserHomeInfoBean userHome = getUserHome(cookie, anchorUid, userInfo, spiBean);
if (userHome == null) {
return -3;//账号被风控
}
if (userHome.getLiveRoom() == null || userHome.getLiveRoom().getRoomid() == 0) {
return -2;//未开通直播间
}
LiveConfigDatabaseBean bean = configService.getConfig(String.valueOf(userHome.getLiveRoom().getRoomid()));
if (bean != null) {
return 2;//已关注
}
LiveConfigDatabaseBean config = configService.addConfig(userHome.getLiveRoom().getUrl(), new LiveConfigDatabaseBean());
if (config != null) {
return 1;
}
} catch (Exception e) {
Log.e(e);
return -1;//其他异常
}
return 0;//添加失败
}
public void confirmFollow(String uid) {
if (followTaskMap.containsKey(uid)) {
followTaskMap.get(uid).setStop(true);
}
followTaskMap.remove(uid);
}
public ResultData<UserFollowingsBean.Follow> checkFollow(String uid) {
if (followTaskMap.containsKey(uid)) {
return followTaskMap.get(uid).getFollowCount();
}
return null;
}
private final Map<String, FollowTask> followTaskMap = new HashMap<>();
public ResultData<UserFollowingsBean.Follow> followAll(String userId, List<UserFollowingsBean.Follow> follows) {
if (followTaskMap.containsKey(userId)) {
return followTaskMap.get(userId).getFollowCount();
}
FollowTask task = new FollowTask();
task.setUid(userId);
task.setFollowList(follows);
followTaskMap.put(userId, task);
task.start();
return task.getFollowCount();
}
public ResultData<UserFollowingsBean.Follow> followAll(String userId) {
return followAll(userId, null);
}
private class FollowTask extends Thread {
@Setter
private String uid;
@Setter
private List<UserFollowingsBean.Follow> followList = null;
@Getter
private ResultData<UserFollowingsBean.Follow> followCount = new ResultData<>();
@Setter
private boolean isStop = false;
@Override
public void run() {
int page = 1;
UserFollowingsBean bean = null;
if (followList == null) {
bean = getUserFollowings(uid, page, 50);
} else {
bean = new UserFollowingsBean();
bean.setTotal(followList.size());
bean.setList(followList);
}
int count = bean.getList().size();
while (count != bean.getTotal() && !isStop && followList == null) {
UserFollowingsBean tmp = getUserFollowings(uid, ++page, 50);
count += tmp.getList().size();
bean.getList().addAll(tmp.getList());
}
followCount.setCount(bean.getTotal());
followCount.setStatus(1);
count = 0;
for (UserFollowingsBean.Follow follow : bean.getList()) {
if (isStop) {
break;
}
if (followAnchor(uid, follow.getMid()) == 1) {
followCount.setData(follow);
followCount.setMessage(follow.getUname());
followCount.setStatus(++count);
}
}
followCount.setStatus(-100);
}
}
public static void main(String[] args) throws InterruptedException {
LiveUserService service = new LiveUserService();
service.userLoginService = new LiveLoginService();
service.configService = new LiveConfigService();
while (service.followAll("96300").getStatus() != 100) {
System.out.println("关注:" + service.checkFollow("96300"));
if (service.checkFollow("96300").getStatus() == 10) {
service.confirmFollow("96300");
break;
}
}
System.out.println(service.checkFollow("96300"));
}
}

View File

@@ -1,21 +0,0 @@
package com.yutou.bilibili.services;
import com.yutou.biliapi.bean.live.LiveRoomConfig;
import com.yutou.biliapi.bean.live.database.LiveDanmuDatabaseBean;
import com.yutou.biliapi.bean.live.database.LiveVideoDatabaseBean;
import com.yutou.biliapi.databases.BiliLiveDatabase;
import com.yutou.bilibili.datas.web.LiveVideoDanmu;
import com.yutou.common.utils.FFmpegUtils;
import jakarta.annotation.Resource;
import org.jetbrains.annotations.NotNull;
import org.springframework.stereotype.Service;
import java.io.File;
import java.util.ArrayList;
import java.util.List;
@Service
public class LiveVideoDanmuService {
}

View File

@@ -342,7 +342,7 @@ public class LiveVideoDownloadService {
private Map<String, List<VideoFilePath>> getVideoInfo(List<LiveVideoDatabaseBean> videoList) {
Map<String, List<VideoFilePath>> map = new HashMap<>();
for (LiveVideoDatabaseBean bean : videoList) {
String date = DateFormatUtils.format(bean.getSql_time(), "yyyy-MM-dd");
String date = DateFormatUtils.getInstance().format(bean.getSql_time(), "yyyy-MM-dd");
if (!map.containsKey(date)) {
map.put(date, new ArrayList<>());
}

View File

@@ -1,8 +0,0 @@
package com.yutou.bilibili.services;
import org.springframework.stereotype.Service;
@Service
public class LiveVideoService {
}

View File

@@ -48,7 +48,7 @@ public class SystemService {
scheduled = timer.scheduleAtFixedRate(() -> {
List<LiveConfigDatabaseBean> list = liveConfigDatabase.getAllConfig();
Log.i("循环任务:" + list.size());
if (DateFormatUtils.checkTime(null, resetTimer)) {
if (DateFormatUtils.getInstance().checkTime(null, resetTimer)) {
videoService.clearUserStopList();
danmuService.clearUserList();
}