一些bug的修复

视频切割车间插件
This commit is contained in:
userA
2023-09-20 01:23:50 +08:00
parent b586fc5656
commit c8a261d3bb
21 changed files with 331 additions and 25 deletions

View File

@@ -2,14 +2,18 @@ package org.example.core;
import org.example.bean.Live;
import org.example.constpool.ConstGroup;
import org.example.constpool.FileNameBuilder;
import org.example.constpool.PluginName;
import org.example.core.bgevnet.BarrageEvent;
import org.example.core.bgevnet.BarrageEventCenter;
import org.example.core.bgevnet.instantslicing.InstantSlicingPlugin;
import org.example.core.section.SectionRequest;
import org.example.core.section.VideoSectionWorkShop;
import org.example.core.taskcenter.observer.AbstractTaskCenterObserver;
import org.example.core.taskcenter.task.ReptileTask;
import org.example.init.InitPluginRegister;
import org.example.plugin.PluginCheckAndDo;
import org.example.util.TimeUtil;
import org.springframework.stereotype.Component;
/**
@@ -43,9 +47,24 @@ public class LiveAndBarrageHandlerObserver extends AbstractTaskCenterObserver {
((Live) param).getLiver(),
task.getLoadConfig().getStartTime()
);
event.setSuffix(task.getLoadConfig().getSuffix());
((BarrageEventCenter)plugin).event(event);
}
},PluginName.BARRAGE_EVENT_PLUGIN);
} else{
PluginCheckAndDo.CheckAndDo(plugin -> {
Object param = task.getRequest().getParam();
if(param instanceof Live){
SectionRequest request = ((VideoSectionWorkShop)plugin).wrapperReq((Live)param,task.getLoadConfig().getSuffix()
,"online",
task.getLoadConfig().getStartTime(),
0,TimeUtil.getTimeNaos(task.getEndTime())
);
((VideoSectionWorkShop)plugin).request(request);
}
},PluginName.VIDEO_SECTION_WORK_SHOP);
}
}

View File

@@ -31,7 +31,7 @@ public class BarrageEvent {
private String date;
private String fileName;
private String suffix;
private String suffix=".flv";
private List<Barrage> barrages;
private boolean isSort = false;

View File

@@ -2,12 +2,20 @@ package org.example.core.bgevnet;
import lombok.AllArgsConstructor;
import lombok.Data;
import org.example.bean.Live;
import org.example.constpool.FileNameBuilder;
import org.example.constpool.PluginName;
import org.example.core.bgevnet.bghot.BarragePopularRangePlugin;
import org.example.core.bgevnet.bghot.PopularRange;
import org.example.core.bgevnet.bgscore.BarragePoint;
import org.example.core.bgevnet.bgscore.BarrageScoreCurvePlugin;
import org.example.core.section.SectionRequest;
import org.example.core.section.VideoSectionWorkShop;
import org.example.plugin.PluginCheckAndDo;
import org.example.plugin.SpringBootPlugin;
import org.example.bean.Barrage;
import org.example.thread.NamedThreadFactory;
import org.example.util.TimeUtil;
import org.springframework.stereotype.Component;
import java.util.*;
@@ -63,13 +71,33 @@ public class BarrageEventCenter extends SpringBootPlugin {
@Override
public void run() {
//计算弹幕曲线
List<Barrage> list = PluginCheckAndDo.CheckAndGet(
List<BarragePoint> points = PluginCheckAndDo.CheckAndGet(
plugin -> {
return ((BarrageScoreCurvePlugin) plugin).generateCurve(event);
}, PluginName.BARRAGE_SCORE_CURVE_PLUGIN, List.class
);
//TODO 弹幕评分切割
// 弹幕热门区间
List<PopularRange> popularRanges = PluginCheckAndDo.CheckAndGet(
plugin -> {
return ((BarragePopularRangePlugin) plugin).findRange(points);
}, PluginName.BARRAGE_POPULAR_RANGE_PLUGIN, List.class
);
if(popularRanges!=null){
PluginCheckAndDo.CheckAndDo(plugin -> {
for (PopularRange popularRange : popularRanges) {
String liver = event.getLiver();
String platform = event.getPlatform();
String suffix = event.getSuffix();
String action = event.getAction();
String fileName = event.getFileName().split("\\.")[0]+suffix;
String date = event.getDate();
SectionRequest request = new SectionRequest(fileName, action, popularRange.getStartTime(), popularRange.getEndTime(), liver, platform,date);
((VideoSectionWorkShop)plugin).request(request);
}
},PluginName.VIDEO_SECTION_WORK_SHOP);
}
//TODO 弹幕标签插件
}
}

View File

@@ -64,14 +64,15 @@ public class ScheduleTimeHandler implements InstantSlicingHandler {
TaskStatus status = task.getType();
if (!task.getStartTime().equals(NULL_TIME)) {
Long time = TimeUtil.getTimeNaos(entry.getValue().getStartTime());
if(now - time > splitTime || status == TaskStatus.Finish){
Integer times = taskSplitTimes.get(task.getTaskId()).get();
if(now - time >= splitTime*(times+1) || status == TaskStatus.Finish){
taskSplitTimes.get(task.getTaskId()).incrementAndGet();
Object live = task.getRequest().getParam();
if (live instanceof Live) {
String platform = ((Live) live).getPlatform();
LoadConfig loadConfig = task.getLoadConfig();
String startTime = task.getLoadConfig().getStartTime();
String liver = ((Live) live).getLiver();
Integer times = taskSplitTimes.get(task.getTaskId()).getAndIncrement();
String barrageRoot = Path.of(BarrageModuleConstPool.BARRAGE_ROOT_PATH,"online",platform).toString();
String videoRoot = Path.of(videoRootPath,"online",platform).toString();
String oldBarrageFileName = FileNameBuilder.buildBarrageFileName(liver,startTime);
@@ -84,7 +85,9 @@ public class ScheduleTimeHandler implements InstantSlicingHandler {
Path.of(barrageRoot,newBarrageFileName).toString(),startNaos,endNaos)) {
if(spiltVideoFile(Path.of(videoRoot,oldVideoFileName).toString(),
Path.of(videoRoot,newVideoFileName).toString(),startNaos/1000,endNaos/1000)){
center.event(new BarrageEvent(platform,"online",liver,startTime,newBarrageFileName));
BarrageEvent event = new BarrageEvent(platform, "online", liver, startTime, newBarrageFileName);
event.setSuffix(task.getLoadConfig().getSuffix());
center.event(event);
}
}
}
@@ -111,7 +114,7 @@ public class ScheduleTimeHandler implements InstantSlicingHandler {
@Override
public void handler() {
this.scheduledFuture = pool.scheduleWithFixedDelay(this::monitorTask,0,splitTime, TimeUnit.MILLISECONDS);
this.scheduledFuture = pool.scheduleWithFixedDelay(this::monitorTask,0,1000, TimeUnit.MILLISECONDS);
}
@Override

View File

@@ -16,4 +16,5 @@ public class ModuleName {
public static final String BARRAGE = ConstPool.BARRAGE;
public static final String LIVE = ConstPool.LIVE_RECORD;
public static final String SECTION = ConstPool.SECTION;
}

View File

@@ -47,4 +47,5 @@ public class PluginName {
public static final String LIVE_CONFIG_PLUGIN= "LiveConfig";
public static final String LIVE_MANAGER_PLUGIN= "LiveDownLoadManager";
public static final String VIDEO_SECTION_WORK_SHOP = "SectionWorkShop";
}

View File

@@ -10,7 +10,8 @@ public enum LoggerType {
File("FileModule "),
Hot("HotModule "),
Barrage("Barrage "),
LiveRecord("LiveRecord ");
LiveRecord("LiveRecord "),
Section("Section ");
private String loggerName;
LoggerType(String name){

View File

@@ -49,6 +49,11 @@
<artifactId>chopperbot-barrage</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.example</groupId>
<artifactId>chopperbot-section</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>io.github.969025903</groupId>
<artifactId>assistant</artifactId>

View File

@@ -6,10 +6,13 @@ import org.example.core.manager.CreeperGroupCenter;
import org.example.core.taskcenter.TaskCenter;
import org.example.core.taskcenter.request.ReptileRequest;
import org.example.core.taskcenter.task.ReptileTask;
import org.example.core.taskcenter.task.TaskStatus;
import org.example.init.InitPluginRegister;
import org.example.plugin.annotation.Plugin;
import org.springframework.stereotype.Component;
import static org.example.constpool.ConstPool.NULL_TIME;
/**
* @author Genius
* @date 2023/09/14 21:43
@@ -25,7 +28,20 @@ public class LiveTaskObserver extends AbstractTaskCenterObserver {
@Override
public void onAlready(ReptileTask task) {
}
@Override
public void onRunning(ReptileTask task) {
ReptileRequest request = task.getRequest();
//重置开始时间,严格保证
while(true){
if(!task.getStartTime().equals(NULL_TIME)){
task.getLoadConfig().setStartTime(task.getStartTime());
break;
}
if(task.getType().equals(TaskStatus.Finish))break;
}
String groupName = request.getCreeperGroup().replace(ConstGroup.LIVE_ONLINE,ConstGroup.BARRAGE_ONLINE);
ReptileRequest barrageReq = new ReptileRequest(
(t)->{
@@ -35,21 +51,16 @@ public class LiveTaskObserver extends AbstractTaskCenterObserver {
TaskCenter plugin = InitPluginRegister.getPlugin(PluginName.TASK_CENTER_PLUGIN, TaskCenter.class);
assert plugin != null;
ReptileTask reptileTask = plugin.getReptileTask(barrageReq);
if(reptileTask!=null){
if(reptileTask!=null&&task.getType().equals(TaskStatus.Running)){
reptileTask.getLoadConfig().setStartTime(task.getLoadConfig().getStartTime());
}
plugin.request(reptileTask);
}
@Override
public void onRunning(ReptileTask task) {
}
@Override
public void onFinish(ReptileTask task) {
String lid = task.getTaskId();
String bid = lid.replace("live_","barrage_");
String bid = lid.replace(ConstGroup.LIVE_ONLINE,ConstGroup.BARRAGE_ONLINE);
taskCenter.stopTask(bid);
}

View File

@@ -16,6 +16,7 @@ import org.example.util.TimeUtil;
import java.io.Serializable;
import java.util.TreeSet;
import java.util.concurrent.locks.ReentrantLock;
import static org.example.constpool.ConstPool.NULL_TIME;
@@ -37,7 +38,7 @@ public class ReptileTask implements Serializable {
@JSONField(serializeUsing = TaskStatusEnumSerializer.class, deserializeUsing = TaskStatusEnumDeserializer.class)
private TaskStatus type;
private ReentrantLock typeLock = new ReentrantLock();
public ReptileTask(LoadTask loadTask,LoadConfig config,ReptileRequest request,String taskId) {
this.loadTask = loadTask;
this.request =request;

View File

@@ -30,6 +30,7 @@ import java.io.Serializable;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Random;
import java.util.concurrent.*;
/**
@@ -159,4 +160,31 @@ public class LiverFollower extends SpringBootPlugin {
focusPool.shutdown();
super.shutdown();
}
public static void main(String[] args) throws InterruptedException {
Executors.newScheduledThreadPool(1).scheduleWithFixedDelay(
()->{
System.out.println("hello");
long sum = 0;
Random random = new Random();
for(int i=0;i<100000000;i++){
sum = random.nextInt();
}
for(int i=0;i<100000000;i++){
sum = random.nextInt();
}
for(int i=0;i<100000000;i++){
sum = random.nextInt();
}
for(int i=0;i<1000000000;i++){
sum = random.nextInt();
}
System.out.println(sum);
},0,1000,TimeUnit.MILLISECONDS
);
while(true){
System.out.println(666);
Thread.sleep(1000);
}
}
}

View File

@@ -18,6 +18,7 @@
</properties>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>

View File

@@ -0,0 +1,5 @@
package org.example.core.auto;
public interface AutoGenerator <T>{
T generate();
}

View File

@@ -50,6 +50,13 @@
<scope>compile</scope>
</dependency>
<dependency>
<groupId>org.example</groupId>
<artifactId>chopperbot-file</artifactId>
<version>1.0-SNAPSHOT</version>
<scope>compile</scope>
</dependency>
<!-- ========== 优化依赖 ffmpeg-platform-gpl javacv-platform 只导入windows liunx平台 ============== -->
<dependency>
<groupId>org.bytedeco</groupId>

View File

@@ -0,0 +1,33 @@
package org.example.core.section;
import lombok.Data;
/**
* @author Genius
* @date 2023/09/19 19:37
**/
@Data
public class SectionRequest {
private String action;
private String videoName;
private long startTime;
private long endTime;
private String platform;
private String liver;
private String tag;
private String date;
public SectionRequest(String videoName,String action, long startTime, long endTime, String liver,String platform,String date) {
this.videoName = videoName;
this.startTime = startTime;
this.endTime = endTime;
this.liver = liver;
this.action = action;
this.platform = platform;
this.date = date;
}
}

