diff --git a/Web/html/body/video.html b/Web/html/body/video.html
index 5d1b3da..1847525 100644
--- a/Web/html/body/video.html
+++ b/Web/html/body/video.html
@@ -250,7 +250,7 @@
});
new Chart($('#giftChart').get(0), {
- type: 'bar',
+ type: 'pie',
data: {
labels: lables,
datasets: [{
diff --git a/Web/index.html b/Web/index.html
index 93fc06b..6a0c6a8 100644
--- a/Web/index.html
+++ b/Web/index.html
@@ -59,7 +59,7 @@
-

+

{{= item.title}}
开播时长:{{= item.liveTime}}
@@ -194,6 +194,13 @@
});
}
setTimeout(() => {
+ // data.data.forEach(item =>{
+ // if(document.getElementById(item.data)!==null){
+ // document.getElementById(item.data).innerHTML=item.message;
+ // }
+
+
+ // })
initFollowStatus(true)
}, 1000);
diff --git a/src/main/java/com/yutou/BilibiliApplication.java b/src/main/java/com/yutou/BilibiliApplication.java
index 2895946..504ca95 100644
--- a/src/main/java/com/yutou/BilibiliApplication.java
+++ b/src/main/java/com/yutou/BilibiliApplication.java
@@ -13,10 +13,10 @@ public class BilibiliApplication {
HttpLoggingInterceptor.setLog(false);
SpringApplication.run(BilibiliApplication.class, args);
}
- //TODO 优化 1 手动中断录制后,没有时间戳问题需要解决,看是提示转码还是有什么其他解决方案
+ //TODO 优化 1 手动中断录制后,没有时间戳问题需要解决,看是提示转码还是有什么其他解决方案 | 改成了通过q来退出
//TODO 优化 2 创建nfo文件看看要不要改成录制后生成,或者触发打包指令再生成
//TODO 优化 3 录制完成前应该也允许查看礼物信息和SC以及弹幕,未停止录制改成从开始时间到当前时间的弹幕和礼物信息,已停止录制则询问是否转码
- //TODO 优化 4 视频页面礼物的图标,有数据计算错误以及单项猛增的话导致其他项目无法查看的问题(可参考泛式死亡笔记录播)
+ //TODO 优化 4 视频页面礼物的图标,有数据计算错误以及单项猛增的话导致其他项目无法查看的问题(可参考泛式死亡笔记录播) | 换成饼状图
//TODO 修复 1 开播时有概率连续触发创建nfo和记录视频到数据宽度问题.
//TODO 测试 1 需要测试网络中断下,弹幕重连机制
//TODO 测试 2 在导出jar包后再测试完整的录制功能
diff --git a/src/main/java/com/yutou/biliapi/net/WebSocketManager.java b/src/main/java/com/yutou/biliapi/net/WebSocketManager.java
index 021502b..6a0253c 100644
--- a/src/main/java/com/yutou/biliapi/net/WebSocketManager.java
+++ b/src/main/java/com/yutou/biliapi/net/WebSocketManager.java
@@ -18,7 +18,6 @@ import com.yutou.biliapi.databases.BiliBiliLoginDatabase;
import com.yutou.biliapi.databases.BiliLiveDatabase;
import com.yutou.biliapi.utils.BiliUserUtils;
import com.yutou.biliapi.utils.BytesUtils;
-import com.yutou.bilibili.Tools.Tools;
import com.yutou.common.okhttp.HttpBody;
import com.yutou.common.okhttp.HttpCallback;
import com.yutou.common.utils.ConfigTools;
@@ -119,6 +118,7 @@ public class WebSocketManager {
roomConfig.setRoomInfo(execute.body() != null ? execute.body().getData() : null);
}
} catch (IOException e) {
+ WebSocketManager.getInstance().roomMap.remove(roomConfig);
throw new RuntimeException(e);
}
api.getLiveRoomDanmuInfo(String.valueOf(roomConfig.getRoomId())).enqueue(new HttpCallback
() {
@@ -132,6 +132,7 @@ public class WebSocketManager {
roomConfig.setLiveInfo(response);
client = new WebSocketClientTh(new URI(url), roomConfig);
} catch (URISyntaxException e) {
+ WebSocketManager.getInstance().roomMap.remove(roomConfig);
throw new RuntimeException(e);
}
}
@@ -139,6 +140,7 @@ public class WebSocketManager {
@Override
public void onFailure(Throwable throwable) {
+ WebSocketManager.getInstance().roomMap.remove(roomConfig);
Log.e(throwable);
}
});
diff --git a/src/main/java/com/yutou/bilibili/Tools/FFmpegUtils.java b/src/main/java/com/yutou/bilibili/Tools/FFmpegUtils.java
deleted file mode 100644
index e64a0a2..0000000
--- a/src/main/java/com/yutou/bilibili/Tools/FFmpegUtils.java
+++ /dev/null
@@ -1,76 +0,0 @@
-package com.yutou.bilibili.Tools;
-
-import com.yutou.common.utils.AppTools;
-import com.yutou.common.utils.Log;
-
-import java.io.File;
-import java.io.InputStream;
-import java.util.ArrayList;
-import java.util.List;
-
-public class FFmpegUtils {
- private static final List nowFFmpegList = new ArrayList<>();
-
- public static int add(String ffmpeg, File file, File out) {
- if (nowFFmpegList.contains(file)) {
- return 2;
- }
- if (file.getName().contains("ffmpeg")) {
- return 1;
- } else {
- startFFmpeg(ffmpeg, file, out);
- }
-
- return 0;
- }
-
- private synchronized static void startFFmpeg(String ffmpeg, File file, File out) {
- if (nowFFmpegList.contains(file)) {
- return;
- }
- nowFFmpegList.add(file);
- new Thread(new Runnable() {
- @Override
- public void run() {
- try {
- if (!out.exists()) {
- out.mkdirs();
- }
- String exec = String.format(
- "%s -i \"%s\" -c:v copy -y \"%s\" ",
- ffmpeg,
- file.getAbsolutePath(),
- out.getAbsolutePath() + File.separator + file.getName());
- Log.i(exec);
- Process process = ProcessUtils.exec(ffmpeg, "-i", file.getAbsolutePath(), "-c:v", "copy", "-y", out.getAbsolutePath() + File.separator + file.getName());
- InputStream inputStream = process.getErrorStream();
- byte[] bytes = new byte[1024];
- while (inputStream.read(bytes) > -1) {
- }
- inputStream.close();
- AppTools.copyFileToName(out.getAbsolutePath() + File.separator + file.getName(), file.getParent() + File.separator, file.getName().replace(".mp4", "_ffmpeg.mp4"), true);
- file.delete();
- new File(out.getAbsolutePath() + File.separator + file.getName()).delete();
- } catch (Exception e) {
- Log.e(e);
- }
- nowFFmpegList.remove(file);
- }
- }).start();
- }
-
- public static void main(String[] args) {
- File file = new File("D:\\ieda\\bilibili\\live\\2021-03-20\\[2021-03-20 003537]1064046.mp4");
- int i = -1;
- while (i != 1) {
- i = add("D:\\ffmpeg-4.3.1-2020-11-19-full_build\\bin\\ffmpeg.exe", file.getAbsoluteFile(), new File("ffmpeg_out"));
- Log.i(i);
- try {
- Thread.sleep(300);
- } catch (InterruptedException e) {
- Log.e(e);
- }
- }
- Log.i("转码完成");
- }
-}
diff --git a/src/main/java/com/yutou/bilibili/services/LiveDanmuService.java b/src/main/java/com/yutou/bilibili/services/LiveDanmuService.java
index 023dca5..e6a6c64 100644
--- a/src/main/java/com/yutou/bilibili/services/LiveDanmuService.java
+++ b/src/main/java/com/yutou/bilibili/services/LiveDanmuService.java
@@ -97,6 +97,10 @@ public class LiveDanmuService {
long videoTime = FFmpegUtils.getVideoTime(videoFile);
long startTime = Long.parseLong(videoId);
long endTime = Long.parseLong(videoId) + videoTime;
+ // videoTime = 0;
+ if (videoTime == 0) {
+ endTime = System.currentTimeMillis();
+ }
List danmuList = liveDatabase.getOfTime(DateFormatUtils.getInstance().format(startTime), DateFormatUtils.getInstance().format(endTime), LiveDanmuDatabaseBean.class);
List superChatList = liveDatabase.getOfTime(DateFormatUtils.getInstance().format(startTime), DateFormatUtils.getInstance().format(endTime), LiveSuperChatDatabaseBean.class);
for (LiveDanmuDatabaseBean bean : danmuList) {
@@ -104,7 +108,7 @@ public class LiveDanmuService {
danmus.getDanmu().add(danmu);
}
for (LiveSuperChatDatabaseBean bean : superChatList) {
- LiveVideoDanmu.SuperChat superChat = new LiveVideoDanmu.SuperChat(startTime,bean);
+ LiveVideoDanmu.SuperChat superChat = new LiveVideoDanmu.SuperChat(startTime, bean);
danmus.getSuperChat().add(superChat);
}
diff --git a/src/main/java/com/yutou/bilibili/services/LiveVideoDownloadService.java b/src/main/java/com/yutou/bilibili/services/LiveVideoDownloadService.java
index f77f83c..14df37c 100644
--- a/src/main/java/com/yutou/bilibili/services/LiveVideoDownloadService.java
+++ b/src/main/java/com/yutou/bilibili/services/LiveVideoDownloadService.java
@@ -257,6 +257,7 @@ public class LiveVideoDownloadService {
// .withNotSymbolParam("-progress", "-")
.withNotSymbolParam("-threads", "8")
.withNotSymbolParam("-c:v", "copy")
+ .withNotSymbolParam("-fflags","+genpts")
.withNotSymbolParam("-y", "");
if (ck != null) {
builder = builder.withParam("-cookies", cookie);
@@ -299,7 +300,7 @@ public class LiveVideoDownloadService {
videoDatabaseBean.setRoomInfoJson(JSONObject.toJSONString(roomInfo));
videoDatabaseBean.setStartTime(new Date());
database.addLiveInfo(videoDatabaseBean);
- LiveInfoNfoTools.saveLiveInfoNfo(roomInfo, rootPath.getAbsolutePath(), new File(savePath).getName().replace(".flv", ".nfo"));
+ // LiveInfoNfoTools.saveLiveInfoNfo(roomInfo, rootPath.getAbsolutePath(), new File(savePath).getName().replace(".flv", ".nfo"));
}
}
diff --git a/src/main/java/com/yutou/common/utils/FFmpegUtils.java b/src/main/java/com/yutou/common/utils/FFmpegUtils.java
index 225c5ae..6bac42d 100644
--- a/src/main/java/com/yutou/common/utils/FFmpegUtils.java
+++ b/src/main/java/com/yutou/common/utils/FFmpegUtils.java
@@ -12,14 +12,12 @@ import java.nio.charset.StandardCharsets;
import java.util.*;
public class FFmpegUtils extends AbsVideoRecord {
- private static final Map pidMap = new HashMap<>();
+ private static final Map pidMap = new HashMap<>();
@Getter
private String command;
@Getter
private String outputFilePath;
private String uid;
- InputStream inputStream;
- OutputStream outputStream;
public FFmpegUtils() {
}
@@ -33,7 +31,10 @@ public class FFmpegUtils extends AbsVideoRecord {
@Override
public boolean check(String roomId) {
try {
- return ProcessUtils.isProcessRunning(pidMap.get(roomId));
+ if(!pidMap.containsKey(roomId)){
+ return false;
+ }
+ return ProcessUtils.isProcessRunning(pidMap.get(roomId).pid);
} catch (Exception e) {
Log.e(e);
throw new RuntimeException(e);
@@ -43,8 +44,11 @@ public class FFmpegUtils extends AbsVideoRecord {
@Override
public void kill(String roomId) {
try {
- ProcessUtils.killProcess(pidMap.get(roomId));
- pidMap.remove(roomId);
+ // ProcessUtils.killProcess(pidMap.get(roomId).pid);
+ Task utils = pidMap.get(roomId);
+ if(utils != null) {
+ utils.kill();
+ }
} catch (Exception e) {
Log.e(e);
throw new RuntimeException(e);
@@ -53,9 +57,9 @@ public class FFmpegUtils extends AbsVideoRecord {
@Override
public void killAll() {
- for (Long pid : pidMap.values()) {
+ for (Task pid : pidMap.values()) {
try {
- ProcessUtils.killProcess(pid);
+ pid.kill();
} catch (Exception e) {
Log.e(e);
}
@@ -137,47 +141,12 @@ public class FFmpegUtils extends AbsVideoRecord {
@Override
public void start(DownloadInterface downloadInterface) {
- new Thread(() -> {
- try {
- if (check(uid)) {
- kill(uid);
- }
- Process process = ProcessUtils.exec(command.split(" "));
- long pid = process.toHandle().pid();
- Log.i("进程id " + pid);
- inputStream = process.getErrorStream();
- outputStream = process.getOutputStream();
- byte[] bytes = new byte[2048];
- if (downloadInterface != null) {
- downloadInterface.onDownloadStart();
- }
- pidMap.put(uid, pid);
- while (inputStream.read(bytes) > -1) {
- if (downloadInterface != null) {
- downloadInterface.onDownloading(0, 0);
- }
- }
- pidMap.remove(uid);
- //获取视频时长:ffprobe -v error -show_entries format=duration -of default=noprint_wrappers=1:nokey=1 input.mp4
- //获取到结果:5372.432000
- if (downloadInterface != null) {
- Log.i("触发下载完成",command);
- downloadInterface.onDownload(null);
- }
- } catch (Exception e) {
- throw new RuntimeException(e);
- }
- }).start();
+ new Task(downloadInterface).start();
}
@Override
public void stop() {
- try {
- outputStream.write("q".getBytes());
- outputStream.flush();
- } catch (IOException e) {
- throw new RuntimeException(e);
- }
+ pidMap.get(uid).kill();
}
/**
@@ -206,4 +175,63 @@ public class FFmpegUtils extends AbsVideoRecord {
throw new RuntimeException(e);
}
}
+
+ private class Task extends Thread {
+ private long pid;
+ InputStream inputStream;
+ OutputStream outputStream;
+ DownloadInterface downloadInterface;
+
+ public Task(DownloadInterface downloadInterface) {
+ this.downloadInterface = downloadInterface;
+ }
+
+ @Override
+ public void run() {
+ super.run();
+ try {
+ if (check(uid)) {
+ kill();
+ }
+ Process process = ProcessUtils.exec(command.split(" "));
+ pid = process.toHandle().pid();
+ Log.i("进程id " + pid);
+ inputStream = process.getErrorStream();
+ outputStream = process.getOutputStream();
+ byte[] bytes = new byte[2048];
+ if (downloadInterface != null) {
+ downloadInterface.onDownloadStart();
+ }
+ pidMap.put(uid, this);
+ while (inputStream.read(bytes) > -1) {
+ if (downloadInterface != null) {
+ downloadInterface.onDownloading(0, 0);
+ }
+ }
+ pidMap.remove(uid);
+ //获取视频时长:ffprobe -v error -show_entries format=duration -of default=noprint_wrappers=1:nokey=1 input.mp4
+ //获取到结果:5372.432000
+ if (downloadInterface != null) {
+ Log.i("触发下载完成", command);
+ downloadInterface.onDownload(null);
+ }
+ } catch (Exception e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+ public void kill() {
+ try {
+ outputStream.write("q".getBytes());
+ outputStream.flush();
+ Thread.sleep(1000);
+ if (check(uid)) {
+ ProcessUtils.killProcess(pid);
+ }
+ pidMap.remove(uid);
+ } catch (Exception e) {
+ throw new RuntimeException(e);
+ }
+ }
+ }
}