Extraction works

This commit is contained in:
Guillaume Tâche
2024-08-04 21:55:30 +02:00
parent 8002fc6719
commit 5efdaa6f63
121 changed files with 3360 additions and 400 deletions

View File

@@ -7,5 +7,10 @@ public interface AudioInfo {
/**
* @return The audio extension (mp3, etc.)
*/
String videoFormat();
String audioFormat();
/**
* @return The audio duration in milliseconds
*/
long duration();
}

View File

@@ -0,0 +1,97 @@
package com.github.gtache.autosubtitle;
import java.util.Locale;
import java.util.Map;
import java.util.Set;
import static java.util.Objects.requireNonNull;
/**
* A list of languages //TODO add more or use Locale if possible?
*/
public enum Language {
AR("arabic", "ar", "ara"),
BE("belarusian", "be", "bel"),
BG("bulgarian", "bg", "bul"),
CS("czech", "cs", "cze"),
DA("danish", "da", "dan"),
DE("german", "de", "deu", "ger"),
EL("greek", "el", "gre"),
EN("english", "en", "eng"),
ES("spanish", "es", "spa"),
FA("persian", "fa", "per"),
FI("finnish", "fi", "fin"),
FR("french", "fr", "fra", "fre"),
HE("hebrew", "he", "heb"),
HR("croatian", "hr", "hrv"),
ID("indonesian", "id", "ind"),
IT("italian", "it", "ita", "gre"),
JA("japanese", "ja", "jpn"),
KO("korean", "ko", "kor"),
LA("latin", "la", "lat"),
LB("luxembourgish", "lb", "ltz"),
LO("lao", "lo", "lao"),
LT("lithuanian", "lt", "lit"),
MT("maltese", "mt", "mlt"),
MY("myanmar", "my", "mya"),
NL("dutch", "nl", "nld"),
NO("norwegian", "no", "nor"),
PL("polish", "pl", "pol"),
PT("portuguese", "pt", "por"),
RO("romanian", "ro", "ron"),
RU("russian", "ru", "rus"),
SK("slovak", "sk", "slo"),
SL("slovenian", "sl", "slv"),
SV("swedish", "sv", "swe"),
TH("thai", "th", "tha"),
TR("turkish", "tr", "tur"),
UK("ukrainian", "uk", "ukr"),
VI("vietnamese", "vi", "vie"),
ZH("chinese", "zh", "zho", "chi"),
AUTO("auto", "auto", "auto");
private static final Map<String, Language> STRING_LANGUAGE_MAP;
static {
final Map<String, Language> map = new java.util.HashMap<>();
for (final var language : Language.values()) {
map.put(language.name().toLowerCase(), language);
map.put(language.iso2, language);
map.put(language.iso3, language);
language.aliases.forEach(s -> map.put(s, language));
}
STRING_LANGUAGE_MAP = map;
}
private final String englishName;
private final String iso2;
private final String iso3;
private final Set<String> aliases;
Language(final String englishName, final String iso2, final String iso3, final String... aliases) {
this.englishName = requireNonNull(englishName);
this.iso2 = requireNonNull(iso2);
this.iso3 = requireNonNull(iso3);
this.aliases = Set.of(aliases);
}
public String englishName() {
return englishName;
}
public String iso2() {
return iso2;
}
public String iso3() {
return iso3;
}
public static Language getLanguage(final String name) {
return STRING_LANGUAGE_MAP.get(name.toLowerCase());
}
public static Language getDefault() {
return STRING_LANGUAGE_MAP.getOrDefault(Locale.getDefault().getLanguage(), EN);
}
}

View File

