package net.knarcraft.ffmpegconverter.converter; import net.knarcraft.ffmpegconverter.container.FFMpegCommand; import net.knarcraft.ffmpegconverter.container.StreamProbeResult; import net.knarcraft.ffmpegconverter.streams.AudioStream; import net.knarcraft.ffmpegconverter.streams.StreamObject; import net.knarcraft.ffmpegconverter.streams.SubtitleStream; import net.knarcraft.ffmpegconverter.streams.VideoStream; import net.knarcraft.ffmpegconverter.utility.FFMpegHelper; import org.jetbrains.annotations.NotNull; import java.util.ArrayList; import java.util.List; /** * A converter mainly designed for converting anime to web-playable mp4 */ public class AnimeConverter extends AbstractConverter { private final String[] audioLanguages; private final String[] subtitleLanguages; private final boolean toStereo; private final boolean preventSignsAndSongs; private final int forcedAudioIndex; private final int forcedSubtitleIndex; private final String subtitleNameFilter; /** * Instantiates a new anime converter * * @param ffprobePath

Path/command to ffprobe.

* @param ffmpegPath

Path/command to ffmpeg.

* @param audioLanguages

List of wanted audio languages in descending order.

* @param subtitleLanguages

List of wanted subtitle languages in descending order.

* @param toStereo

Convert video with several audio channels to stereo.

* @param preventSignsAndSongs

Prevent subtitles only converting signs and songs (not speech).

* @param forcedAudioIndex

A specific audio stream to force. 0-indexed from the first audio stream found

* @param forcedSubtitleIndex

A specific subtitle stream to force. 0-indexed for the first subtitle stream found

*/ public AnimeConverter(String ffprobePath, String ffmpegPath, String[] audioLanguages, String[] subtitleLanguages, boolean toStereo, boolean preventSignsAndSongs, int forcedAudioIndex, int forcedSubtitleIndex, String subtitleNameFilter) { super("mp4"); this.ffprobePath = ffprobePath; this.ffmpegPath = ffmpegPath; this.audioLanguages = audioLanguages; this.subtitleLanguages = subtitleLanguages; this.toStereo = toStereo; this.preventSignsAndSongs = preventSignsAndSongs; this.forcedAudioIndex = forcedAudioIndex; this.forcedSubtitleIndex = forcedSubtitleIndex; this.subtitleNameFilter = subtitleNameFilter; } @Override public String[] generateConversionCommand(@NotNull String executable, @NotNull StreamProbeResult probeResult, @NotNull String outFile) { FFMpegCommand command = FFMpegHelper.getFFMpegWebVideoCommand(executable, probeResult.parsedFiles()); List streams = probeResult.parsedStreams(); if (this.debug) { FFMpegHelper.addDebugArguments(command, 50, 120); } //Get the first audio stream in accordance with chosen languages List audioStreams = filterAudioStreams(filterStreamsByType(streams, AudioStream.class), this.audioLanguages); AudioStream audioStream = getNthAudioSteam(new ArrayList<>(audioStreams), Math.max(this.forcedAudioIndex, 0)); //Get the first subtitle stream in accordance with chosen languages and signs and songs prevention List allSubtitleStreams = filterStreamsByType(streams, SubtitleStream.class); List subtitleStreams = filterSubtitleStreams(allSubtitleStreams, this.subtitleLanguages, this.preventSignsAndSongs, this.subtitleNameFilter); SubtitleStream subtitleStream = getNthSubtitleStream(new ArrayList<>(subtitleStreams), Math.max(this.forcedSubtitleIndex, 0)); //Get the first video stream VideoStream videoStream = getNthVideoStream(streams, 0); if (videoStream == null) { throw new IllegalArgumentException("The selected video stream does not exist"); } //Add streams to output file FFMpegHelper.addAudioStream(command, audioStream, this.toStereo); FFMpegHelper.addSubtitleAndVideoStream(command, subtitleStream, videoStream); command.setOutputFile(outFile); return command.getResult(); } @Override public String[] getValidFormats() { return this.videoFormats; } }