From 7e75e16749ecb1c5c60e848fee3f1caa9411ed33 Mon Sep 17 00:00:00 2001 From: ThisBirchWood Date: Sun, 11 May 2025 22:26:32 +0200 Subject: [PATCH] REFACTOR job to be a DTO, CompressionService is now stateless --- .../java/com/ddf/vodsystem/entities/Job.java | 29 ++++++ .../services/CompressionService.java | 91 +++++++------------ .../vodsystem/services/DownloadService.java | 2 +- .../ddf/vodsystem/services/EditService.java | 4 +- .../ddf/vodsystem/services/JobService.java | 19 +++- .../ddf/vodsystem/services/UploadService.java | 2 +- .../java/com/ddf/vodsystem/tools/Job.java | 52 ----------- 7 files changed, 78 insertions(+), 121 deletions(-) create mode 100644 src/main/java/com/ddf/vodsystem/entities/Job.java delete mode 100644 src/main/java/com/ddf/vodsystem/tools/Job.java diff --git a/src/main/java/com/ddf/vodsystem/entities/Job.java b/src/main/java/com/ddf/vodsystem/entities/Job.java new file mode 100644 index 0000000..560ebee --- /dev/null +++ b/src/main/java/com/ddf/vodsystem/entities/Job.java @@ -0,0 +1,29 @@ +package com.ddf.vodsystem.entities; + +import lombok.Data; +import java.io.File; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +@Data +public class Job { + private static final Logger logger = LoggerFactory.getLogger(Job.class); + + private String uuid; + private File inputFile; + private File outputFile; + + // configs + private ClipConfig clipConfig; + + // job status + private JobStatus status = JobStatus.PENDING; + private Float progress = 0.0f; + + public Job(String uuid, File inputFile, File outputFile) { + this.uuid = uuid; + this.inputFile = inputFile; + this.outputFile = outputFile; + } +} diff --git a/src/main/java/com/ddf/vodsystem/services/CompressionService.java b/src/main/java/com/ddf/vodsystem/services/CompressionService.java index ea4a330..378e8d0 100644 --- a/src/main/java/com/ddf/vodsystem/services/CompressionService.java +++ b/src/main/java/com/ddf/vodsystem/services/CompressionService.java @@ -1,7 +1,8 @@ package com.ddf.vodsystem.services; import com.ddf.vodsystem.entities.ClipConfig; -import lombok.Data; +import com.ddf.vodsystem.entities.JobStatus; +import com.ddf.vodsystem.entities.Job; import java.io.BufferedReader; import java.io.File; @@ -11,32 +12,14 @@ import java.util.ArrayList; import java.util.List; import java.util.regex.Pattern; -import lombok.Getter; -import lombok.Setter; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import org.springframework.stereotype.Service; -import static java.lang.Long.parseLong; - +@Service public class CompressionService { private static final Logger logger = LoggerFactory.getLogger(CompressionService.class); - private List command; - - @Getter @Setter - private File inputFile; - @Getter @Setter - private File outputFile; - @Getter @Setter - private ClipConfig clipConfig; - - private final Float startPoint; - private final Float endPoint; - private final Integer width; - private final Integer height; - private final Float fps; - private final Float fileSize; - private static final float AUDIO_RATIO = 0.15f; private static final float MAX_AUDIO_BITRATE = 128f; private static final float BITRATE_MULTIPLIER = 0.9f; @@ -44,26 +27,7 @@ public class CompressionService { private Pattern timePattern = Pattern.compile("time=([\\d:.]+)"); private long out_time_ms; - public CompressionService(File file, File output, ClipConfig clipConfig) { - command = new ArrayList<>(); - command.add("ffmpeg"); - command.add("-progress"); - command.add("pipe:1"); - command.add("-y"); - - this.inputFile = file; - this.outputFile = output; - this.clipConfig = clipConfig; - this.startPoint = clipConfig.getStartPoint(); - this.endPoint = clipConfig.getEndPoint(); - this.fps = clipConfig.getFps(); - this.fileSize = clipConfig.getFileSize(); - this.width = clipConfig.getWidth(); - this.height = clipConfig.getHeight(); - - } - - private void buildFilters() { + private void buildFilters(ArrayList command, Float fps, Integer width, Integer height) { List filters = new ArrayList<>(); if (fps != null) { @@ -82,8 +46,7 @@ public class CompressionService { } } - private void buildBitrate() { - float length = endPoint - startPoint; + private void buildBitrate(ArrayList command, Float length, Float fileSize) { float bitrate = ((fileSize * 8) / length) * BITRATE_MULTIPLIER; float audio_bitrate = bitrate * AUDIO_RATIO; @@ -102,29 +65,37 @@ public class CompressionService { command.add(audio_bitrate + "k"); } - private void buildInputs(){ - if (startPoint != null) { - command.add("-ss"); - command.add(startPoint.toString()); + private void buildInputs(ArrayList command, File inputFile, Float startPoint, Float endPoint) { + if (startPoint == null) { + startPoint = 0f; } + command.add("-ss"); + command.add(startPoint.toString()); + command.add("-i"); command.add(inputFile.getAbsolutePath()); if (endPoint != null) { + Float length = endPoint - startPoint; command.add("-t"); - - Float duration = endPoint - startPoint; - command.add(duration.toString()); + command.add(length.toString()); } } - private ProcessBuilder buildCommand() { - buildInputs(); - buildFilters(); + private ProcessBuilder buildCommand(File inputFile, File outputFile, ClipConfig clipConfig) { + ArrayList command = new ArrayList<>(); + command.add("ffmpeg"); + command.add("-progress"); + command.add("pipe:1"); + command.add("-y"); - if (fileSize != null) { - buildBitrate(); + Float length = clipConfig.getEndPoint() - clipConfig.getStartPoint(); + buildInputs(command, inputFile, clipConfig.getStartPoint(), clipConfig.getEndPoint()); + buildFilters(command, clipConfig.getFps(), clipConfig.getWidth(), clipConfig.getHeight()); + + if (clipConfig.getFileSize() != null) { + buildBitrate(command, length, clipConfig.getFileSize()); } // Output file @@ -134,22 +105,22 @@ public class CompressionService { return new ProcessBuilder(command); } - public void run() throws IOException, InterruptedException { + public void run(Job job) throws IOException, InterruptedException { logger.info("FFMPEG starting..."); - ProcessBuilder pb = buildCommand(); + + ProcessBuilder pb = buildCommand(job.getInputFile(), job.getOutputFile(), job.getClipConfig()); pb.redirectErrorStream(true); Process process = pb.start(); + job.setStatus(JobStatus.RUNNING); BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream())); String line; while ((line = reader.readLine()) != null) { logger.debug(line); -// if (line.startsWith("out_time_ms=")) { -// out_time_ms = parseLong(line.substring("out_time_ms=".length())); -// } } + job.setStatus(JobStatus.FINISHED); logger.info("FFMPEG finished"); } diff --git a/src/main/java/com/ddf/vodsystem/services/DownloadService.java b/src/main/java/com/ddf/vodsystem/services/DownloadService.java index aae5eb3..ecfb55e 100644 --- a/src/main/java/com/ddf/vodsystem/services/DownloadService.java +++ b/src/main/java/com/ddf/vodsystem/services/DownloadService.java @@ -3,7 +3,7 @@ package com.ddf.vodsystem.services; import com.ddf.vodsystem.entities.JobStatus; import com.ddf.vodsystem.exceptions.JobNotFinished; import com.ddf.vodsystem.exceptions.JobNotFound; -import com.ddf.vodsystem.tools.Job; +import com.ddf.vodsystem.entities.Job; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.core.io.FileSystemResource; import org.springframework.core.io.Resource; diff --git a/src/main/java/com/ddf/vodsystem/services/EditService.java b/src/main/java/com/ddf/vodsystem/services/EditService.java index 7d599f6..7bbd4d4 100644 --- a/src/main/java/com/ddf/vodsystem/services/EditService.java +++ b/src/main/java/com/ddf/vodsystem/services/EditService.java @@ -1,7 +1,7 @@ package com.ddf.vodsystem.services; import com.ddf.vodsystem.entities.ClipConfig; -import com.ddf.vodsystem.tools.Job; +import com.ddf.vodsystem.entities.Job; import org.springframework.stereotype.Service; @Service @@ -22,8 +22,6 @@ public class EditService { } job.setClipConfig(clipConfig); - - } public void jobReady(String uuid) { diff --git a/src/main/java/com/ddf/vodsystem/services/JobService.java b/src/main/java/com/ddf/vodsystem/services/JobService.java index 9a775ee..9491c76 100644 --- a/src/main/java/com/ddf/vodsystem/services/JobService.java +++ b/src/main/java/com/ddf/vodsystem/services/JobService.java @@ -1,6 +1,6 @@ package com.ddf.vodsystem.services; -import com.ddf.vodsystem.tools.Job; +import com.ddf.vodsystem.entities.Job; import com.ddf.vodsystem.entities.JobStatus; import jakarta.annotation.PostConstruct; import org.springframework.stereotype.Service; @@ -8,6 +8,7 @@ import org.springframework.stereotype.Service; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import java.io.IOException; import java.util.HashMap; import java.util.LinkedList; @@ -16,6 +17,11 @@ public class JobService { private static final Logger logger = LoggerFactory.getLogger(JobService.class); private final HashMap jobs = new HashMap<>(); private final LinkedList jobQueue = new LinkedList<>(); + private final CompressionService compressionService; + + public JobService(CompressionService compressionService) { + this.compressionService = compressionService; + } public void add(Job job) { logger.info("Added job: {}", job.getUuid()); @@ -43,10 +49,15 @@ public class JobService { Thread thread = new Thread(() -> { while (true) { if (!jobQueue.isEmpty()) { - Job task = jobQueue.poll(); + Job job = jobQueue.poll(); - logger.info("Starting job {}", task.getUuid()); - task.run(); // Execute the task + logger.info("Starting job {}", job.getUuid()); + + try { + compressionService.run(job);// Execute the task + } catch (IOException | InterruptedException e) { + logger.error("Error while running job {}", job.getUuid(), e); + } } } diff --git a/src/main/java/com/ddf/vodsystem/services/UploadService.java b/src/main/java/com/ddf/vodsystem/services/UploadService.java index f9930c5..12e1399 100644 --- a/src/main/java/com/ddf/vodsystem/services/UploadService.java +++ b/src/main/java/com/ddf/vodsystem/services/UploadService.java @@ -1,6 +1,6 @@ package com.ddf.vodsystem.services; -import com.ddf.vodsystem.tools.Job; +import com.ddf.vodsystem.entities.Job; import jakarta.annotation.PostConstruct; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; diff --git a/src/main/java/com/ddf/vodsystem/tools/Job.java b/src/main/java/com/ddf/vodsystem/tools/Job.java deleted file mode 100644 index f148f20..0000000 --- a/src/main/java/com/ddf/vodsystem/tools/Job.java +++ /dev/null @@ -1,52 +0,0 @@ -package com.ddf.vodsystem.tools; - -import com.ddf.vodsystem.entities.ClipConfig; -import com.ddf.vodsystem.entities.JobStatus; -import com.ddf.vodsystem.services.CompressionService; -import lombok.Data; -import java.io.File; -import java.io.IOException; - -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -@Data -public class Job implements Runnable { - private static final Logger logger = LoggerFactory.getLogger(Job.class); - - private String uuid; - private File inputFile; - private File outputFile; - - // configs - private ClipConfig clipConfig; - - // job status - private JobStatus status = JobStatus.PENDING; - private Float progress = 0.0f; - - public Job(String uuid, File inputFile, File outputFile) { - this.uuid = uuid; - this.inputFile = inputFile; - this.outputFile = outputFile; - } - - @Override - public void run() { - logger.info("Job {} started", uuid); - this.status = JobStatus.RUNNING; - - CompressionService f = new CompressionService(inputFile, outputFile, clipConfig); - - try { - f.run(); - } catch (IOException | InterruptedException e) { - logger.error(e.getMessage()); - } - - - this.status = JobStatus.FINISHED; - inputFile.delete(); - logger.info("Job {} finished", uuid); - } -}