@@ -3,88 +3,86 @@ package com.github.gtache.autosubtitle;
import com.github.gtache.autosubtitle.subtitle.Subtitle;
import com.github.gtache.autosubtitle.subtitle.SubtitleCollection;
import java.util.Locale;
/**
* Translates texts and subtitles
*/
public interface Translator {
/**
* Guesses the locale of the given text
* Guesses the language of the given text
*
* @param text The text
* @return The guessed locale
* @return The guessed language
*/
Locale getLocale(final String text);
Language getLanguage(final String text);
/**
* Guesses the locale of the given subtitle
* Guesses the language of the given subtitle
*
* @param subtitle The subtitle
* @return The guessed locale
* @return The guessed language
*/
default Locale getLocale(final Subtitle subtitle) {
return getLocale(subtitle.content());
default Language getLanguage(final Subtitle subtitle) {
return getLanguage(subtitle.content());
}
/**
* Translates the given text to the given locale
* Translates the given text to the given language
*
* @param text The text to translate
* @param to The target locale
* @param to The target language
* @return The translated text
*/
String translate(String text, Locale to);
String translate(String text, Language to);
/**
* Translates the given text to the given locale
* Translates the given text to the given language
*
* @param text The text to translate
* @param to The target locale
* @param to The target language
* @return The translated text
*/
default String translate(final String text, final String to) {
return translate(text, Locale.forLanguageTag(to));
return translate(text, Language.getLanguage(to));
}
/**
* Translates the given subtitle to the given locale
* Translates the given subtitle to the given language
*
* @param subtitle The subtitle to translate
* @param to The target locale
* @param to The target language
* @return The translated subtitle
*/
Subtitle translate(Subtitle subtitle, Locale to);
Subtitle translate(Subtitle subtitle, Language to);
/**
* Translates the given subtitle to the given locale
* Translates the given subtitle to the given language
*
* @param subtitle The subtitle to translate
* @param to The target locale
* @param to The target language
* @return The translated subtitle
*/
default Subtitle translate(final Subtitle subtitle, final String to) {
return translate(subtitle, Locale.forLanguageTag(to));
return translate(subtitle, Language.getLanguage(to));
}
/**
* Translates the given subtitles collection to the given locale
* Translates the given subtitles collection to the given language
*
* @param collection The subtitles collection to translate
* @param to The target locale
* @param to The target language
* @return The translated subtitles collection
*/
default SubtitleCollection translate(final SubtitleCollection collection, final String to) {
return translate(collection, Locale.forLanguageTag(to));
return translate(collection, Language.getLanguage(to));
}
/**
* Translates the given subtitles collection to the given locale
* Translates the given subtitles collection to the given language
*
* @param collection The subtitles collection to translate
* @param to The target locale
* @param to The target language
* @return The translated subtitles collection
*/
SubtitleCollection translate(SubtitleCollection collection, Locale to);
SubtitleCollection translate(SubtitleCollection collection, Language to);
}

View File

@@ -0,0 +1,31 @@
package com.github.gtache.autosubtitle.process;
import java.io.IOException;
import java.time.Duration;
/**
* Listens to a process
*/
public interface ProcessListener {
/**
* @return The process
*/
Process process();
/**
* Waits for the next output of the process (or its end). Note that the process may become stuck if the output is not read.
*
* @return The next line of the process output, or null if the process has ended
* @throws IOException if an error occurs
*/
String readLine() throws IOException;
/**
* Waits for the process to finish
*
* @param duration The maximum time to wait
* @return The process result
*/
ProcessResult join(final Duration duration) throws IOException;
}

View File

@@ -28,4 +28,44 @@ public interface ProcessRunner {
* @throws IOException if something goes wrong
*/
ProcessResult run(final List<String> args) throws IOException;
/**
* Starts a process
*
* @param args the command
* @return The process
* @throws IOException if something goes wrong
*/
default Process start(final String... args) throws IOException {
return start(Arrays.asList(args));
}
/**
* Starts a process
*
* @param args the command
* @return The process
* @throws IOException if something goes wrong
*/
Process start(final List<String> args) throws IOException;
/**
* Starts a process
*
* @param args the command
* @return An object allowing to listen to the process
* @throws IOException if something goes wrong
*/
default ProcessListener startListen(final String... args) throws IOException {
return startListen(Arrays.asList(args));
}
/**
* Starts a process
*
* @param args the command
* @return An object allowing to listen to the process
* @throws IOException if something goes wrong
*/
ProcessListener startListen(final List<String> args) throws IOException;
}

View File

@@ -0,0 +1,8 @@
package com.github.gtache.autosubtitle.setup;
/**
* Represents a setup action
*/
public enum SetupAction {
CHECK, DOWNLOAD, INSTALL, UNINSTALL, UPDATE, DELETE
}

View File

@@ -0,0 +1,27 @@
package com.github.gtache.autosubtitle.setup;
/**
* Events that can be triggered by {@link SetupManager}
*/
public interface SetupEvent {
/**
* @return the action that triggered the event
*/
SetupAction action();
/**
* @return the target of the action
*/
String target();
/**
* @return the progress of the setup
*/
double progress();
/**
* @return the setup manager that triggered the event
*/
SetupManager setupManager();
}

View File

@@ -0,0 +1,21 @@
package com.github.gtache.autosubtitle.setup;
/**
* Listens on {@link SetupManager}'s {@link SetupEvent}s
*/
public interface SetupListener {
/**
* Triggered when an action starts
*
* @param event the event
*/
void onActionStart(SetupEvent event);
/**
* Triggered when an action ends
*
* @param event the event
*/
void onActionEnd(SetupEvent event);
}

View File

@@ -17,11 +17,9 @@ public interface SetupManager {
/**
* @return whether the component is installed
* @throws SetupException if an error occurred during the check
* @throws SetupException if an error occurred
*/
default boolean isInstalled() throws SetupException {
return status().isInstalled();
}
boolean isInstalled() throws SetupException;
/**
* Installs the component
@@ -42,10 +40,7 @@ public interface SetupManager {
*
* @throws SetupException if an error occurred during the reinstallation
*/
default void reinstall() throws SetupException {
uninstall();
install();
}
void reinstall() throws SetupException;
/**
* Checks if an update is available for the component
@@ -53,9 +48,7 @@ public interface SetupManager {
* @return whether an update is available
* @throws SetupException if an error occurred during the check
*/
default boolean isUpdateAvailable() throws SetupException {
return status() == SetupStatus.UPDATE_AVAILABLE;
}
boolean isUpdateAvailable() throws SetupException;
/**
* Updates the component
@@ -63,4 +56,23 @@ public interface SetupManager {
* @throws SetupException if an error occurred during the update
*/
void update() throws SetupException;
/**
* Adds a listener
*
* @param listener the listener
*/
void addListener(SetupListener listener);
/**
* Removes a listener
*
* @param listener the listener
*/
void removeListener(SetupListener listener);
/**
* Removes all listeners
*/
void removeListeners();
}

View File

@@ -4,9 +4,9 @@ package com.github.gtache.autosubtitle.setup;
* The status of a setup
*/
public enum SetupStatus {
ERRORED, NOT_INSTALLED, INSTALLED, UPDATE_AVAILABLE;
ERRORED, NOT_INSTALLED, SYSTEM_INSTALLED, BUNDLE_INSTALLED, UPDATE_AVAILABLE;
public boolean isInstalled() {
return this == INSTALLED || this == UPDATE_AVAILABLE;
return this == SYSTEM_INSTALLED || this == BUNDLE_INSTALLED || this == UPDATE_AVAILABLE;
}
}

View File

@@ -0,0 +1,17 @@
package com.github.gtache.autosubtitle.subtitle;
/**
* Events that can be triggered by {@link SubtitleExtractor}
*/
public interface ExtractEvent {
/**
* @return the message
*/
String message();
/**
* @return the progress of the setup
*/
double progress();
}

View File

@@ -0,0 +1,19 @@
package com.github.gtache.autosubtitle.subtitle;
/**
* Exception thrown when an error occurs during subtitle extraction
*/
public class ExtractException extends Exception {
public ExtractException(final String message) {
super(message);
}
public ExtractException(final String message, final Throwable cause) {
super(message, cause);
}
public ExtractException(final Throwable cause) {
super(cause);
}
}

View File

@@ -0,0 +1,11 @@
package com.github.gtache.autosubtitle.subtitle;
/**
* An extraction model
*/
public interface ExtractionModel {
/**
* @return the name of the model
*/
String name();
}

View File

@@ -0,0 +1,25 @@
package com.github.gtache.autosubtitle.subtitle;
import java.util.List;
/**
* Provider of {@link ExtractionModel}
*/
public interface ExtractionModelProvider {
/**
* @return the list of all available models
*/
List<ExtractionModel> getAvailableExtractionModels();
/**
* @return the default model
*/
ExtractionModel getDefaultExtractionModel();
/**
* @param name the name of the model
* @return the model with the specified name
*/
ExtractionModel getExtractionModel(final String name);
}

View File

@@ -0,0 +1,8 @@
package com.github.gtache.autosubtitle.subtitle;
/**
* The possible subtitles output formats
*/
public enum OutputFormat {
SRT, ASS
}

View File

@@ -1,7 +1,8 @@
package com.github.gtache.autosubtitle.subtitle;
import com.github.gtache.autosubtitle.Language;
import java.util.Collection;
import java.util.Locale;
/**
* Represents a collection of {@link Subtitle}
@@ -14,7 +15,7 @@ public interface SubtitleCollection {
Collection<? extends Subtitle> subtitles();
/**
* @return The locale of the subtitles
* @return The language of the subtitles
*/
Locale locale();
Language language();
}

