diff --git a/src/main/java/com/annimon/ffmpegbot/commands/ffmpeg/MediaProcessingBundle.java b/src/main/java/com/annimon/ffmpegbot/commands/ffmpeg/MediaProcessingBundle.java index 9193ff6..a39b81a 100644 --- a/src/main/java/com/annimon/ffmpegbot/commands/ffmpeg/MediaProcessingBundle.java +++ b/src/main/java/com/annimon/ffmpegbot/commands/ffmpeg/MediaProcessingBundle.java @@ -4,6 +4,8 @@ import com.annimon.ffmpegbot.file.FileDownloadException; import com.annimon.ffmpegbot.file.FileDownloader; import com.annimon.ffmpegbot.parameters.Parameter; import com.annimon.ffmpegbot.file.FilePath; +import com.annimon.ffmpegbot.parameters.resolvers.GlobalParametersResolver; +import com.annimon.ffmpegbot.parameters.resolvers.ParametersResolver; import com.annimon.ffmpegbot.session.MediaSession; import com.annimon.ffmpegbot.session.Resolver; import com.annimon.ffmpegbot.session.Sessions; @@ -17,6 +19,7 @@ import com.annimon.tgbotsmodule.services.CommonAbsSender; import org.jetbrains.annotations.NotNull; import org.telegram.telegrambots.meta.api.objects.Message; +import java.util.ArrayList; import java.util.concurrent.CompletableFuture; import java.util.function.BiConsumer; import java.util.function.Consumer; @@ -30,10 +33,12 @@ public class MediaProcessingBundle implements CommandBundle { private final Sessions sessions; private final FileDownloader fileDownloader; + private final ParametersResolver parametersResolver; public MediaProcessingBundle(Sessions sessions, FileDownloader fileDownloader) { this.sessions = sessions; this.fileDownloader = fileDownloader; + this.parametersResolver = new GlobalParametersResolver(); } @Override @@ -51,7 +56,10 @@ public class MediaProcessingBundle implements CommandBundle { final var session = new MediaSession(); session.setChatId(message.getChatId()); session.fromFileInfo(fileInfo); - session.setParams(Resolver.resolveParameters(fileInfo.fileType())); + + final var params = new ArrayList>(); + parametersResolver.resolve(params, fileInfo); + session.setParams(params); final var result = Methods.sendMessage() .setChatId(message.getChatId()) diff --git a/src/main/java/com/annimon/ffmpegbot/parameters/OutputFormat.java b/src/main/java/com/annimon/ffmpegbot/parameters/OutputFormat.java index 16d3ca0..c3705d8 100644 --- a/src/main/java/com/annimon/ffmpegbot/parameters/OutputFormat.java +++ b/src/main/java/com/annimon/ffmpegbot/parameters/OutputFormat.java @@ -9,14 +9,6 @@ public class OutputFormat extends StringParameter { public static final String AUDIO = "AUDIO"; public static final String VIDEO_NOTE = "VIDEO NOTE"; - public static OutputFormat forVideo() { - return new OutputFormat(List.of(VIDEO, AUDIO), VIDEO); - } - - public static OutputFormat forVideoNote() { - return new OutputFormat(List.of(VIDEO_NOTE, VIDEO, AUDIO), VIDEO_NOTE); - } - public OutputFormat(List values, String initialValue) { super("output", "Output", values, initialValue); } diff --git a/src/main/java/com/annimon/ffmpegbot/parameters/Parameters.java b/src/main/java/com/annimon/ffmpegbot/parameters/Parameters.java deleted file mode 100644 index 23e7ffe..0000000 --- a/src/main/java/com/annimon/ffmpegbot/parameters/Parameters.java +++ /dev/null @@ -1,56 +0,0 @@ -package com.annimon.ffmpegbot.parameters; - -import java.util.List; - -public class Parameters { - - public static List> forAudio() { - return List.of( - new AudioBitrate(), - new AudioEffect(), - new AudioPitch(), - new AudioVolume(), - new SpeedFactor() - ); - } - - public static List> forAnimation() { - return List.of( - new VideoBitrate(), - new VideoScale(), - new VideoFrameRate(), - new SpeedFactor() - ); - } - - public static List> forVideo() { - return List.of( - new DisableAudio(), - new AudioBitrate(), - new AudioEffect(), - new AudioPitch(), - new AudioVolume(), - new AudioStreamByLanguage(), - new VideoBitrate(), - new VideoScale(), - new VideoFrameRate(), - new SpeedFactor(), - OutputFormat.forVideo() - ); - } - - public static List> forVideoNote() { - return List.of( - new DisableAudio(), - new AudioBitrate(), - new AudioEffect(), - new AudioPitch(), - new AudioVolume(), - new VideoBitrate(), - new VideoScale(), - new VideoFrameRate(), - new SpeedFactor(), - OutputFormat.forVideoNote() - ); - } -} diff --git a/src/main/java/com/annimon/ffmpegbot/parameters/resolvers/AudioResolver.java b/src/main/java/com/annimon/ffmpegbot/parameters/resolvers/AudioResolver.java new file mode 100644 index 0000000..81eda70 --- /dev/null +++ b/src/main/java/com/annimon/ffmpegbot/parameters/resolvers/AudioResolver.java @@ -0,0 +1,39 @@ +package com.annimon.ffmpegbot.parameters.resolvers; + +import com.annimon.ffmpegbot.parameters.*; +import com.annimon.ffmpegbot.session.FileInfo; +import com.annimon.ffmpegbot.session.FileType; +import org.jetbrains.annotations.NotNull; +import java.util.List; + +public class AudioResolver implements ParametersResolver { + + @Override + public void resolve(@NotNull List> parameters, @NotNull FileInfo fileInfo) { + final boolean hasAudio = switch (fileInfo.fileType()) { + case ANIMATION -> false; + case AUDIO, VOICE -> true; + case VIDEO, VIDEO_NOTE -> true; // TODO: add actual ffprobe check for audio + }; + + if (hasAudio) { + disableAudioParam(parameters, fileInfo.fileType()); + parameters.addAll(List.of( + new AudioBitrate(), + new AudioEffect(), + new AudioPitch(), + new AudioVolume() + )); + } + } + + private void disableAudioParam(@NotNull List> parameters, @NotNull FileType fileType) { + final boolean canAudioBeDisabled = switch (fileType) { + case ANIMATION, AUDIO, VOICE -> false; + case VIDEO, VIDEO_NOTE -> true; + }; + if (canAudioBeDisabled) { + parameters.add(new DisableAudio()); + } + } +} diff --git a/src/main/java/com/annimon/ffmpegbot/parameters/resolvers/GlobalParametersResolver.java b/src/main/java/com/annimon/ffmpegbot/parameters/resolvers/GlobalParametersResolver.java new file mode 100644 index 0000000..d13c06a --- /dev/null +++ b/src/main/java/com/annimon/ffmpegbot/parameters/resolvers/GlobalParametersResolver.java @@ -0,0 +1,27 @@ +package com.annimon.ffmpegbot.parameters.resolvers; + +import com.annimon.ffmpegbot.parameters.Parameter; +import com.annimon.ffmpegbot.session.FileInfo; +import org.jetbrains.annotations.NotNull; +import java.util.ArrayList; +import java.util.List; + +public class GlobalParametersResolver implements ParametersResolver { + private final List resolvers; + + public GlobalParametersResolver() { + resolvers = new ArrayList<>(); + resolvers.add(new AudioResolver()); + resolvers.add(new MultiAudioStreamsResolver()); + resolvers.add(new VideoResolver()); + resolvers.add(new SpeedFactorResolver()); + resolvers.add(new OutputFormatResolver()); + } + + @Override + public void resolve(@NotNull List> parameters, @NotNull FileInfo fileInfo) { + for (ParametersResolver resolver : resolvers) { + resolver.resolve(parameters, fileInfo); + } + } +} diff --git a/src/main/java/com/annimon/ffmpegbot/parameters/resolvers/MultiAudioStreamsResolver.java b/src/main/java/com/annimon/ffmpegbot/parameters/resolvers/MultiAudioStreamsResolver.java new file mode 100644 index 0000000..3d88224 --- /dev/null +++ b/src/main/java/com/annimon/ffmpegbot/parameters/resolvers/MultiAudioStreamsResolver.java @@ -0,0 +1,16 @@ +package com.annimon.ffmpegbot.parameters.resolvers; + +import com.annimon.ffmpegbot.parameters.Parameter; +import com.annimon.ffmpegbot.session.FileInfo; +import org.jetbrains.annotations.NotNull; +import java.util.List; + +public class MultiAudioStreamsResolver implements ParametersResolver { + + @Override + public void resolve(@NotNull List> parameters, @NotNull FileInfo fileInfo) { + // TODO: Disabled until files support will be implemented + // Check for mkv file type + // parameters.add(new AudioStreamByLanguage()); + } +} diff --git a/src/main/java/com/annimon/ffmpegbot/parameters/resolvers/OutputFormatResolver.java b/src/main/java/com/annimon/ffmpegbot/parameters/resolvers/OutputFormatResolver.java new file mode 100644 index 0000000..c46fe2d --- /dev/null +++ b/src/main/java/com/annimon/ffmpegbot/parameters/resolvers/OutputFormatResolver.java @@ -0,0 +1,23 @@ +package com.annimon.ffmpegbot.parameters.resolvers; + +import com.annimon.ffmpegbot.parameters.OutputFormat; +import com.annimon.ffmpegbot.parameters.Parameter; +import com.annimon.ffmpegbot.session.FileInfo; +import org.jetbrains.annotations.NotNull; +import java.util.List; +import static com.annimon.ffmpegbot.parameters.OutputFormat.*; + +public class OutputFormatResolver implements ParametersResolver { + + @Override + public void resolve(@NotNull List> parameters, @NotNull FileInfo fileInfo) { + final var outputFormat = switch (fileInfo.fileType()) { + case VIDEO -> new OutputFormat(List.of(VIDEO, AUDIO), VIDEO); + case VIDEO_NOTE -> new OutputFormat(List.of(VIDEO_NOTE, VIDEO, AUDIO), VIDEO_NOTE); + default -> null; + }; + if (outputFormat != null) { + parameters.add(outputFormat); + } + } +} diff --git a/src/main/java/com/annimon/ffmpegbot/parameters/resolvers/ParametersResolver.java b/src/main/java/com/annimon/ffmpegbot/parameters/resolvers/ParametersResolver.java new file mode 100644 index 0000000..7cb9f9e --- /dev/null +++ b/src/main/java/com/annimon/ffmpegbot/parameters/resolvers/ParametersResolver.java @@ -0,0 +1,11 @@ +package com.annimon.ffmpegbot.parameters.resolvers; + +import com.annimon.ffmpegbot.parameters.Parameter; +import com.annimon.ffmpegbot.session.FileInfo; +import org.jetbrains.annotations.NotNull; +import java.util.List; + +public interface ParametersResolver { + + void resolve(@NotNull List> parameters, @NotNull FileInfo fileInfo); +} diff --git a/src/main/java/com/annimon/ffmpegbot/parameters/resolvers/SpeedFactorResolver.java b/src/main/java/com/annimon/ffmpegbot/parameters/resolvers/SpeedFactorResolver.java new file mode 100644 index 0000000..5ba0160 --- /dev/null +++ b/src/main/java/com/annimon/ffmpegbot/parameters/resolvers/SpeedFactorResolver.java @@ -0,0 +1,16 @@ +package com.annimon.ffmpegbot.parameters.resolvers; + +import com.annimon.ffmpegbot.parameters.Parameter; +import com.annimon.ffmpegbot.parameters.SpeedFactor; +import com.annimon.ffmpegbot.session.FileInfo; +import org.jetbrains.annotations.NotNull; +import java.util.List; + +public class SpeedFactorResolver implements ParametersResolver { + + @Override + public void resolve(@NotNull List> parameters, @NotNull FileInfo fileInfo) { + // For anything except static images + parameters.add(new SpeedFactor()); + } +} diff --git a/src/main/java/com/annimon/ffmpegbot/parameters/resolvers/VideoResolver.java b/src/main/java/com/annimon/ffmpegbot/parameters/resolvers/VideoResolver.java new file mode 100644 index 0000000..ced77b6 --- /dev/null +++ b/src/main/java/com/annimon/ffmpegbot/parameters/resolvers/VideoResolver.java @@ -0,0 +1,25 @@ +package com.annimon.ffmpegbot.parameters.resolvers; + +import com.annimon.ffmpegbot.parameters.*; +import com.annimon.ffmpegbot.session.FileInfo; +import org.jetbrains.annotations.NotNull; +import java.util.List; + +public class VideoResolver implements ParametersResolver { + + @Override + public void resolve(@NotNull List> parameters, @NotNull FileInfo fileInfo) { + final boolean hasVideo = switch (fileInfo.fileType()) { + case ANIMATION, VIDEO, VIDEO_NOTE -> true; + default -> false; + }; + + if (hasVideo) { + parameters.addAll(List.of( + new VideoBitrate(), + new VideoScale(), + new VideoFrameRate() + )); + } + } +} diff --git a/src/main/java/com/annimon/ffmpegbot/session/Resolver.java b/src/main/java/com/annimon/ffmpegbot/session/Resolver.java index 623c74d..58235b4 100644 --- a/src/main/java/com/annimon/ffmpegbot/session/Resolver.java +++ b/src/main/java/com/annimon/ffmpegbot/session/Resolver.java @@ -1,17 +1,14 @@ package com.annimon.ffmpegbot.session; -import com.annimon.ffmpegbot.parameters.Parameter; -import com.annimon.ffmpegbot.parameters.Parameters; import com.annimon.tgbotsmodule.api.methods.Methods; import com.annimon.tgbotsmodule.api.methods.interfaces.MediaMessageMethod; import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; import org.telegram.telegrambots.meta.api.methods.ActionType; import org.telegram.telegrambots.meta.api.objects.Message; -import java.util.List; - public class Resolver { - public static FileInfo resolveFileInfo(@NotNull Message message) { + public static @Nullable FileInfo resolveFileInfo(@NotNull Message message) { if (message.hasAnimation()) { final var att = message.getAnimation(); return new FileInfo(FileType.ANIMATION, att.getFileId(), att.getFileName(), @@ -36,15 +33,6 @@ public class Resolver { } } - public static List> resolveParameters(@NotNull FileType fileType) { - return switch (fileType) { - case ANIMATION -> Parameters.forAnimation(); - case VIDEO -> Parameters.forVideo(); - case VIDEO_NOTE -> Parameters.forVideoNote(); - case AUDIO, VOICE -> Parameters.forAudio(); - }; - } - public static MediaMessageMethod, ?> resolveMethod(@NotNull FileType fileType) { return switch (fileType) { case ANIMATION -> Methods.sendAnimation(); @@ -55,7 +43,7 @@ public class Resolver { }; } - public static ActionType resolveAction(FileType fileType) { + public static ActionType resolveAction(@NotNull FileType fileType) { return switch (fileType) { case VIDEO -> ActionType.UPLOADVIDEO; case VIDEO_NOTE -> ActionType.UPLOADVIDEONOTE;