All checks were successful
KnarCraft/FFmpegConvert/pipeline/head This commit looks good
125 lines
6.0 KiB
Java
125 lines
6.0 KiB
Java
package net.knarcraft.ffmpegconverter.converter;
|
|
|
|
import net.knarcraft.ffmpegconverter.FFMpegConvert;
|
|
import net.knarcraft.ffmpegconverter.config.Configuration;
|
|
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.hardwarecoding.HardwareDecodeModule;
|
|
import net.knarcraft.ffmpegconverter.converter.module.mapping.AddStereoAudioStreamModule;
|
|
import net.knarcraft.ffmpegconverter.converter.module.mapping.BurnSubtitleModule;
|
|
import net.knarcraft.ffmpegconverter.converter.module.mapping.SelectSingleStreamModule;
|
|
import net.knarcraft.ffmpegconverter.converter.module.output.SetOutputFileModule;
|
|
import net.knarcraft.ffmpegconverter.converter.sorter.AudioLanguageSorter;
|
|
import net.knarcraft.ffmpegconverter.converter.sorter.MinimalSubtitleSorter;
|
|
import net.knarcraft.ffmpegconverter.converter.sorter.StreamSorter;
|
|
import net.knarcraft.ffmpegconverter.converter.sorter.SubtitleLanguageSorter;
|
|
import net.knarcraft.ffmpegconverter.converter.sorter.SubtitleTitleSorter;
|
|
import net.knarcraft.ffmpegconverter.property.MinimalSubtitlePreference;
|
|
import net.knarcraft.ffmpegconverter.streams.AudioStream;
|
|
import net.knarcraft.ffmpegconverter.streams.SubtitleStream;
|
|
import net.knarcraft.ffmpegconverter.streams.VideoStream;
|
|
import net.knarcraft.ffmpegconverter.utility.FFMpegHelper;
|
|
import org.jetbrains.annotations.NotNull;
|
|
import org.jetbrains.annotations.Nullable;
|
|
|
|
import java.util.ArrayList;
|
|
import java.util.List;
|
|
|
|
import static net.knarcraft.ffmpegconverter.utility.FFMpegHelper.getNthSteam;
|
|
|
|
/**
|
|
* A converter mainly designed for converting anime to web-playable mp4
|
|
*/
|
|
public class WebAnimeConverter extends AbstractConverter {
|
|
|
|
private final List<String> audioLanguages;
|
|
private final List<String> subtitleLanguages;
|
|
private final boolean toStereo;
|
|
private final MinimalSubtitlePreference subtitlePreference;
|
|
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 toStereo <p>Convert video with several audio channels to stereo.</p>
|
|
* @param subtitlePreference <p>How minimal subtitles should be prioritized</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 WebAnimeConverter(@NotNull String ffprobePath, @NotNull String ffmpegPath, boolean toStereo,
|
|
@NotNull MinimalSubtitlePreference subtitlePreference, int forcedAudioIndex,
|
|
int forcedSubtitleIndex, @NotNull String subtitleNameFilter) {
|
|
super("mp4");
|
|
Configuration configuration = FFMpegConvert.getConfiguration();
|
|
this.ffprobePath = ffprobePath;
|
|
this.ffmpegPath = ffmpegPath;
|
|
this.audioLanguages = configuration.getAnimeAudioLanguages();
|
|
this.subtitleLanguages = configuration.getAnimeSubtitleLanguages();
|
|
this.toStereo = toStereo;
|
|
this.subtitlePreference = subtitlePreference;
|
|
this.forcedAudioIndex = forcedAudioIndex;
|
|
this.forcedSubtitleIndex = forcedSubtitleIndex;
|
|
this.subtitleNameFilter = subtitleNameFilter;
|
|
}
|
|
|
|
@Override
|
|
@Nullable
|
|
public FFMpegCommand generateConversionCommand(@NotNull String executable, @NotNull StreamProbeResult probeResult,
|
|
@NotNull String outFile) {
|
|
FFMpegCommand command = FFMpegHelper.getFFMpegWebVideoCommand(executable, probeResult.parsedFiles());
|
|
List<ConverterModule> modules = new ArrayList<>();
|
|
if (this.debug) {
|
|
modules.add(new DebugModule(0, 0));
|
|
}
|
|
|
|
//Get the first audio stream in accordance with chosen languages
|
|
AudioStream audioStream = getNthSteam(new AudioLanguageSorter(this.audioLanguages).sort(
|
|
probeResult.getAudioStreams()), this.forcedAudioIndex);
|
|
if (audioStream == null) {
|
|
throw new IllegalArgumentException("The given input resulted in no audio stream being selected");
|
|
}
|
|
if (this.toStereo) {
|
|
modules.add(new AddStereoAudioStreamModule(audioStream, true));
|
|
} else {
|
|
modules.add(new SelectSingleStreamModule(audioStream));
|
|
}
|
|
|
|
//Get the first video stream
|
|
VideoStream videoStream = getNthSteam(probeResult.getVideoStreams(), 0);
|
|
|
|
//Get the first subtitle stream in accordance with chosen languages and signs and songs prevention
|
|
StreamSorter<SubtitleStream> subtitleSorter = new SubtitleTitleSorter(List.of(this.subtitleNameFilter))
|
|
.append(new MinimalSubtitleSorter(this.subtitlePreference))
|
|
.append(new SubtitleLanguageSorter(this.subtitleLanguages));
|
|
SubtitleStream subtitleStream = getNthSteam(subtitleSorter.chainSort(probeResult.getSubtitleStreams()),
|
|
this.forcedSubtitleIndex);
|
|
|
|
modules.add(new HardwareDecodeModule());
|
|
if (subtitleStream != null && videoStream != null) {
|
|
modules.add(new BurnSubtitleModule(subtitleStream, videoStream, true));
|
|
} else if (videoStream != null) {
|
|
modules.add(new SelectSingleStreamModule(videoStream));
|
|
} else {
|
|
throw new IllegalArgumentException("The selected video stream does not exist!");
|
|
}
|
|
modules.add(new SetOutputFileModule(outFile));
|
|
|
|
new ModuleExecutor(command, modules).execute();
|
|
return command;
|
|
}
|
|
|
|
@Override
|
|
@NotNull
|
|
public List<String> getValidFormats() {
|
|
return this.videoFormats;
|
|
}
|
|
|
|
}
|