forked from jsl/video_editing_poc
Implement scheduler input claiming
This commit is contained in:
parent
702d768e33
commit
45092e23b0
|
|
@ -22,7 +22,7 @@ Note: the local machine's filesystem root is read-only in this workspace, so abs
|
|||
2. [x] Add folder scheduler configuration properties.
|
||||
3. [x] Create startup directory initialization for input, output, working, processed, and rejected folders.
|
||||
4. [x] Add deterministic scanner that picks one candidate video at a time.
|
||||
5. [ ] Add repeat-prevention by moving selected inputs to a working folder before processing.
|
||||
5. [x] Add repeat-prevention by moving selected inputs to a working folder before processing.
|
||||
6. [ ] Add valid-video detection using extension filtering and `ffprobe`.
|
||||
7. [ ] Add invalid-file handling that logs the reason and moves files to rejected storage.
|
||||
8. [ ] Add FFmpeg clipping into `/output/clips/<video-name>/` using 8-second MP4/H.264/AAC segments.
|
||||
|
|
|
|||
|
|
@ -11,6 +11,7 @@ import java.io.IOException;
|
|||
import java.math.BigInteger;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.StandardCopyOption;
|
||||
import java.util.Comparator;
|
||||
import java.util.Optional;
|
||||
import java.util.concurrent.atomic.AtomicBoolean;
|
||||
|
|
@ -38,7 +39,10 @@ public class FolderVideoScanScheduler {
|
|||
|
||||
try {
|
||||
findNextCandidate().ifPresentOrElse(
|
||||
candidate -> log.info("Selected folder video candidate for processing: {}", candidate.getFileName()),
|
||||
candidate -> {
|
||||
Path workingFile = moveToWorking(candidate);
|
||||
log.info("Claimed folder video candidate for processing: {}", workingFile.getFileName());
|
||||
},
|
||||
() -> log.debug("No folder video candidate found in {}", properties.getInputDirectory())
|
||||
);
|
||||
} finally {
|
||||
|
|
@ -46,6 +50,16 @@ public class FolderVideoScanScheduler {
|
|||
}
|
||||
}
|
||||
|
||||
Path moveToWorking(Path candidate) {
|
||||
Path workingFile = Path.of(properties.getWorkingDirectory()).resolve(candidate.getFileName());
|
||||
try {
|
||||
return Files.move(candidate, workingFile, StandardCopyOption.ATOMIC_MOVE);
|
||||
} catch (IOException ex) {
|
||||
throw new IllegalStateException("Unable to move folder video candidate to working directory: "
|
||||
+ candidate.getFileName(), ex);
|
||||
}
|
||||
}
|
||||
|
||||
Optional<Path> findNextCandidate() {
|
||||
Path inputDirectory = Path.of(properties.getInputDirectory());
|
||||
if (!Files.isDirectory(inputDirectory)) {
|
||||
|
|
|
|||
|
|
@ -92,6 +92,8 @@ class FolderVideoScanSchedulerTest {
|
|||
scheduler.scan();
|
||||
|
||||
assertFalse(((AtomicBoolean) scanningField.get(scheduler)).get());
|
||||
assertFalse(Files.exists(tempDir.resolve("1.mp4")));
|
||||
assertTrue(Files.exists(tempDir.resolve("working/1.mp4")));
|
||||
}
|
||||
|
||||
@Test
|
||||
|
|
@ -105,9 +107,38 @@ class FolderVideoScanSchedulerTest {
|
|||
assertFalse(((AtomicBoolean) scanningField.get(scheduler)).get());
|
||||
}
|
||||
|
||||
@Test
|
||||
void claimedCandidateIsNotSelectedAgain() throws Exception {
|
||||
Files.writeString(tempDir.resolve("1.mp4"), "video");
|
||||
FolderVideoScanScheduler scheduler = scheduler(tempDir);
|
||||
|
||||
scheduler.scan();
|
||||
|
||||
assertTrue(scheduler.findNextCandidate().isEmpty());
|
||||
assertEquals("video", Files.readString(tempDir.resolve("working/1.mp4")));
|
||||
}
|
||||
|
||||
@Test
|
||||
void failsWhenCandidateCannotBeMovedToWorkingDirectory() throws Exception {
|
||||
Path candidate = Files.writeString(tempDir.resolve("1.mp4"), "video");
|
||||
Files.writeString(tempDir.resolve("working"), "not a directory");
|
||||
|
||||
assertThrows(IllegalStateException.class, () -> scheduler(tempDir).moveToWorking(candidate));
|
||||
assertTrue(Files.exists(candidate));
|
||||
}
|
||||
|
||||
private FolderVideoScanScheduler scheduler(Path inputDirectory) {
|
||||
VideoClippingProperties properties = new VideoClippingProperties();
|
||||
properties.getFolderScheduler().setInputDirectory(inputDirectory.toString());
|
||||
Path workingDirectory = tempDir.resolve("working");
|
||||
if (!Files.exists(workingDirectory)) {
|
||||
try {
|
||||
Files.createDirectory(workingDirectory);
|
||||
} catch (Exception ex) {
|
||||
throw new IllegalStateException(ex);
|
||||
}
|
||||
}
|
||||
properties.getFolderScheduler().setWorkingDirectory(workingDirectory.toString());
|
||||
return new FolderVideoScanScheduler(properties);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue