103 lines
3.4 KiB
Java
103 lines
3.4 KiB
Java
package tech.bitgoblin.video;
|
|
|
|
import java.io.BufferedReader;
|
|
import java.io.File;
|
|
import java.io.InputStream;
|
|
import java.io.InputStreamReader;
|
|
import java.io.IOException;
|
|
import java.lang.InterruptedException;
|
|
import java.lang.Process;
|
|
import java.nio.file.Path;
|
|
import java.nio.file.Paths;
|
|
import java.util.function.Consumer;
|
|
import java.util.concurrent.Executors;
|
|
|
|
import tech.bitgoblin.io.IOUtils;
|
|
|
|
public class Transcoder {
|
|
|
|
private String repo_dir;
|
|
private String ffmpeg_path = "/usr/bin/ffmpeg";
|
|
|
|
// only define the working directory; use default FFMPEG path
|
|
public Transcoder(String repo_dir) {
|
|
this.repo_dir = IOUtils.resolveTilda(repo_dir);
|
|
this.initDirectory();
|
|
}
|
|
// define a custom FFMPEG binary path
|
|
public Transcoder(String repo_dir, String ffmpeg_path) {
|
|
this.repo_dir = IOUtils.resolveTilda(repo_dir);
|
|
this.ffmpeg_path = ffmpeg_path;
|
|
this.initDirectory();
|
|
}
|
|
|
|
// transcode files in the working directory
|
|
public void transcode() {
|
|
// search for files
|
|
System.out.println("Searching for files to transcode in " + this.repo_dir);
|
|
File repo = new File(Paths.get(this.repo_dir, "ingest").toString());
|
|
File[] sourceFiles = repo.listFiles();
|
|
|
|
// transcode
|
|
System.out.println("Transcoding files in " + this.repo_dir + "/ingest...");
|
|
for (File f : sourceFiles) {
|
|
String filePath = f.toString().substring(0, f.toString().lastIndexOf("."));
|
|
String filename = Paths.get(filePath).getFileName().toString();
|
|
String outputPath = Paths.get(this.repo_dir, "output", String.format("%s.mov", filename)).toString();
|
|
|
|
String cmd = String.format("%s -i %s -c:v %s -vf \"%s\" -profile:v %s -c:a %s %s",
|
|
this.ffmpeg_path, // FFMPEG binary path
|
|
f.toString(), // input file
|
|
"dnxhd", // video codec
|
|
"scale=1920x1080,fps=60,format=yuv422p", // video format
|
|
"dnxhr_hq", // video profile
|
|
"pcm_s16le", // audio codec
|
|
outputPath // output file path
|
|
);
|
|
|
|
ProcessBuilder pb = new ProcessBuilder(cmd.split("\\s+"));
|
|
pb.redirectErrorStream(true);
|
|
pb.redirectOutput(ProcessBuilder.Redirect.PIPE);
|
|
try {
|
|
Process process = pb.start();
|
|
int ret = process.waitFor();
|
|
System.out.printf("Program exited with code: %d", ret);
|
|
} catch (IOException | InterruptedException e) {
|
|
throw new RuntimeException(e);
|
|
}
|
|
}
|
|
|
|
// end output
|
|
System.out.println("------------ End of transcoding ------------");
|
|
System.out.println();
|
|
}
|
|
|
|
// ensures the transcoder's working directory is available
|
|
private void initDirectory() {
|
|
// create transcoder directory
|
|
IOUtils.createDirectory(this.repo_dir);
|
|
// create the sub-directories
|
|
IOUtils.createDirectory(Paths.get(this.repo_dir, "ingest").toString());
|
|
IOUtils.createDirectory(Paths.get(this.repo_dir, "archive").toString());
|
|
IOUtils.createDirectory(Paths.get(this.repo_dir, "output").toString());
|
|
}
|
|
|
|
|
|
// Stream handler class for the Transcoder
|
|
private static class StreamGobbler implements Runnable {
|
|
private InputStream inputStream;
|
|
private Consumer<String> consumer;
|
|
|
|
public StreamGobbler(InputStream inputStream, Consumer<String> consumer) {
|
|
this.inputStream = inputStream;
|
|
this.consumer = consumer;
|
|
}
|
|
|
|
@Override
|
|
public void run() {
|
|
new BufferedReader(new InputStreamReader(inputStream)).lines().forEach(consumer);
|
|
}
|
|
}
|
|
|
|
}
|