From cfba4342439f8f82517f7c545e88642bc1141efd Mon Sep 17 00:00:00 2001 From: EpicKnarvik97 Date: Tue, 13 Nov 2018 11:33:48 +0100 Subject: [PATCH] Adds hardsubbing of subtitles with same name as video file Better file collision detection Adds debug mode to only render part of the video --- .idea/artifacts/FFmpegConvert.xml | 11 +++ .idea/misc.xml | 2 +- src/ffmpegconverter/Main.java | 6 +- .../converter/AnimeConverter.java | 2 +- src/ffmpegconverter/converter/Converter.java | 12 ++++ .../converter/VideoConverter.java | 68 ++++++++++++++++--- 6 files changed, 86 insertions(+), 15 deletions(-) create mode 100644 .idea/artifacts/FFmpegConvert.xml diff --git a/.idea/artifacts/FFmpegConvert.xml b/.idea/artifacts/FFmpegConvert.xml new file mode 100644 index 0000000..43d09af --- /dev/null +++ b/.idea/artifacts/FFmpegConvert.xml @@ -0,0 +1,11 @@ + + + $PROJECT_DIR$/out/artifacts/FFmpegConvert + + + + + + + + \ No newline at end of file diff --git a/.idea/misc.xml b/.idea/misc.xml index 74384e8..a2598f9 100644 --- a/.idea/misc.xml +++ b/.idea/misc.xml @@ -3,7 +3,7 @@ - + \ No newline at end of file diff --git a/src/ffmpegconverter/Main.java b/src/ffmpegconverter/Main.java index 65f3c6e..8c43277 100644 --- a/src/ffmpegconverter/Main.java +++ b/src/ffmpegconverter/Main.java @@ -15,8 +15,8 @@ import java.util.function.Predicate; * Converts a files or files in a folder to a web playable mp4. */ public class Main { - private static final String FFPROBE_PATH = "C:\\Users\\Kristian\\Box Sync\\AutoIt\\FFMPEGConvert\\ffmpeg\\bin\\ffprobe"; //Can be just ffprobe if it's in the path - private static final String FFMPEG_PATH = "C:\\Users\\Kristian\\Box Sync\\AutoIt\\FFMPEGConvert\\ffmpeg\\bin\\ffmpeg"; //Can be just ffmpeg if it's in the path + private static final String FFPROBE_PATH = "C:\\Users\\Kristian\\Nextcloud\\Programming\\AutoIt\\FFMPEGConvert\\ffmpeg\\bin\\ffprobe"; //Can be just ffprobe if it's in the path + private static final String FFMPEG_PATH = "C:\\Users\\Kristian\\Nextcloud\\Programming\\AutoIt\\FFMPEGConvert\\ffmpeg\\bin\\ffmpeg"; //Can be just ffmpeg if it's in the path private static Scanner in = new Scanner(System.in); private static Converter con = null; @@ -70,7 +70,7 @@ public class Main { } private static void animeConverter() { - System.out.println("[Audio languages jap,eng,ger,fre] [Subtitle languages eng,ger,fre] [Convert to stareo if necessary true/false] [Prevent signs&songs subtitles true/false]\nYour input: "); + System.out.println("[Audio languages jap,eng,ger,fre] [Subtitle languages eng,ger,fre] [Convert to stereo if necessary true/false] [Prevent signs&songs subtitles true/false]\nYour input: "); List input = readInput(4); String[] audioLang = new String[]{"jpn"}; String[] subtitleLang = new String[]{"eng"}; diff --git a/src/ffmpegconverter/converter/AnimeConverter.java b/src/ffmpegconverter/converter/AnimeConverter.java index de172c3..292aac4 100644 --- a/src/ffmpegconverter/converter/AnimeConverter.java +++ b/src/ffmpegconverter/converter/AnimeConverter.java @@ -43,7 +43,7 @@ public class AnimeConverter extends Converter { if (streams.length == 0) { throw new IllegalArgumentException("The file has no streams"); } - String newPath = fileCollisionPrevention(stripExtension(file) + ".mp4", "mp4"); + String newPath = fileCollisionPrevention(folder.getAbsolutePath() + File.separator + stripExtension(file) + ".mp4", "mp4"); convertProcess(new ProcessBuilder(builderCommand(ffmpegPath, file.getName(), streams, newPath)), folder); } diff --git a/src/ffmpegconverter/converter/Converter.java b/src/ffmpegconverter/converter/Converter.java index 21c6f69..222e417 100644 --- a/src/ffmpegconverter/converter/Converter.java +++ b/src/ffmpegconverter/converter/Converter.java @@ -113,6 +113,13 @@ public abstract class Converter { return command; } + static void addDebug(List command, int start, int length) { + command.add("-ss"); + command.add("" + start); + command.add("-t"); + command.add("" + length); + } + /** * Checks for the occurrence of otf attachments signifying the existence of image based subtitles. * @@ -121,6 +128,7 @@ public abstract class Converter { */ static boolean isImageSub(String[] list, int index) { return list[index].contains("codec_name=hdmv_pgs_subtitle"); + //Filename .sup } /** @@ -291,6 +299,10 @@ public abstract class Converter { return file.getName().substring(0, file.getName().lastIndexOf('.')); } + static String stripExtension(String file) { + return file.substring(0, file.lastIndexOf('.')); + } + /** * Combines two arrays to one * diff --git a/src/ffmpegconverter/converter/VideoConverter.java b/src/ffmpegconverter/converter/VideoConverter.java index 41f9f56..5045265 100644 --- a/src/ffmpegconverter/converter/VideoConverter.java +++ b/src/ffmpegconverter/converter/VideoConverter.java @@ -6,6 +6,7 @@ import java.util.List; public class VideoConverter extends Converter { private String newExt; + private boolean debug = false; public VideoConverter(String ffprobePath, String ffmpegPath, String newExt) { this.ffprobePath = ffprobePath; @@ -25,8 +26,8 @@ public class VideoConverter extends Converter { if (streams.length == 0) { throw new IllegalArgumentException("The file has no streams"); } - String newPath = fileCollisionPrevention(stripExtension(file) + "." + newExt, newExt); - convertProcess(new ProcessBuilder(builderCommand(ffmpegPath, file.getName(), streams, newPath)), folder); + String newPath = fileCollisionPrevention(folder.getAbsolutePath() + File.separator + stripExtension(file) + "." + newExt, newExt); + convertProcess(new ProcessBuilder(builderCommand(ffmpegPath, file.getName(), streams, newPath, folder)), folder); } /** @@ -38,22 +39,69 @@ public class VideoConverter extends Converter { * @param outFile The output file * @return A list of commands */ - private String[] builderCommand(String executable, String fileName, String[] streams, String outFile) { + private String[] builderCommand(String executable, String fileName, String[] streams, String outFile, File folder) { List command = generalFile(executable, fileName); + + if (this.debug) { + addDebug(command, 50, 120); + } + List videoStreams = listVideo(streams); - if (videoStreams.size() > 0) { - command.add("-map"); - command.add("0:" + videoStreams.get(0)); - } List audioStreams = listAudio(streams); - if (audioStreams.size() > 0) { - command.add("-map"); - command.add("0:" + audioStreams.get(0)); + + String ext = hasExternalSubtitle(folder.getAbsolutePath(), fileName); + String ext2 = hasExternalImageSubtitle(folder.getAbsolutePath(), fileName); + if (!ext.equals("")) { + command.add("-vf"); + command.add("subtitles=" + stripExtension(fileName) + ext); + } else if (!ext2.equals("")) { + command.add("-i"); + command.add(stripExtension(fileName) + ext2); + if (this.debug) { + addDebug(command, 50, 120); + } + //TODO: Scale subtitles to video + command.add("-filter_complex"); + command.add("[1:s]scale=width=1920:height=808,crop=w=1920:h=808:x=0:y=out_h[sub];[" + videoStreams.get(0) + ":v][sub]overlay"); + command.add("-profile:v"); + command.add("baseline"); } + + if (ext2.equals("") || !ext.equals("")) { + if (videoStreams.size() > 0) { + command.add("-map"); + command.add("0:" + videoStreams.get(0)); + } + if (audioStreams.size() > 0) { + command.add("-map"); + command.add("0:" + audioStreams.get(0)); + } + } + command.add(outFile); return command.toArray(new String[0]); } + private String hasExternalImageSubtitle(String directory, String file) { + String path = stripExtension(file); + for (String s : new String[] {".idx", ".sub"}) { + if (new File(directory + File.separator + path + s).exists()) { + return s; + } + } + return ""; + } + + private String hasExternalSubtitle(String directory, String file) { + String path = stripExtension(file); + for (String s : new String[] {".srt", ".ass"}) { + if (new File(directory + File.separator + path + s).exists()) { + return s; + } + } + return ""; + } + @Override public String[] getValidFormats() { return VIDEO_FORMATS;