package net.knarcraft.ffmpegconverter.converter; import net.knarcraft.ffmpegconverter.container.FFMpegCommand; import net.knarcraft.ffmpegconverter.container.StreamProbeResult; import net.knarcraft.ffmpegconverter.handler.AvailableHardwareEncoderHandler; import net.knarcraft.ffmpegconverter.utility.FFMpegHelper; import net.knarcraft.ffmpegconverter.utility.FileUtil; import net.knarcraft.ffmpegconverter.utility.OutputUtil; import org.apache.commons.configuration2.ex.ConfigurationException; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import java.io.File; import java.io.IOException; import java.util.ArrayList; import java.util.List; /** * Implements all methods which can be useful for any implementation of a converter. */ public abstract class AbstractConverter implements Converter { final boolean debug = false; private final String newExtension; protected String ffprobePath; protected String ffmpegPath; protected String[] audioFormats; protected String[] videoFormats; protected AvailableHardwareEncoderHandler encoderHandler = null; /** * Initializes variables used by the abstract converter */ AbstractConverter(@Nullable String newExtension) { this.newExtension = newExtension; OutputUtil.setDebug(this.debug); try { audioFormats = FileUtil.readFileLines("audio_formats.txt"); videoFormats = FileUtil.readFileLines("video_formats.txt"); } catch (IOException e) { System.out.println("Unable to read audio and/or video formats from internal files."); System.exit(1); } } @Override public void convert(@NotNull File file) throws IOException { StreamProbeResult probeResult = FFMpegHelper.probeFile(ffprobePath, file); if (probeResult.parsedStreams().isEmpty()) { throw new IllegalArgumentException("The file has no valid streams. Please make sure the file exists and" + " is not corrupt."); } String outExtension = newExtension != null ? newExtension : FileUtil.getExtension(file.getName()); String newPath = FileUtil.getNonCollidingPath(file.getParentFile(), file, outExtension); OutputUtil.println(); OutputUtil.println("Preparing to start process..."); OutputUtil.println("Converting " + file); FFMpegCommand ffMpegCommand = generateConversionCommand(ffmpegPath, probeResult, newPath); // If the command is null, that means the file does not need conversion if (ffMpegCommand == null) { return; } String[] command = ffMpegCommand.getResult(); // If no commands were given, no conversion is necessary if (command.length == 0) { return; } ProcessBuilder processBuilder = new ProcessBuilder(command); int exitCode = FFMpegHelper.runProcess(processBuilder, file.getParentFile(), "\n", true).exitCode(); if (exitCode != 0) { try { handleError(ffMpegCommand, file, newPath); } catch (ConfigurationException e) { throw new RuntimeException(e); } } } /** * Handles an ffmpeg conversion error * * @param ffMpegCommand
The failed ffmpeg command
* @param fileThe file that was to be converted
* @param newPathThe path of the output file
* @throws IOExceptionIf unable to produce output
* @throws ConfigurationExceptionIf unable
*/ private void handleError(@NotNull FFMpegCommand ffMpegCommand, @NotNull File file, @NotNull String newPath) throws IOException, ConfigurationException { File outputFile = new File(newPath); if (outputFile.exists() && !outputFile.delete()) { OutputUtil.println("Failed to remove failed output file. Please remove it manually"); } String outputCodec = ffMpegCommand.getOutputVideoCodec(); if (outputCodec != null && outputCodec.contains("_")) { String[] parts = outputCodec.split("_"); String hardwareAcceleration = parts[parts.length - 1]; ListAvailable hardware encoding methods
*/ protected List