This commit is contained in:
2024-10-31 18:23:39 +08:00
parent 4b04c1863b
commit 34a41f50ac
31 changed files with 561 additions and 223 deletions

View File

@@ -56,7 +56,7 @@ public class LiveConfigController {
return ResultData.fail(ReturnCode.RC999.getCode(),"弹幕录制时间格式错误");
}
LiveConfigDatabaseBean config = configService.updateConfig(new BigInteger(roomId), bean);
LiveConfigDatabaseBean config = configService.updateConfig(new String(roomId), bean);
if (config != null) {
return ResultData.success(config.toJson());
}
@@ -69,7 +69,7 @@ public class LiveConfigController {
if ("0".equals(roomId) || !StringUtils.hasText(roomId)) {
return ResultData.fail(ReturnCode.RC999);
}
LiveConfigDatabaseBean config = configService.getConfig(new BigInteger(roomId));
LiveConfigDatabaseBean config = configService.getConfig(new String(roomId));
if (config != null) {
return ResultData.success(config.toJson());
}
@@ -88,8 +88,8 @@ public class LiveConfigController {
@RequestMapping(value = "delete", method = RequestMethod.GET)
@ResponseBody
public JSONObject deleteConfig(BigInteger roomId) {
if (roomId.equals(BigInteger.ZERO)) {
public JSONObject deleteConfig(String roomId) {
if ("0".equals(roomId)|| !StringUtils.hasText(roomId)) {
return ResultData.fail(ReturnCode.RC999);
}
boolean flag = configService.deleteConfig(roomId);

View File

@@ -0,0 +1,32 @@
package com.yutou.bilibili.Controllers;
import com.alibaba.fastjson2.JSONObject;
import com.yutou.bilibili.datas.ResultData;
import com.yutou.bilibili.datas.VideoFilePath;
import com.yutou.bilibili.services.LiveDanmuService;
import com.yutou.bilibili.services.LiveService;
import com.yutou.bilibili.services.LiveVideoService;
import jakarta.annotation.Resource;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import java.util.List;
@Controller
public class LiveController {
@Resource
LiveVideoService videoService;
@Resource
LiveDanmuService danmuService;
@Resource
LiveService liveService;
@RequestMapping("/live/list")
@ResponseBody
public JSONObject getLiveList(){
return ResultData.success(liveService.getLiveList());
}
}

View File

@@ -1,5 +1,6 @@
package com.yutou.bilibili.Controllers;
import com.yutou.common.okhttp.HttpLoggingInterceptor;
import com.yutou.common.utils.FFmpegUtils;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
@@ -12,4 +13,10 @@ public class TestControllers {
public String test(){
return "hello world";
}
@ResponseBody
@RequestMapping("/root/log")
public String log(boolean flag){
HttpLoggingInterceptor.setLog(flag);
return flag+"";
}
}

View File

@@ -1,22 +1,41 @@
package com.yutou.bilibili.Tools;
import com.yutou.common.utils.Log;
import java.text.SimpleDateFormat;
import java.util.Date;
public class DateFormatUtils {
public static String format(Date date,String format){
public static String format(Date date, String format) {
return new SimpleDateFormat(format).format(date);
}
public static String format(long time,String format){
public static String format(long time, String format) {
return new SimpleDateFormat(format).format(new Date(time));
}
public static String format(long time){
public static String format(long time) {
return new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS").format(new Date(time));
}
public static String format(Date date){
public static String format(Date date) {
return new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS").format(date);
}
public static String format(){
public static String format() {
return new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS").format(new Date());
}
public static Date parseTimer(String date) {
return parse(date, "HH:mm:ss");
}
public static Date parse(String date, String format) {
try {
return new SimpleDateFormat(format).parse(date);
} catch (Exception e) {
Log.e(e);
return null;
}
}
}

View File

@@ -0,0 +1,21 @@
package com.yutou.bilibili.datas.web;
import com.yutou.common.okhttp.BaseBean;
import lombok.Data;
import lombok.EqualsAndHashCode;
@EqualsAndHashCode(callSuper = true)
@Data
public class LiveData extends BaseBean {
private String roomId;
private String anchorName;
private String anchorUid;
private String anchorFace;
private String title;
private String cover;
private boolean isLive;
private boolean isDanmu;
private boolean isDownloadVideo;
}

View File

@@ -27,7 +27,7 @@ public class LiveConfigService {
if (!StringUtils.hasText(roomId)) {
return null;
}
bean.setRoomId(new BigInteger(roomId));
bean.setRoomId(new String(roomId));
try {
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();
@@ -36,14 +36,13 @@ public class LiveConfigService {
bean.setAnchorFace(infoBean.getInfo().getFace());
bean.setAnchorName(infoBean.getInfo().getUname());
database.setConfig(bean);
downloadFace(bean);
return bean;
} catch (IOException e) {
throw new RuntimeException(e);
}
}
public LiveConfigDatabaseBean updateConfig(BigInteger roomId, LiveConfigDatabaseBean bean) {
public LiveConfigDatabaseBean updateConfig(String roomId, LiveConfigDatabaseBean bean) {
LiveConfigDatabaseBean config = database.getConfig(roomId);
if (config == null) {
return null;
@@ -51,11 +50,10 @@ public class LiveConfigService {
bean.setRoomId(roomId);
bean.setSql_time(config.getSql_time());
database.setConfig(bean);
downloadFace(bean);
return bean;
}
public boolean deleteConfig(BigInteger roomId) {
public boolean deleteConfig(String roomId) {
LiveConfigDatabaseBean config = database.getConfig(roomId);
if (config == null) {
return false;
@@ -68,32 +66,23 @@ public class LiveConfigService {
return database.getAllConfig();
}
public LiveConfigDatabaseBean getConfig(BigInteger roomId) {
public LiveConfigDatabaseBean getConfig(String roomId) {
return database.getConfig(roomId);
}
public File getFace(String roomId) {
LiveConfigDatabaseBean config = database.getConfig(new BigInteger(roomId));
LiveConfigDatabaseBean config = database.getConfig(new String(roomId));
if (config == null) {
return null;
}
return new File(config.getRecordPath() + File.separator + config.getAnchorName() + File.separator + config.getAnchorFace());
}
private void downloadFace(LiveConfigDatabaseBean bean) {
HttpDownloadUtils.download(
new HttpDownloadUtils.Builder()
.setPath(bean.getRecordPath() + File.separator + bean.getAnchorName())
.setUrl(bean.getAnchorFace())
.setFileName("face.jpg")
);
bean.setAnchorFace(bean.getRecordPath() + File.separator + bean.getAnchorName() + File.separator + "face.jpg");
}
public boolean checkUrl(String url) {
if (!url.startsWith("https://live.bilibili.com/")) {
try {
new BigInteger(url);
new String(url);
} catch (Exception e) {
return false;
}

View File

@@ -25,6 +25,11 @@ public class LiveDanmuService {
public void start(String roomId,boolean isUser) {
WebSocketManager.getInstance().addRoom(LiveRoomConfig.buildConfig(roomId), isUser);
}
public boolean check(String roomId) {
LiveRoomConfig roomConfig = new LiveRoomConfig();
roomConfig.setRoomId(roomId);
return WebSocketManager.getInstance().checkRoom(roomConfig);
}
public void stop(String roomId,boolean isUser) {
WebSocketManager.getInstance().stopRoom(roomId, isUser);
@@ -37,7 +42,7 @@ public class LiveDanmuService {
public List<File> getDanmuFileList(String roomId) {
BiliLiveConfigDatabase configDatabase=new BiliLiveConfigDatabase();
LiveConfigDatabaseBean bean = configDatabase.getConfig(new BigInteger(roomId));
LiveConfigDatabaseBean bean = configDatabase.getConfig(new String(roomId));
configDatabase.close();
return Tools.scanFile(new File(bean.getRecordPath() + File.separator + bean.getAnchorName()));
}

View File

@@ -0,0 +1,62 @@
package com.yutou.bilibili.services;
import com.yutou.biliapi.api.LiveApi;
import com.yutou.biliapi.bean.live.LiveRoomInfo;
import com.yutou.biliapi.bean.live.database.LiveConfigDatabaseBean;
import com.yutou.biliapi.databases.BiliLiveConfigDatabase;
import com.yutou.biliapi.net.BiliLiveNetApiManager;
import com.yutou.bilibili.datas.web.LiveData;
import com.yutou.common.okhttp.HttpBody;
import com.yutou.common.utils.AppTools;
import com.yutou.common.utils.Log;
import jakarta.annotation.Resource;
import org.springframework.stereotype.Service;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
@Service
public class LiveService {
BiliLiveConfigDatabase liveConfigDatabase;
@Resource
LiveVideoService videoService;
@Resource
LiveDanmuService danmuService;
LiveApi api;
public LiveService() {
liveConfigDatabase = new BiliLiveConfigDatabase();
api = BiliLiveNetApiManager.getInstance().getApi(null);
}
public List<LiveData> getLiveList() {
List<LiveConfigDatabaseBean> allConfig = liveConfigDatabase.getAllConfig();
List<LiveData> liveDataList = new ArrayList<>();
for (LiveConfigDatabaseBean config : allConfig) {
LiveData liveData = new LiveData();
liveData.setRoomId(config.getRoomId());
liveData.setAnchorUid(config.getAnchorUid());
liveData.setAnchorName(config.getAnchorName());
liveData.setAnchorFace(config.getAnchorFace());
liveData.setDownloadVideo(videoService.checkDownload(config.getRoomId()));
liveData.setDanmu(danmuService.check(config.getRoomId()));
try {
LiveRoomInfo body = api.getRoomInfo(config.getRoomId()).execute().body().getData();
if (body != null) {
liveData.setTitle(body.getTitle());
liveData.setLive(body.getLiveStatus() == 1);
if (body.getLiveStatus() == 1) {
liveData.setCover(body.getKeyframe());
} else {
liveData.setCover(body.getUserCover());
}
}
liveDataList.add(liveData);
} catch (IOException e) {
Log.e(e);
}
}
return liveDataList;
}
}

View File

@@ -47,16 +47,20 @@ import static com.alibaba.fastjson2.util.DateUtils.DateTimeFormatPattern.DATE_FO
@Service
public class LiveVideoService {
ThreadPoolExecutor executor;
private final ThreadPoolExecutor executor;
private final List<String> userStopList = new ArrayList<>();//手动停止列表
AbsVideoRecord videoRecord;
private final AbsVideoRecord videoRecord;
public LiveVideoService() {
Log.i("初始化下载服务");
videoRecord=new FFmpegUtils();
videoRecord = new FFmpegUtils();
executor = new ThreadPoolExecutor(2, 4, Long.MAX_VALUE, TimeUnit.SECONDS, new ArrayBlockingQueue<Runnable>(100));
}
public boolean checkDownload(String roomId) {
return videoRecord.check(roomId);
}
public void start(LiveConfigDatabaseBean bean, boolean isUser) {
if (!isUser && userStopList.contains(bean.getRoomId().toString())) {
return;
@@ -240,15 +244,17 @@ public class LiveVideoService {
cookie = ck.toCookieString();
}
FFmpegUtils command = new FFmpegUtils.Builder()
FFmpegUtils.Builder builder = new FFmpegUtils.Builder()
.withParam("-user_agent", ConfigTools.getUserAgent())
.withParam("-cookies", cookie)
.withParam("-headers", "Referer: https://live.bilibili.com")
// .withNotSymbolParam("-progress", "-")
.withNotSymbolParam("-threads", "8")
.withNotSymbolParam("-c:v", "copy")
.withNotSymbolParam("-y", "")
.build(config.getRoomId().toString(), ffmpegPath, url, savePath);
.withNotSymbolParam("-y", "");
if (ck != null) {
builder = builder.withParam("-cookies", cookie);
}
FFmpegUtils command = builder.build(config.getRoomId(), ffmpegPath, url, savePath);
Log.i(command.getCommand());
try {
command.start(new DownloadInterface() {
@@ -306,7 +312,7 @@ public class LiveVideoService {
public List<VideoFilePath> getVideoPath(String roomId) {
BiliLiveConfigDatabase configDatabase = new BiliLiveConfigDatabase();
LiveConfigDatabaseBean bean = configDatabase.getConfig(new BigInteger(roomId));
LiveConfigDatabaseBean bean = configDatabase.getConfig(new String(roomId));
configDatabase.close();
return new ArrayList<>(getVideoFilePath(bean));
}