View File

@@ -0,0 +1,23 @@
package org.example.core.section;
import lombok.Data;
/**
* @author Genius
* @date 2023/09/19 19:39
**/
@Data
public class VideoSection {
private String videoPath;
private String tag;
private String liver;
private String platform;
public VideoSection(String videoPath, String tag, String liver, String platform) {
this.videoPath = videoPath;
this.tag = tag;
this.liver = liver;
this.platform = platform;
}
}

View File

@@ -0,0 +1,88 @@
package org.example.core.section;
import org.apache.coyote.Request;
import org.example.bean.Live;
import org.example.cache.FileCache;
import org.example.constpool.ConstPool;
import org.example.constpool.FileNameBuilder;
import org.example.constpool.GlobalFileCache;
import org.example.plugin.SpringGuardPlugin;
import org.example.util.FileUtil;
import org.example.util.TimeUtil;
import org.example.util.VideoUtil;
import org.springframework.stereotype.Component;
import java.nio.file.Paths;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.TimeUnit;
/**
* @author Genius
* @date 2023/09/19 19:35
**/
@Component
public class VideoSectionWorkShop extends SpringGuardPlugin {
private BlockingQueue<SectionRequest> requests;
private String liveRoot;
@Override
public boolean init() {
requests = new LinkedBlockingQueue<>(1000);
liveRoot = (String) GlobalFileCache.ModuleSrcConfigFile.get("src", ConstPool.LIVE_RECORD);
return super.init();
}
@Override
public void start() {
try {
SectionRequest request = requests.poll(1000, TimeUnit.SECONDS);
long videoStartTime = TimeUtil.getTimeNaos(request.getDate());
long start = (timeBias(request.getStartTime())-videoStartTime)/1000;
start = start<0?0:start;
long end = (timeBias(request.getEndTime())-videoStartTime)/1000;
String root = Paths.get(liveRoot,request.getAction(),request.getPlatform()).toString();
String startTime = VideoUtil.formatTimeToFFMpeg(start);
String endTime = VideoUtil.formatTimeToFFMpeg(end);
String videoName = request.getVideoName();
String[] split = videoName.split("\\.");
String oldPath = Paths.get(root,videoName).toString();
String liver = request.getLiver();
String date = request.getDate();
String newVideoName = FileNameBuilder.buildVideoFileNameNoSuffix(liver, date)+"_section("+ FileUtil.convertTimeToFile(startTime) +"-"+FileUtil.convertTimeToFile(endTime)+")."+split[1];
String newPath = Paths.get(root,newVideoName).toString();
if (VideoUtil.cutVideoByFFMpeg(oldPath,newPath,startTime,endTime)) {
VideoSection videoSection = new VideoSection(newVideoName,request.getTag(),request.getLiver(),request.getPlatform());
}
}catch (InterruptedException e){
return;
}catch (Exception e){
}
}
public long timeBias(long time){
return time+8*1000;
}
public SectionRequest wrapperReq(Live live,String suffix,String action,String date,long startTime,long endTime){
String fileName = FileNameBuilder.buildVideoFileNameNoSuffix(live.getLiver(), date)+suffix;
return new SectionRequest(fileName, action, startTime, endTime, live.getLiver(), live.getPlatform(),date);
}
public boolean request(SectionRequest request) {
try {
return requests.offer(request,1000,TimeUnit.SECONDS);
}catch (Exception e){
return false;
}
}
public static void main(String[] args) {
String s1 = "2023-09-20 00:22:45";
long timeNaos = TimeUtil.getTimeNaos(s1);
String s = VideoUtil.formatTimeToFFMpeg((1695140913000L-timeNaos)/1000);
System.out.println(s);
}
}

