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) { if (param != null && ctx.argumentsLength() == 2) {
final int index = Integer.parseInt(ctx.argument(1)); final int index = Integer.parseInt(ctx.argument(1));
param.select(index); param.select(index);
parametersResolver.refine(session.getParams());
session.setSelectedParam(null); session.setSelectedParam(null);
} }
} }

View File

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

View File

@ -2,7 +2,9 @@ package com.annimon.ffmpegbot.parameters;
import com.annimon.ffmpegbot.commands.ffmpeg.Visitor; import com.annimon.ffmpegbot.commands.ffmpeg.Visitor;
import java.util.ArrayList;
import java.util.List; import java.util.List;
import java.util.Objects;
public class OutputFormat extends StringParameter { public class OutputFormat extends StringParameter {
public static final String ID = "output"; public static final String ID = "output";
@ -12,7 +14,29 @@ public class OutputFormat extends StringParameter {
public static final String VIDEO_NOTE = "VIDEO NOTE"; public static final String VIDEO_NOTE = "VIDEO NOTE";
public OutputFormat(List<String> values, String initialValue) { 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 @Override

View File

@ -12,12 +12,14 @@ public abstract class Parameter<T> {
protected final String displayName; protected final String displayName;
protected final List<? extends T> possibleValues; protected final List<? extends T> possibleValues;
protected T value; protected T value;
private boolean enabled;
protected Parameter(String id, String displayName, List<? extends T> values, T value) { protected Parameter(String id, String displayName, List<? extends T> values, T value) {
this.id = id; this.id = id;
this.displayName = displayName; this.displayName = displayName;
this.possibleValues = values; this.possibleValues = values;
this.value = value; this.value = value;
this.enabled = true;
checkArgument(!values.isEmpty(), "possible values cannot be empty"); checkArgument(!values.isEmpty(), "possible values cannot be empty");
checkArgument(values.contains(value), "possible values must contain a value"); checkArgument(values.contains(value), "possible values must contain a value");
} }
@ -34,6 +36,17 @@ public abstract class Parameter<T> {
return possibleValues.size(); 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); 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 org.jetbrains.annotations.NotNull;
import java.util.*; import java.util.*;
import java.util.stream.Stream;
public class Parameters extends AbstractCollection<Parameter<?>> { public class Parameters extends AbstractCollection<Parameter<?>> {
private final Map<String, Parameter<?>> enabledParameters; private final Map<String, Parameter<?>> parameters;
private final Map<String, Parameter<?>> disabledParameters;
public Parameters() { public Parameters() {
enabledParameters = new LinkedHashMap<>(); parameters = new LinkedHashMap<>();
disabledParameters = new LinkedHashMap<>();
} }
@Override @Override
public boolean add(Parameter<?> parameter) { 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) { 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) { public void disable(String id) {
Optional.ofNullable(findById(id)) Optional.ofNullable(parameters.get(id))
.ifPresent(p -> disabledParameters.put(p.id, p)); .ifPresent(Parameter::disable);
}
public void disableAll(Collection<String> ids) {
ids.forEach(this::disable);
} }
public void enable(String id) { public void enable(String id) {
Optional.ofNullable(disabledParameters.get(id)) Optional.ofNullable(parameters.get(id))
.ifPresent(this::add); .ifPresent(Parameter::enable);
}
public void enableAll(Collection<String> ids) {
ids.forEach(this::enable);
} }
@NotNull @NotNull
@Override @Override
public Iterator<Parameter<?>> iterator() { public Iterator<Parameter<?>> iterator() {
return enabledParameters.values().iterator(); return enabledParameters().iterator();
} }
@Override @Override
public int size() { 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 com.annimon.ffmpegbot.session.FileType;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import java.util.List; import java.util.List;
import java.util.Optional;
import java.util.Set;
public class AudioResolver implements ParametersResolver { 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) { private void disableAudioParam(@NotNull Parameters parameters, @NotNull FileType fileType) {
final boolean canAudioBeDisabled = switch (fileType) { final boolean canAudioBeDisabled = switch (fileType) {
case ANIMATION, AUDIO, VOICE -> false; case ANIMATION, AUDIO, VOICE -> false;

View File

@ -24,4 +24,11 @@ public class GlobalParametersResolver implements ParametersResolver {
resolver.resolve(parameters, fileInfo); 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; package com.annimon.ffmpegbot.parameters.resolvers;
import com.annimon.ffmpegbot.parameters.AudioStreamByLanguage; import com.annimon.ffmpegbot.parameters.*;
import com.annimon.ffmpegbot.parameters.Parameters;
import com.annimon.ffmpegbot.session.FileInfo; import com.annimon.ffmpegbot.session.FileInfo;
import com.annimon.ffmpegbot.session.FileType; import com.annimon.ffmpegbot.session.FileType;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
@ -19,4 +18,16 @@ public class MultiAudioStreamsResolver implements ParametersResolver {
parameters.add(new AudioStreamByLanguage()); 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 { public interface ParametersResolver {
void resolve(@NotNull Parameters parameters, @NotNull FileInfo fileInfo); 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 com.annimon.ffmpegbot.session.FileInfo;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import java.util.List; import java.util.List;
import java.util.Objects;
import java.util.Set;
public class VideoResolver implements ParametersResolver { 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);
}
});
}
} }