diff --git a/src/main/java/net/knarcraft/ffmpegconverter/FFMpegConvert.java b/src/main/java/net/knarcraft/ffmpegconverter/FFMpegConvert.java index a65450d..b0ac594 100644 --- a/src/main/java/net/knarcraft/ffmpegconverter/FFMpegConvert.java +++ b/src/main/java/net/knarcraft/ffmpegconverter/FFMpegConvert.java @@ -3,6 +3,7 @@ package net.knarcraft.ffmpegconverter; import net.knarcraft.ffmpegconverter.config.Configuration; import net.knarcraft.ffmpegconverter.converter.AnimeConverter; import net.knarcraft.ffmpegconverter.converter.AudioConverter; +import net.knarcraft.ffmpegconverter.converter.AudioExtractor; import net.knarcraft.ffmpegconverter.converter.AudioToVorbisConverter; import net.knarcraft.ffmpegconverter.converter.Converter; import net.knarcraft.ffmpegconverter.converter.DownScaleConverter; @@ -100,13 +101,14 @@ public class FFMpegConvert { 10. Anime to h265 all streams 11. Stream reorder 12. Letterbox cropper - 13. Video's Audio to vorbis converter""", 1, 13); + 13. Video's Audio to vorbis converter + 14. Audio from video extractor""", 1, 14, Integer.MIN_VALUE); return switch (choice) { case 1 -> generateWebAnimeConverter(); - case 2 -> new AudioConverter(FFPROBE_PATH, FFMPEG_PATH, getChoice("")); - case 3 -> new VideoConverter(FFPROBE_PATH, FFMPEG_PATH, getChoice("")); - case 4 -> new WebVideoConverter(FFPROBE_PATH, FFMPEG_PATH, getChoice("")); + case 2 -> new AudioConverter(FFPROBE_PATH, FFMPEG_PATH, getChoice("", null)); + case 3 -> new VideoConverter(FFPROBE_PATH, FFMPEG_PATH, getChoice("", null)); + case 4 -> new WebVideoConverter(FFPROBE_PATH, FFMPEG_PATH, getChoice("", null)); case 5 -> new MkvH264Converter(FFPROBE_PATH, FFMPEG_PATH); case 6 -> new MkvH265ReducedConverter(FFPROBE_PATH, FFMPEG_PATH); case 7 -> generateMKVToMP4Transcoder(); @@ -116,6 +118,8 @@ public class FFMpegConvert { case 11 -> generateStreamOrderConverter(); case 12 -> new LetterboxCropper(FFPROBE_PATH, FFMPEG_PATH); case 13 -> new AudioToVorbisConverter(FFPROBE_PATH, FFMPEG_PATH); + case 14 -> new AudioExtractor(FFPROBE_PATH, FFMPEG_PATH, getChoice("", + "mp3"), getChoice("", 0, 1000, 0)); default -> null; }; } @@ -182,9 +186,9 @@ public class FFMpegConvert { private static Converter generateMKVToMP4Transcoder() { OutputUtil.println("[Audio stream index 0-n] [Subtitle stream index 0-n] [Video stream index 0-n]\nYour input: "); List input = readInput(3); - int audioStreamIndex = -1; - int subtitleStreamIndex = -1; - int videoStreamIndex = -1; + int audioStreamIndex = 0; + int subtitleStreamIndex = 0; + int videoStreamIndex = 0; try { if (!input.isEmpty()) { @@ -331,16 +335,20 @@ public class FFMpegConvert { /** * Gets the user's choice * - * @param prompt

The prompt shown to the user.

+ * @param prompt

The prompt shown to the user.

+ * @param defaultValue

The default value, if no input is given

* @return

The non-empty choice given by the user.

*/ @NotNull - private static String getChoice(@NotNull String prompt) { + private static String getChoice(@NotNull String prompt, @Nullable Object defaultValue) { OutputUtil.println(prompt); String choice = ""; while (choice.isEmpty()) { OutputUtil.println("Your input: "); choice = READER.nextLine(); + if (choice.isEmpty() && defaultValue != null) { + return String.valueOf(defaultValue); + } } return choice; } @@ -353,7 +361,7 @@ public class FFMpegConvert { * @param max The maximum allowed value * @return The value given by the user */ - private static int getChoice(@NotNull String prompt, int min, int max) { + private static int getChoice(@NotNull String prompt, int min, int max, int defaultValue) { OutputUtil.println(prompt); int choice = Integer.MIN_VALUE; do { @@ -361,6 +369,9 @@ public class FFMpegConvert { try { choice = Integer.parseInt(READER.next()); } catch (NumberFormatException e) { + if (defaultValue != Integer.MIN_VALUE) { + return defaultValue; + } OutputUtil.println("Invalid choice. Please try again."); } finally { READER.nextLine(); diff --git a/src/main/java/net/knarcraft/ffmpegconverter/converter/AudioExtractor.java b/src/main/java/net/knarcraft/ffmpegconverter/converter/AudioExtractor.java new file mode 100644 index 0000000..57d2539 --- /dev/null +++ b/src/main/java/net/knarcraft/ffmpegconverter/converter/AudioExtractor.java @@ -0,0 +1,65 @@ +package net.knarcraft.ffmpegconverter.converter; + +import net.knarcraft.ffmpegconverter.container.FFMpegCommand; +import net.knarcraft.ffmpegconverter.container.StreamProbeResult; +import net.knarcraft.ffmpegconverter.converter.module.ConverterModule; +import net.knarcraft.ffmpegconverter.converter.module.DebugModule; +import net.knarcraft.ffmpegconverter.converter.module.ModuleExecutor; +import net.knarcraft.ffmpegconverter.converter.module.mapping.NthAudioStreamModule; +import net.knarcraft.ffmpegconverter.converter.module.output.SetOutputFileModule; +import net.knarcraft.ffmpegconverter.utility.FFMpegHelper; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import java.util.ArrayList; +import java.util.List; + +/** + * An extractor for getting audio streams from video files + */ +public class AudioExtractor extends AbstractConverter { + + private final int streamToExtract; + + /** + * Instantiates a new audio extractor + * + * @param ffprobePath

Path/command to ffprobe.

+ * @param ffmpegPath

Path/command to ffmpeg.

+ * @param newExtension

The extension of the new file.

+ * @param streamToExtract

The stream to be extracted from the video file

+ */ + public AudioExtractor(@NotNull String ffprobePath, @NotNull String ffmpegPath, @NotNull String newExtension, + int streamToExtract) { + super(newExtension); + this.ffprobePath = ffprobePath; + this.ffmpegPath = ffmpegPath; + this.streamToExtract = Math.max(0, streamToExtract); + } + + @Override + @Nullable + public FFMpegCommand generateConversionCommand(@NotNull String executable, @NotNull StreamProbeResult probeResult, + @NotNull String outFile) { + FFMpegCommand command = FFMpegHelper.getFFMpegGeneralFileCommand(executable, probeResult.parsedFiles()); + List modules = new ArrayList<>(); + + if (this.debug) { + modules.add(new DebugModule()); + } + + //Gets the first audio stream from the file and adds it to the output file + modules.add(new NthAudioStreamModule(probeResult.getAudioStreams(), streamToExtract)); + modules.add(new SetOutputFileModule(outFile)); + + new ModuleExecutor(command, modules).execute(); + return command; + } + + @Override + @NotNull + public List getValidFormats() { + return videoFormats; + } + +} diff --git a/src/main/resources/audio_formats.txt b/src/main/resources/audio_formats.txt index 2dab9b9..6fa7c34 100644 --- a/src/main/resources/audio_formats.txt +++ b/src/main/resources/audio_formats.txt @@ -37,4 +37,5 @@ wma wv webm 8svx -mka \ No newline at end of file +mka +ac3 \ No newline at end of file