diff --git a/src/main/java/com/ddf/vodsystem/services/media/CommandRunner.java b/src/main/java/com/ddf/vodsystem/services/media/CommandRunner.java index e3478d5..c0f00b6 100644 --- a/src/main/java/com/ddf/vodsystem/services/media/CommandRunner.java +++ b/src/main/java/com/ddf/vodsystem/services/media/CommandRunner.java @@ -2,6 +2,7 @@ package com.ddf.vodsystem.services.media; import com.ddf.vodsystem.dto.CommandOutput; import com.ddf.vodsystem.dto.ProgressTracker; +import org.springframework.stereotype.Component; import java.io.BufferedReader; import java.io.IOException; @@ -11,10 +12,11 @@ import java.util.function.Consumer; import java.util.regex.Matcher; import java.util.regex.Pattern; +@Component public class CommandRunner { private static final Pattern timePattern = Pattern.compile("out_time_ms=(\\d+)"); - public static CommandOutput run(List command, Consumer onOutput) throws IOException, InterruptedException { + public CommandOutput run(List command, Consumer onOutput) throws IOException, InterruptedException { ProcessBuilder processBuilder = new ProcessBuilder(command); processBuilder.redirectErrorStream(true); @@ -41,19 +43,15 @@ public class CommandRunner { return commandOutput; } - public static CommandOutput run(List command) throws IOException, InterruptedException { + public CommandOutput run(List command) throws IOException, InterruptedException { return run(command, null); } - public static void setProgress(String line, ProgressTracker progress, float length) { + public void setProgress(String line, ProgressTracker progress, float length) { Matcher matcher = timePattern.matcher(line); if (matcher.find()) { float timeInMs = Float.parseFloat(matcher.group(1)) / 1000000f; progress.setProgress(timeInMs / length); } } - - private CommandRunner() { - // Private constructor to prevent instantiation - } } \ No newline at end of file diff --git a/src/main/java/com/ddf/vodsystem/services/media/CompressionService.java b/src/main/java/com/ddf/vodsystem/services/media/CompressionService.java index 883bf3c..4b1c299 100644 --- a/src/main/java/com/ddf/vodsystem/services/media/CompressionService.java +++ b/src/main/java/com/ddf/vodsystem/services/media/CompressionService.java @@ -13,17 +13,19 @@ import java.nio.file.Path; import java.util.ArrayList; import java.util.List; import java.util.concurrent.CompletableFuture; -import java.util.regex.Matcher; -import java.util.regex.Pattern; @Service public class CompressionService { private static final Logger logger = LoggerFactory.getLogger(CompressionService.class); + private final CommandRunner commandRunner; private static final float AUDIO_RATIO = 0.15f; private static final float MAX_AUDIO_BITRATE = 128f; private static final float BITRATE_MULTIPLIER = 0.9f; - private final Pattern timePattern = Pattern.compile("out_time_ms=(\\d+)"); + + public CompressionService(CommandRunner commandRunner) { + this.commandRunner = commandRunner; + } @Async("ffmpegTaskExecutor") public CompletableFuture compress(Path inputFile, @@ -38,20 +40,12 @@ public class CompressionService { outputFile, clipOptions ); - CommandOutput result = CommandRunner.run(command, line -> CommandRunner.setProgress(line, progress, clipOptions.getDuration())); + CommandOutput result = commandRunner.run(command, line -> commandRunner.setProgress(line, progress, clipOptions.getDuration())); progress.markComplete(); return CompletableFuture.completedFuture(result); } - private void setProgress(String line, ProgressTracker progress, float length) { - Matcher matcher = timePattern.matcher(line); - if (matcher.find()) { - float timeInMs = Float.parseFloat(matcher.group(1)) / 1000000f; - progress.setProgress(timeInMs / length); - } - } - private List buildFilters(Float fps, Integer width, Integer height) { List command = new ArrayList<>(); command.add("-vf"); diff --git a/src/main/java/com/ddf/vodsystem/services/media/MetadataService.java b/src/main/java/com/ddf/vodsystem/services/media/MetadataService.java index 9bf26b0..07a093e 100644 --- a/src/main/java/com/ddf/vodsystem/services/media/MetadataService.java +++ b/src/main/java/com/ddf/vodsystem/services/media/MetadataService.java @@ -19,9 +19,14 @@ import java.util.concurrent.Future; @Service public class MetadataService { private static final Logger logger = LoggerFactory.getLogger(MetadataService.class); + public final CommandRunner commandRunner; private static final String DURATION = "duration"; + public MetadataService(CommandRunner commandRunner) { + this.commandRunner = commandRunner; + } + @Async("ffmpegTaskExecutor") public Future getVideoMetadata(Path file) { logger.info("Getting metadata for file {}", file); @@ -39,7 +44,7 @@ public class MetadataService { StringBuilder outputBuilder = new StringBuilder(); try { - CommandOutput output = CommandRunner.run(command); + CommandOutput output = commandRunner.run(command); for (String line : output.getOutput()) { outputBuilder.append(line); diff --git a/src/main/java/com/ddf/vodsystem/services/media/RemuxService.java b/src/main/java/com/ddf/vodsystem/services/media/RemuxService.java index 86c4c2d..3fffafb 100644 --- a/src/main/java/com/ddf/vodsystem/services/media/RemuxService.java +++ b/src/main/java/com/ddf/vodsystem/services/media/RemuxService.java @@ -9,12 +9,14 @@ import java.io.File; import java.io.IOException; import java.util.List; import java.util.concurrent.CompletableFuture; -import java.util.regex.Matcher; -import java.util.regex.Pattern; @Service public class RemuxService { - private final Pattern timePattern = Pattern.compile("out_time_ms=(\\d+)"); + private final CommandRunner commandRunner; + + public RemuxService(CommandRunner commandRunner) { + this.commandRunner = commandRunner; + } @Async("ffmpegTaskExecutor") public CompletableFuture remux(File inputFile, @@ -33,14 +35,7 @@ public class RemuxService { outputFile.getAbsolutePath() ); - return CompletableFuture.completedFuture(CommandRunner.run(command, line -> setProgress(line, remuxProgress, length))); - } - - private void setProgress(String line, ProgressTracker progress, float length) { - Matcher matcher = timePattern.matcher(line); - if (matcher.find()) { - float timeInMs = Float.parseFloat(matcher.group(1)) / 1000000f; - progress.setProgress(timeInMs / length); - } + return CompletableFuture.completedFuture(commandRunner.run(command, line -> + commandRunner.setProgress(line, remuxProgress, length))); } } diff --git a/src/main/java/com/ddf/vodsystem/services/media/StreamActionsService.java b/src/main/java/com/ddf/vodsystem/services/media/StreamActionsService.java index 201cc22..f8fec8a 100644 --- a/src/main/java/com/ddf/vodsystem/services/media/StreamActionsService.java +++ b/src/main/java/com/ddf/vodsystem/services/media/StreamActionsService.java @@ -23,6 +23,11 @@ import java.util.stream.Collectors; @Service public class StreamActionsService { private static final Logger logger = LoggerFactory.getLogger(StreamActionsService.class); + private final CommandRunner commandRunner; + + public StreamActionsService(CommandRunner commandRunner) { + this.commandRunner = commandRunner; + } /** * Concatenates a list of video segments and extracts a trimmed section @@ -71,7 +76,7 @@ public class StreamActionsService { logger.info("Saving section with ({} segments) to '{}'", segments.size(), outputFile); - CommandRunner.run(command, line -> CommandRunner.setProgress(line, progressTracker, duration)); + commandRunner.run(command, line -> commandRunner.setProgress(line, progressTracker, duration)); progressTracker.markComplete(); return CompletableFuture.completedFuture(outputFile); diff --git a/src/main/java/com/ddf/vodsystem/services/media/ThumbnailService.java b/src/main/java/com/ddf/vodsystem/services/media/ThumbnailService.java index 7e11508..7df5d18 100644 --- a/src/main/java/com/ddf/vodsystem/services/media/ThumbnailService.java +++ b/src/main/java/com/ddf/vodsystem/services/media/ThumbnailService.java @@ -12,6 +12,11 @@ import java.util.List; @Service public class ThumbnailService { private static final Logger logger = LoggerFactory.getLogger(ThumbnailService.class); + private final CommandRunner commandRunner; + + public ThumbnailService(CommandRunner commandRunner) { + this.commandRunner = commandRunner; + } @Async("ffmpegTaskExecutor") public void createThumbnail(Path inputFile, Path outputFile, Float timeInVideo) throws IOException, InterruptedException { @@ -25,6 +30,6 @@ public class ThumbnailService { outputFile.toAbsolutePath().toString() ); - CommandRunner.run(command); + commandRunner.run(command); } }