View File

@@ -1,16 +1,76 @@
package com.github.gtache.autosubtitle.subtitle;
import com.github.gtache.autosubtitle.Audio;
import com.github.gtache.autosubtitle.Language;
import com.github.gtache.autosubtitle.Video;
import java.util.Collection;
/**
* Extracts subtitles from a video or audio
*/
public interface SubtitleExtractor {
Collection<? extends EditableSubtitle> extract(final Video in);
/**
* Adds a listener
*
* @param listener The listener
*/
void addListener(SubtitleExtractorListener listener);
Collection<? extends EditableSubtitle> extract(final Audio in);
/**
* Removes a listener
*
* @param listener The listener
*/
void removeListener(SubtitleExtractorListener listener);
/**
* Removes all listeners
*/
void removeListeners();
/**
* Extracts the subtitles from a video
*
* @param video The video
* @param model The model to use
* @return The extracted subtitle collection
* @throws ExtractException If an error occurs
*/
default SubtitleCollection extract(final Video video, final ExtractionModel model) throws ExtractException {
return extract(video, Language.AUTO, model);
}
/**
* Extracts the subtitles from a video
*
* @param video The video
* @param language The language of the video
* @param model The model to use
* @return The extracted subtitle collection
* @throws ExtractException If an error occurs
*/
SubtitleCollection extract(final Video video, final Language language, final ExtractionModel model) throws ExtractException;
/**
* Extracts the subtitles from an audio
*
* @param audio The audio
* @param model The model to use
* @return The extracted subtitle collection
* @throws ExtractException If an error occurs
*/
default SubtitleCollection extract(final Audio audio, final ExtractionModel model) throws ExtractException {
return extract(audio, Language.AUTO, model);
}
/**
* Extracts the subtitles from an audio
*
* @param audio The audio
* @param language The language of the audio
* @param model The model to use
* @return The extracted subtitle collection
* @throws ExtractException If an error occurs
*/
SubtitleCollection extract(final Audio audio, final Language language, final ExtractionModel model) throws ExtractException;
}

View File

@@ -0,0 +1,15 @@
package com.github.gtache.autosubtitle.subtitle;
/**
* Listener for {@link SubtitleExtractor}
*/
@FunctionalInterface
public interface SubtitleExtractorListener {
/**
* Called when an event is triggered
*
* @param event The event
*/
void listen(final ExtractEvent event);
}