View File

@@ -0,0 +1,22 @@
package org.example.init;
import org.example.constpool.ModuleName;
import org.example.constpool.PluginName;
import org.example.core.section.VideoSectionWorkShop;
import org.example.plugin.annotation.Plugin;
import org.springframework.stereotype.Component;
/**
* @author Genius
* @date 2023/09/19 19:56
**/
@Plugin(moduleName = ModuleName.SECTION,
pluginName = PluginName.VIDEO_SECTION_WORK_SHOP,
needPlugin = {PluginName.FILE_CACHE_PLUGIN},
pluginName_CN = "切片车间",
pluginClass= VideoSectionWorkShop.class,
springBootPlugin = true
)
@Component
public class VideoSectionWorkShopInitMachine extends SpringPlugInitMachine{
}

View File

@@ -0,0 +1,25 @@
package org.example.init.module;
import org.example.constpool.ConstPool;
import org.example.constpool.ModuleName;
import org.example.init.ModuleInitMachine;
import org.example.log.ChopperLogFactory;
import org.example.log.LoggerType;
import java.util.List;
/**
* <p>用于初始化弹幕模块所需</p>
*
* @author welsir
* @date 2023/7/31 10:11
*/
public class SectionModuleInitMachine extends ModuleInitMachine {
public SectionModuleInitMachine() {
super(List.of(ModuleName.LIVE,ModuleName.FILE),
ChopperLogFactory.getLogger(LoggerType.Section),
ModuleName.SECTION);
}
}

