1
0
mirror of https://github.com/aNNiMON/ffmpegbot synced 2024-09-19 22:54:20 +03:00

Dynamically updating parameters list based on a user's input

This commit is contained in:
aNNiMON 2024-07-03 22:21:17 +03:00
parent a046585327
commit bc4e3af5bc
10 changed files with 157 additions and 15 deletions

View File

@ -83,6 +83,7 @@ public class MediaProcessingBundle implements CommandBundle<For> {
if (param != null && ctx.argumentsLength() == 2) {
final int index = Integer.parseInt(ctx.argument(1));
param.select(index);
parametersResolver.refine(session.getParams());
session.setSelectedParam(null);
}
}

View File

@ -7,6 +7,10 @@ public abstract class BooleanParameter extends Parameter<Boolean> {
super(id, name, List.of(false, true), value);
}
public boolean getValueAsPrimitive() {
return (value != null && value);
}
@Override
public String describeValue(Boolean value) {
if (value != null && value) {

View File

@ -2,7 +2,9 @@ package com.annimon.ffmpegbot.parameters;
import com.annimon.ffmpegbot.commands.ffmpeg.Visitor;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
public class OutputFormat extends StringParameter {
public static final String ID = "output";
@ -12,7 +14,29 @@ public class OutputFormat extends StringParameter {
public static final String VIDEO_NOTE = "VIDEO NOTE";
public OutputFormat(List<String> values, String initialValue) {
super(ID, "\uFE0F Output", values, initialValue);
super(ID, "➡️ Output", values, initialValue);
}
public OutputFormat disableFormat(String format) {
if (possibleValues.size() <= 1) return this;
final var values = possibleValues.stream()
.filter(f -> !Objects.equals(f, format))
.map(Objects::toString)
.toList();
if (possibleValues.size() == values.size()) {
return this;
}
return new OutputFormat(values, values.get(0));
}
public OutputFormat enableFormat(String format) {
boolean contains = possibleValues.stream()
.anyMatch(f -> Objects.equals(f, format));
if (contains) return this;
final var values = new ArrayList<String>(possibleValues);
values.add(format);
return new OutputFormat(values, values.get(0));
}
@Override

View File

@ -12,12 +12,14 @@ public abstract class Parameter<T> {
protected final String displayName;
protected final List<? extends T> possibleValues;
protected T value;
private boolean enabled;
protected Parameter(String id, String displayName, List<? extends T> values, T value) {
this.id = id;
this.displayName = displayName;
this.possibleValues = values;
this.value = value;
this.enabled = true;
checkArgument(!values.isEmpty(), "possible values cannot be empty");
checkArgument(values.contains(value), "possible values must contain a value");
}
@ -34,6 +36,17 @@ public abstract class Parameter<T> {
return possibleValues.size();
}
public boolean isEnabled() {
return enabled;
}
public void enable() {
enabled = true;
}
public void disable() {
enabled = false;
}
public abstract <I> void accept(Visitor<I> visitor, I input);

View File

@ -2,44 +2,68 @@ package com.annimon.ffmpegbot.parameters;
import org.jetbrains.annotations.NotNull;
import java.util.*;
import java.util.stream.Stream;
public class Parameters extends AbstractCollection<Parameter<?>> {
private final Map<String, Parameter<?>> enabledParameters;
private final Map<String, Parameter<?>> disabledParameters;
private final Map<String, Parameter<?>> parameters;
public Parameters() {
enabledParameters = new LinkedHashMap<>();
disabledParameters = new LinkedHashMap<>();
parameters = new LinkedHashMap<>();
}
@Override
public boolean add(Parameter<?> parameter) {
return !Objects.equals(parameter, enabledParameters.put(parameter.id, parameter));
parameter.enable();
return !Objects.equals(parameter, parameters.put(parameter.id, parameter));
}
public Parameter<?> findById(String id) {
return enabledParameters.get(id);
final var parameter = parameters.get(id);
if (parameter != null && parameter.isEnabled()) {
return parameter;
}
return null;
}
public <P extends Parameter<?>> Optional<P> findById(String id, Class<P> clazz) {
return Optional.ofNullable(findById(id))
.filter(clazz::isInstance)
.map(clazz::cast);
}
public void disable(String id) {
Optional.ofNullable(findById(id))
.ifPresent(p -> disabledParameters.put(p.id, p));
Optional.ofNullable(parameters.get(id))
.ifPresent(Parameter::disable);
}
public void disableAll(Collection<String> ids) {
ids.forEach(this::disable);
}
public void enable(String id) {
Optional.ofNullable(disabledParameters.get(id))
.ifPresent(this::add);
Optional.ofNullable(parameters.get(id))
.ifPresent(Parameter::enable);
}
public void enableAll(Collection<String> ids) {
ids.forEach(this::enable);
}
@NotNull
@Override
public Iterator<Parameter<?>> iterator() {
return enabledParameters.values().iterator();
return enabledParameters().iterator();
}
@Override
public int size() {
return enabledParameters.size();
return (int) enabledParameters().count();
}
private Stream<Parameter<?>> enabledParameters() {
return parameters.values()
.stream()
.filter(Parameter::isEnabled);
}
}

View File

@ -5,6 +5,8 @@ import com.annimon.ffmpegbot.session.FileInfo;
import com.annimon.ffmpegbot.session.FileType;
import org.jetbrains.annotations.NotNull;
import java.util.List;
import java.util.Optional;
import java.util.Set;
public class AudioResolver implements ParametersResolver {
@ -28,6 +30,28 @@ public class AudioResolver implements ParametersResolver {
}
}
@Override
public void refine(@NotNull Parameters parameters) {
parameters.findById(DisableAudio.ID, DisableAudio.class)
.ifPresent(p -> {
final Set<String> parameterIds = Set.of(
AudioBitrate.ID,
AudioCrystalizer.ID,
AudioEffect.ID,
AudioPitch.ID,
AudioVolume.ID
);
Optional<OutputFormat> outputFormat = parameters.findById(OutputFormat.ID, OutputFormat.class);
if (p.getValueAsPrimitive()) {
parameters.disableAll(parameterIds);
outputFormat.ifPresent(par -> parameters.add(par.disableFormat(OutputFormat.AUDIO)));
} else {
parameters.enableAll(parameterIds);
outputFormat.ifPresent(par -> parameters.add(par.enableFormat(OutputFormat.AUDIO)));
}
});
}
private void disableAudioParam(@NotNull Parameters parameters, @NotNull FileType fileType) {
final boolean canAudioBeDisabled = switch (fileType) {
case ANIMATION, AUDIO, VOICE -> false;

View File

@ -24,4 +24,11 @@ public class GlobalParametersResolver implements ParametersResolver {
resolver.resolve(parameters, fileInfo);
}
}
@Override
public void refine(@NotNull Parameters parameters) {
for (ParametersResolver resolver : resolvers) {
resolver.refine(parameters);
}
}
}

View File

@ -1,7 +1,6 @@
package com.annimon.ffmpegbot.parameters.resolvers;
import com.annimon.ffmpegbot.parameters.AudioStreamByLanguage;
import com.annimon.ffmpegbot.parameters.Parameters;
import com.annimon.ffmpegbot.parameters.*;
import com.annimon.ffmpegbot.session.FileInfo;
import com.annimon.ffmpegbot.session.FileType;
import org.jetbrains.annotations.NotNull;
@ -19,4 +18,16 @@ public class MultiAudioStreamsResolver implements ParametersResolver {
parameters.add(new AudioStreamByLanguage());
}
}
@Override
public void refine(@NotNull Parameters parameters) {
parameters.findById(DisableAudio.ID, DisableAudio.class)
.ifPresent(p -> {
if (p.getValueAsPrimitive()) {
parameters.disable(AudioStreamByLanguage.ID);
} else {
parameters.enable(AudioStreamByLanguage.ID);
}
});
}
}

View File

@ -7,4 +7,15 @@ import org.jetbrains.annotations.NotNull;
public interface ParametersResolver {
void resolve(@NotNull Parameters parameters, @NotNull FileInfo fileInfo);
/**
* Refines all parameters based on user input.
* <p>
* Example: if Disable audio is ON -> removes all audio parameters.
*
* @param parameters all parameters
*/
default void refine(@NotNull Parameters parameters) {
}
}

View File

@ -4,6 +4,8 @@ import com.annimon.ffmpegbot.parameters.*;
import com.annimon.ffmpegbot.session.FileInfo;
import org.jetbrains.annotations.NotNull;
import java.util.List;
import java.util.Objects;
import java.util.Set;
public class VideoResolver implements ParametersResolver {
@ -25,4 +27,25 @@ public class VideoResolver implements ParametersResolver {
));
}
}
@Override
public void refine(@NotNull Parameters parameters) {
parameters.findById(OutputFormat.ID, OutputFormat.class)
.map(Parameter::getValue)
.ifPresent(format -> {
final Set<String> parameterIds = Set.of(
Contrast.ID,
Gamma.ID,
Saturation.ID,
VideoBitrate.ID,
VideoScale.ID,
VideoFrameRate.ID
);
if (Objects.equals(format, OutputFormat.AUDIO)) {
parameters.disableAll(parameterIds);
} else {
parameters.enableAll(parameterIds);
}
});
}
}