MOVE clip creation method from ClipService to JobService

The original clip creation method in ClipService handled many different services, like metadata handling, callback methods and more. Moving it to a more suitable location in the JobService allows it to easily access the Job object and update it upon failure.
This commit is contained in:
2025-12-15 21:23:01 +00:00
parent 0f5fc76e55
commit 65ec8cb29a
2 changed files with 36 additions and 52 deletions

View File

@@ -1,6 +1,5 @@
package com.ddf.vodsystem.services; package com.ddf.vodsystem.services;
import com.ddf.vodsystem.dto.ProgressTracker;
import com.ddf.vodsystem.dto.ClipOptions; import com.ddf.vodsystem.dto.ClipOptions;
import com.ddf.vodsystem.entities.*; import com.ddf.vodsystem.entities.*;
@@ -15,7 +14,6 @@ import java.util.concurrent.ExecutionException;
import com.ddf.vodsystem.exceptions.FFMPEGException; import com.ddf.vodsystem.exceptions.FFMPEGException;
import com.ddf.vodsystem.exceptions.NotAuthenticated; import com.ddf.vodsystem.exceptions.NotAuthenticated;
import com.ddf.vodsystem.repositories.ClipRepository; import com.ddf.vodsystem.repositories.ClipRepository;
import com.ddf.vodsystem.services.media.CompressionService;
import com.ddf.vodsystem.services.media.MetadataService; import com.ddf.vodsystem.services.media.MetadataService;
import com.ddf.vodsystem.services.media.ThumbnailService; import com.ddf.vodsystem.services.media.ThumbnailService;
import org.slf4j.Logger; import org.slf4j.Logger;
@@ -28,60 +26,22 @@ public class ClipService {
private final ClipRepository clipRepository; private final ClipRepository clipRepository;
private final DirectoryService directoryService; private final DirectoryService directoryService;
private final CompressionService compressionService;
private final MetadataService metadataService; private final MetadataService metadataService;
private final ThumbnailService thumbnailService; private final ThumbnailService thumbnailService;
private final UserService userService; private final UserService userService;
public ClipService(ClipRepository clipRepository, public ClipService(ClipRepository clipRepository,
DirectoryService directoryService, DirectoryService directoryService,
CompressionService compressionService,
MetadataService metadataService, MetadataService metadataService,
ThumbnailService thumbnailService, ThumbnailService thumbnailService,
UserService userService) { UserService userService) {
this.clipRepository = clipRepository; this.clipRepository = clipRepository;
this.directoryService = directoryService; this.directoryService = directoryService;
this.compressionService = compressionService;
this.metadataService = metadataService; this.metadataService = metadataService;
this.thumbnailService = thumbnailService; this.thumbnailService = thumbnailService;
this.userService = userService; this.userService = userService;
} }
/**
* Run the clip creation process.
* This method normalizes the input metadata, compresses the video file,
* updates the output metadata with the file size, and saves the clip
* to the database if the user is authenticated.
*
* @param inputMetadata The metadata of the input video file.
* @param outputMetadata The metadata for the output video file.
* @param inputFile The input video file to be processed.
* @param outputFile The output file where the processed video will be saved.
* @param progress A tracker to monitor the progress of the video processing.
* @throws IOException if an I/O error occurs during file processing.
* @throws InterruptedException if the thread is interrupted during processing.
*/
public void create(ClipOptions inputMetadata,
ClipOptions outputMetadata,
File inputFile,
File outputFile,
ProgressTracker progress)
throws IOException, InterruptedException {
Optional<User> user = userService.getLoggedInUser();
metadataService.normalizeVideoMetadata(inputMetadata, outputMetadata);
compressionService.compress(inputFile, outputFile, outputMetadata, progress)
.thenRun(() -> user.ifPresent(value ->
persistClip(
outputMetadata,
value,
outputFile,
inputFile.getName()
))).exceptionally(ex -> {
throw new FFMPEGException("FFMPEG Compression failed: " + ex.getMessage());
});
}
/** /**
* Retrieves all clips associated with the currently logged-in user. * Retrieves all clips associated with the currently logged-in user.
* *
@@ -161,7 +121,7 @@ public class ClipService {
return user.get().getId().equals(clip.getUser().getId()); return user.get().getId().equals(clip.getUser().getId());
} }
private void persistClip(ClipOptions clipOptions, public void persistClip(ClipOptions clipOptions,
User user, User user,
File tempFile, File tempFile,
String fileName) { String fileName) {

View File

@@ -4,11 +4,14 @@ import java.io.File;
import java.io.IOException; import java.io.IOException;
import java.nio.file.Files; import java.nio.file.Files;
import java.nio.file.Paths; import java.nio.file.Paths;
import java.util.Optional;
import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentHashMap;
import com.ddf.vodsystem.dto.Job; import com.ddf.vodsystem.dto.Job;
import com.ddf.vodsystem.exceptions.FFMPEGException; import com.ddf.vodsystem.entities.User;
import com.ddf.vodsystem.services.media.CompressionService;
import com.ddf.vodsystem.services.media.RemuxService; import com.ddf.vodsystem.services.media.RemuxService;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
@@ -26,16 +29,23 @@ public class JobService {
private final ClipService clipService; private final ClipService clipService;
private final RemuxService remuxService; private final RemuxService remuxService;
private final DirectoryService directoryService; private final DirectoryService directoryService;
private final CompressionService compressionService;
private final UserService userService;
/** /**
* Constructs a JobService with the given CompressionService. * Constructs a JobService with the given CompressionService.
* @param clipService the compression service to use for processing jobs * @param clipService the compression service to use for processing jobs
*/ */
public JobService(ClipService clipService, public JobService(ClipService clipService,
RemuxService remuxService, DirectoryService directoryService) { RemuxService remuxService,
CompressionService compressionService,
DirectoryService directoryService,
UserService userService) {
this.clipService = clipService; this.clipService = clipService;
this.remuxService = remuxService; this.remuxService = remuxService;
this.directoryService = directoryService; this.directoryService = directoryService;
this.compressionService = compressionService;
this.userService = userService;
} }
/** /**
@@ -84,7 +94,14 @@ public class JobService {
} catch (IOException e) { } catch (IOException e) {
throw new RuntimeException(e); throw new RuntimeException(e);
} }
}).whenComplete((ignored, throwable) -> {
if (throwable != null) {
logger.error("Remux failed for jobId={}", job.getUuid(), throwable);
} else {
logger.info("Remux completed for jobId={}", job.getUuid());
}
}); });
} catch (IOException | InterruptedException e) { } catch (IOException | InterruptedException e) {
logger.error("Error converting job {}: {}", job.getUuid(), e.getMessage()); logger.error("Error converting job {}: {}", job.getUuid(), e.getMessage());
Thread.currentThread().interrupt(); Thread.currentThread().interrupt();
@@ -100,18 +117,25 @@ public class JobService {
job.getStatus().getProcess().reset(); job.getStatus().getProcess().reset();
try { try {
clipService.create( Optional<User> user = userService.getLoggedInUser();
job.getInputClipOptions(), compressionService.compress(job.getInputFile(), job.getOutputFile(), job.getOutputClipOptions(), job.getStatus().getProcess())
job.getOutputClipOptions(), .thenRun(() -> user.ifPresent(value ->
job.getInputFile(), clipService.persistClip(
job.getOutputFile(), job.getOutputClipOptions(),
job.getStatus().getProcess() value,
); job.getOutputFile(),
job.getInputFile().getName()
)
)).exceptionally(
ex -> {
job.getStatus().setFailed(true);
return null;
}
);
} catch (IOException | InterruptedException e) { } catch (IOException | InterruptedException e) {
job.getStatus().setFailed(true);
logger.error("Error processing job {}: {}", job.getUuid(), e.getMessage()); logger.error("Error processing job {}: {}", job.getUuid(), e.getMessage());
Thread.currentThread().interrupt(); Thread.currentThread().interrupt();
} catch (FFMPEGException e) {
job.getStatus().setFailed(true);
} }
} }
} }