Improve handling of the orignal and pp files

This commit is contained in:
0xb00bface 2020-09-22 12:38:21 +02:00
parent fbf1c8ac16
commit e1bce0acf5
19 changed files with 168 additions and 38 deletions

View File

@ -157,6 +157,7 @@ public class JavaFxRecording extends Recording {
setStatus(updated.getStatus());
setProgress(updated.getProgress());
setSizeInByte(updated.getSizeInByte());
setSingleFile(updated.isSingleFile());
}
@Override
@ -188,6 +189,11 @@ public class JavaFxRecording extends Recording {
return delegate.isSingleFile();
}
@Override
public void setSingleFile(boolean singleFile) {
delegate.setSingleFile(singleFile);
}
@Override
public boolean isPinned() {
return delegate.isPinned();

View File

@ -559,7 +559,6 @@ public class RecordingsTab extends Tab implements TabSelectionListener {
}
private void onOpenDirectory(JavaFxRecording first) {
String recordingsDir = Config.getInstance().getSettings().recordingsDir;
File tsFile = first.getAbsoluteFile();
new Thread(() -> DesktopIntegration.open(tsFile.getParent())).start();
}

View File

@ -50,6 +50,10 @@
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
</dependency>
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
</dependency>
<dependency>
<groupId>org.openjfx</groupId>
<artifactId>javafx-controls</artifactId>

View File

@ -3,7 +3,7 @@ package ctbrec;
public class NotImplementedExcetion extends RuntimeException {
public NotImplementedExcetion() {
super();
super("Not implemented");
}
public NotImplementedExcetion(String mesg) {

View File

@ -17,12 +17,14 @@ public class IoUtils {
public static void deleteEmptyParents(File parent) throws IOException {
File recDir = new File(Config.getInstance().getSettings().recordingsDir);
while (parent != null && parent.list() != null && parent.list().length == 0) {
while (parent != null && (parent.list() != null && parent.list().length == 0 || !parent.exists()) ) {
if (parent.equals(recDir)) {
return;
}
if(parent.exists()) {
LOG.debug("Deleting empty directory {}", parent.getAbsolutePath());
Files.delete(parent.toPath());
}
parent = parent.getParentFile();
}
}

View File

@ -165,7 +165,7 @@ public class NextGenLocalRecorder implements Recorder {
List<PostProcessor> postProcessors = config.getSettings().postProcessors;
for (PostProcessor postProcessor : postProcessors) {
LOG.debug("Running post-processor: {}", postProcessor.getName());
postProcessor.postprocess(recording);
postProcessor.postprocess(recording, config);
}
setRecordingStatus(recording, State.FINISHED);
recordingManager.saveRecording(recording);
@ -652,6 +652,7 @@ public class NextGenLocalRecorder implements Recorder {
Download download = other.getModel().createDownload();
download.init(Config.getInstance(), other.getModel(), other.getStartDate());
other.setDownload(download);
other.setPostProcessedFile(null);
submitPostProcessingJob(other);
return;
}

View File

@ -29,7 +29,7 @@ public abstract class AbstractPlaceholderAwarePostProcessor extends AbstractPost
"${recordingsDir}"
};
public String fillInPlaceHolders(String input, Recording rec) {
public String fillInPlaceHolders(String input, Recording rec, Config config) {
// @formatter:off
String output = input
.replace("${modelName}", ofNullable(rec.getModel().getName()).orElse("modelName"))
@ -39,8 +39,8 @@ public abstract class AbstractPlaceholderAwarePostProcessor extends AbstractPost
.replace("${siteSanitizedName}", getSanitizedSiteName(rec))
.replace("${fileSuffix}", getFileSuffix(rec))
.replace("${epochSecond}", Long.toString(rec.getStartDate().getEpochSecond()))
.replace("${modelNotes}", Config.getInstance().getModelNotes(rec.getModel()))
.replace("${recordingsDir}", Config.getInstance().getSettings().recordingsDir)
.replace("${modelNotes}", config.getModelNotes(rec.getModel()))
.replace("${recordingsDir}", config.getSettings().recordingsDir)
;
output = replaceUtcDateTime(rec, output);

View File

@ -2,12 +2,13 @@ package ctbrec.recorder.postprocessing;
import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import org.apache.commons.io.FileUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.google.common.io.Files;
import ctbrec.Config;
import ctbrec.Recording;
public class Copy extends AbstractPostProcessor {
@ -20,20 +21,28 @@ public class Copy extends AbstractPostProcessor {
}
@Override
public void postprocess(Recording rec) throws IOException, InterruptedException {
public void postprocess(Recording rec, Config config) throws IOException, InterruptedException {
File orig = rec.getPostProcessedFile();
String copyFilename = getFilenameForCopy(orig);
File copy = new File(orig.getParentFile(), copyFilename);
LOG.info("Creating a copy {}", copy);
Files.copy(rec.getPostProcessedFile(), copy);
if (orig.isFile()) {
Files.copy(rec.getPostProcessedFile().toPath(), copy.toPath());
} else {
FileUtils.copyDirectory(orig, copy, true);
}
rec.setPostProcessedFile(copy);
rec.getAssociatedFiles().add(copy.getCanonicalPath());
}
private String getFilenameForCopy(File orig) {
String filename = orig.getName();
if (orig.isFile()) {
String name = filename.substring(0, filename.lastIndexOf('.'));
String ext = filename.substring(filename.lastIndexOf('.') + 1);
return name + "_copy." + ext;
} else {
return filename + "_copy";
}
}
}

View File

@ -0,0 +1,20 @@
package ctbrec.recorder.postprocessing;
import java.io.IOException;
import ctbrec.Config;
import ctbrec.NotImplementedExcetion;
import ctbrec.Recording;
public class CreateContactSheet extends AbstractPlaceholderAwarePostProcessor {
@Override
public String getName() {
return "create contact sheet";
}
@Override
public void postprocess(Recording rec, Config config) throws IOException, InterruptedException {
throw new NotImplementedExcetion();
}
}

View File

@ -0,0 +1,20 @@
package ctbrec.recorder.postprocessing;
import java.io.IOException;
import ctbrec.Config;
import ctbrec.NotImplementedExcetion;
import ctbrec.Recording;
public class CreateTimelineThumbs extends AbstractPlaceholderAwarePostProcessor {
@Override
public String getName() {
return "create timeline thumbnails";
}
@Override
public void postprocess(Recording rec, Config config) throws IOException, InterruptedException {
throw new NotImplementedExcetion();
}
}

View File

@ -5,6 +5,7 @@ import static ctbrec.io.IoUtils.*;
import java.io.IOException;
import java.nio.file.Files;
import ctbrec.Config;
import ctbrec.Recording;
public class DeleteOriginal extends AbstractPostProcessor {
@ -15,7 +16,7 @@ public class DeleteOriginal extends AbstractPostProcessor {
}
@Override
public void postprocess(Recording rec) throws IOException, InterruptedException {
public void postprocess(Recording rec, Config config) throws IOException, InterruptedException {
if (rec.getAbsoluteFile().isFile()) {
Files.deleteIfExists(rec.getAbsoluteFile().toPath());
deleteEmptyParents(rec.getAbsoluteFile().getParentFile());

View File

@ -3,13 +3,13 @@ import static ctbrec.io.IoUtils.*;
import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.util.Objects;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.google.common.io.Files;
import ctbrec.Config;
import ctbrec.Recording;
public class Move extends AbstractPlaceholderAwarePostProcessor {
@ -24,17 +24,17 @@ public class Move extends AbstractPlaceholderAwarePostProcessor {
}
@Override
public void postprocess(Recording rec) throws IOException {
public void postprocess(Recording rec, Config config) throws IOException {
String pathTemplate = getConfig().getOrDefault(PATH_TEMPLATE, DEFAULT);
String path = fillInPlaceHolders(pathTemplate, rec);
String path = fillInPlaceHolders(pathTemplate, rec, config);
File src = rec.getPostProcessedFile();
File target = new File(path, src.getName());
if (Objects.equals(src, target)) {
return;
}
LOG.info("Moving {} to {}", src.getName(), target.getParentFile().getCanonicalPath());
Files.createParentDirs(target);
Files.move(rec.getPostProcessedFile(), target);
Files.createDirectories(target.getParentFile().toPath());
Files.move(rec.getPostProcessedFile().toPath(), target.toPath());
rec.setPostProcessedFile(target);
if (Objects.equals(src, rec.getAbsoluteFile())) {
rec.setAbsoluteFile(target);

View File

@ -4,12 +4,13 @@ import java.io.IOException;
import java.io.Serializable;
import java.util.Map;
import ctbrec.Config;
import ctbrec.Recording;
public interface PostProcessor extends Serializable {
String getName();
void postprocess(Recording rec) throws IOException, InterruptedException;
void postprocess(Recording rec, Config config) throws IOException, InterruptedException;
Map<String, String> getConfig();
void setConfig(Map<String, String> conf);

View File

@ -0,0 +1,20 @@
package ctbrec.recorder.postprocessing;
import java.io.IOException;
import ctbrec.Config;
import ctbrec.NotImplementedExcetion;
import ctbrec.Recording;
public class RemoveKeepFile extends AbstractPostProcessor {
@Override
public String getName() {
return "remove recording, but keep the files";
}
@Override
public void postprocess(Recording rec, Config config) throws IOException, InterruptedException {
throw new NotImplementedExcetion();
}
}

View File

@ -5,12 +5,15 @@ import java.io.FileOutputStream;
import java.io.IOException;
import java.nio.file.Files;
import java.util.Arrays;
import java.util.Objects;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import ctbrec.Config;
import ctbrec.OS;
import ctbrec.Recording;
import ctbrec.io.IoUtils;
import ctbrec.io.StreamRedirectThread;
import ctbrec.recorder.download.ProcessExitedUncleanException;
@ -27,15 +30,18 @@ public class Remux extends AbstractPostProcessor {
}
@Override
public void postprocess(Recording rec) throws IOException, InterruptedException {
public void postprocess(Recording rec, Config config) throws IOException, InterruptedException {
String fileExt = getConfig().get(FILE_EXT);
String[] args = getConfig().get(FFMPEG_ARGS).split(" ");
String[] argsPlusFile = new String[args.length + 3];
File inputFile = rec.getPostProcessedFile();
if (inputFile.isDirectory()) {
inputFile = new File(inputFile, "playlist.m3u8");
}
int i = 0;
argsPlusFile[i++] = "-i";
argsPlusFile[i++] = rec.getPostProcessedFile().getAbsolutePath();
argsPlusFile[i++] = inputFile.getCanonicalPath();
System.arraycopy(args, 0, argsPlusFile, i, args.length);
File inputFile = rec.getPostProcessedFile();
File remuxedFile = new File(rec.getPostProcessedFile().getAbsolutePath() + '.' + fileExt);
argsPlusFile[argsPlusFile.length - 1] = remuxedFile.getAbsolutePath();
String[] cmdline = OS.getFFmpegCommand(argsPlusFile);
@ -43,16 +49,29 @@ public class Remux extends AbstractPostProcessor {
Process ffmpeg = Runtime.getRuntime().exec(cmdline, new String[0], rec.getPostProcessedFile().getParentFile());
setupLogging(ffmpeg, rec);
rec.setPostProcessedFile(remuxedFile);
if (inputFile.getName().equals("playlist.m3u8")) {
IoUtils.deleteDirectory(inputFile.getParentFile());
if (Objects.equals(inputFile.getParentFile(), rec.getAbsoluteFile())) {
rec.setAbsoluteFile(remuxedFile);
}
} else {
Files.deleteIfExists(inputFile.toPath());
if (Objects.equals(inputFile, rec.getAbsoluteFile())) {
rec.setAbsoluteFile(remuxedFile);
}
}
IoUtils.deleteEmptyParents(inputFile.getParentFile());
rec.getAssociatedFiles().remove(inputFile.getCanonicalPath());
rec.getAssociatedFiles().add(remuxedFile.getCanonicalPath());
rec.setSingleFile(true);
rec.setSizeInByte(remuxedFile.length());
}
private void setupLogging(Process ffmpeg, Recording rec) throws IOException, InterruptedException {
int exitCode = 1;
File video = rec.getPostProcessedFile();
File ffmpegLog = new File(video.getParentFile(), video.getName() + ".ffmpeg.log");
rec.getAssociatedFiles().add(ffmpegLog.getCanonicalPath());
try (FileOutputStream mergeLogStream = new FileOutputStream(ffmpegLog)) {
Thread stdout = new Thread(new StreamRedirectThread(ffmpeg.getInputStream(), mergeLogStream));
Thread stderr = new Thread(new StreamRedirectThread(ffmpeg.getErrorStream(), mergeLogStream));
@ -67,6 +86,7 @@ public class Remux extends AbstractPostProcessor {
if (exitCode != 1) {
if (ffmpegLog.exists()) {
Files.delete(ffmpegLog.toPath());
rec.getAssociatedFiles().remove(ffmpegLog.getCanonicalPath());
}
} else {
rec.getAssociatedFiles().add(ffmpegLog.getAbsolutePath());

View File

@ -1,13 +1,13 @@
package ctbrec.recorder.postprocessing;
import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.util.Objects;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.google.common.io.Files;
import ctbrec.Config;
import ctbrec.Recording;
public class Rename extends AbstractPlaceholderAwarePostProcessor {
@ -22,16 +22,16 @@ public class Rename extends AbstractPlaceholderAwarePostProcessor {
}
@Override
public void postprocess(Recording rec) throws IOException {
public void postprocess(Recording rec, Config config) throws IOException {
String filenameTemplate = getConfig().getOrDefault(FILE_NAME_TEMPLATE, DEFAULT);
String filename = fillInPlaceHolders(filenameTemplate, rec);
String filename = fillInPlaceHolders(filenameTemplate, rec, config);
File src = rec.getPostProcessedFile();
File target = new File(src.getParentFile(), filename);
if (Objects.equals(src, target)) {
return;
}
LOG.info("Renaming {} to {}", src.getName(), target.getName());
Files.move(rec.getPostProcessedFile(), target);
Files.move(rec.getPostProcessedFile().toPath(), target.toPath());
rec.setPostProcessedFile(target);
if (Objects.equals(src, rec.getAbsoluteFile())) {
rec.setAbsoluteFile(target);

View File

@ -0,0 +1,21 @@
package ctbrec.recorder.postprocessing;
import java.io.IOException;
import ctbrec.Config;
import ctbrec.NotImplementedExcetion;
import ctbrec.Recording;
public class Script extends AbstractPlaceholderAwarePostProcessor {
@Override
public String getName() {
return "execute script";
}
@Override
public void postprocess(Recording rec, Config config) throws IOException, InterruptedException {
// TODO make it possible to choose, which placeholders to pass to the script
throw new NotImplementedExcetion();
}
}

View File

@ -103,6 +103,11 @@
<artifactId>guava</artifactId>
<version>17.0</version>
</dependency>
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<version>2.8.0</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>

View File

@ -40,8 +40,6 @@ public class HlsServlet extends AbstractCtbrecServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
String contextPath = getServletContext().getContextPath();
String request = req.getRequestURI().substring(contextPath.length() + 5);
Path recordingsDirPath = Paths.get(config.getSettings().recordingsDir).toAbsolutePath().normalize();
@ -68,7 +66,10 @@ public class HlsServlet extends AbstractCtbrecServlet {
String id = request.split("/")[0];
Optional<Recording> rec = getRecordingById(id);
if (rec.isPresent()) {
File file = rec.get().getAbsoluteFile();
File path = rec.get().getAbsoluteFile();
if (!path.isFile()) {
path = new File(path, requestedFile.getName());
}
if (LOG.isTraceEnabled()) {
Enumeration<String> headerNames = req.getHeaderNames();
while (headerNames.hasMoreElements()) {
@ -76,7 +77,7 @@ public class HlsServlet extends AbstractCtbrecServlet {
LOG.trace("{}: {}", header, req.getHeader(header));
}
}
serveSegment(req, resp, file);
serveSegment(req, resp, path);
} else {
error404(req, resp);
return;