View File

@@ -404,18 +404,17 @@ public class VideoUtil {
}
private static String formatTimeToFFMpeg(long seconds){
public static String formatTimeToFFMpeg(long seconds){
long hours = seconds / 3600;
long minutes = (seconds % 3600) / 60;
long remainingSeconds = seconds % 60;
return String.format("%02d:%02d:%02d", hours, minutes, remainingSeconds);
}
public static boolean cutVideoByFFMpeg(String inputFilePath,String outputFilePath,long startSeconds,long endSeconds){
String startTime = formatTimeToFFMpeg(startSeconds);
String endTime = formatTimeToFFMpeg(endSeconds);
public static boolean cutVideoByFFMpeg(String inputFilePath,String outputFilePath,String start,String end){
try {
String ffmpegCmd = FFMPEG_PATH + " -i " + "\""+inputFilePath+"\"" + " -ss " + startTime + " -to " + endTime + " -c copy " + "\""+outputFilePath+"\"" +" -y";
String ffmpegCmd = FFMPEG_PATH + " -i " + "\""+inputFilePath+"\"" + " -ss " + start + " -to " + end + " -c copy " + "\""+outputFilePath+"\"" +" -y";
// 执行FFmpeg命令
Process process = Runtime.getRuntime().exec(ffmpegCmd);
@@ -435,6 +434,11 @@ public class VideoUtil {
return false;
}
}
public static boolean cutVideoByFFMpeg(String inputFilePath,String outputFilePath,long startSeconds,long endSeconds){
String startTime = formatTimeToFFMpeg(startSeconds);
String endTime = formatTimeToFFMpeg(endSeconds);
return cutVideoByFFMpeg(inputFilePath,outputFilePath,startTime,endTime);
}
public static void main(String[] args) {
cutVideoByFFMpeg(

View File

@@ -53,7 +53,7 @@ public class BarrageCurveTest {
@Test
public void testCurve(){
long l = System.currentTimeMillis();
List<BarragePoint> list = plugin.generateCurve(new BarrageEvent("bilibili", "online", "Asaki大人", "2023-09-18 23_12_43"));
List<BarragePoint> list = plugin.generateCurve(new BarrageEvent("bilibili", "online", "Asaki大人", "2023-09-19 22_00_06"));
System.out.println(System.currentTimeMillis()-l);
LineChartDemo demo = new LineChartDemo("Asaki大人",list);
demo.pack();
@@ -63,13 +63,13 @@ public class BarrageCurveTest {
System.out.println(range);
int i = 0;
for (PopularRange popularRange : range) {
long timeNaos = TimeUtil.getTimeNaos("2023-09-18 23:12:43");
long timeNaos = TimeUtil.getTimeNaos("2023-09-19 22:00:06");
long videoStartTime = popularRange.getStartTime()-timeNaos;
videoStartTime = videoStartTime<0?0:videoStartTime;
long videoEndTime = popularRange.getEndTime()-timeNaos;
System.out.println(videoStartTime+" "+videoEndTime);
VideoUtil.cutVideoByFFMpeg("E:\\Project\\ChopperBot\\chopperbot-test\\config\\LiveRecord\\online\\bilibili\\Asaki大人_2023-09-18 23_12_43.flv",
"E:\\Project\\ChopperBot\\chopperbot-test\\config\\LiveRecord\\online\\bilibili\\Asaki大人_2023-09-18 23_12_43"+i+".flv",
VideoUtil.cutVideoByFFMpeg("E:\\Project\\ChopperBot\\chopperbot-test\\config\\LiveRecord\\online\\bilibili\\Asaki大人_2023-09-19 22_00_06.flv",
"E:\\Project\\ChopperBot\\chopperbot-test\\config\\LiveRecord\\online\\bilibili\\Asaki大人_2023-09-19 22_00_06"+i+".flv",
videoStartTime/1000,videoEndTime/1000);
i++;
}