EpicKnarvik97 376d5655f2 Improves FFMpeg command generation
Adds an object for storing FFmpeg variables. This allows any argument type to be added at any time, removing the limitation of having to add to the command in a specific order.
Makes stream objects store the index of the input file they belong to.
Saves the result of probes to a record that's easy to pass around.
Always passes all probed files to the input files of ffmpeg.
Makes it easier to enable h26x encoding/decoding when necessary.
Removes the hard-coded behavior for external subtitles, and allows any stream to be an external stream.
2024-04-08 20:00:09 +02:00

96 lines
4.5 KiB
Java

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 <p>Path/command to ffprobe.</p>
* @param ffmpegPath <p>Path/command to ffmpeg.</p>
* @param audioLanguages <p>List of wanted audio languages in descending order.</p>
* @param subtitleLanguages <p>List of wanted subtitle languages in descending order.</p>
* @param toStereo <p>Convert video with several audio channels to stereo.</p>
* @param preventSignsAndSongs <p>Prevent subtitles only converting signs and songs (not speech).</p>
* @param forcedAudioIndex <p>A specific audio stream to force. 0-indexed from the first audio stream found</p>
* @param forcedSubtitleIndex <p>A specific subtitle stream to force. 0-indexed for the first subtitle stream found</p>
*/
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<StreamObject> streams = probeResult.parsedStreams();
if (this.debug) {
FFMpegHelper.addDebugArguments(command, 50, 120);
}
//Get the first audio stream in accordance with chosen languages
List<AudioStream> 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<SubtitleStream> allSubtitleStreams = filterStreamsByType(streams, SubtitleStream.class);
List<SubtitleStream> 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;
}
}