Can playback video with controls, need to fix performance and reducing window size

This commit is contained in:
Guillaume Tâche
2024-08-01 19:42:25 +02:00
parent 75829244b9
commit a94eaff9ad
102 changed files with 2921 additions and 423 deletions

View File

@@ -16,6 +16,11 @@
<groupId>com.github.gtache.autosubtitle</groupId>
<artifactId>autosubtitle-api</artifactId>
</dependency>
<dependency>
<groupId>com.google.dagger</groupId>
<artifactId>dagger</artifactId>
</dependency>
</dependencies>
</project>

View File

@@ -0,0 +1,35 @@
package com.github.gtache.autosubtitle.gui;
import java.util.Arrays;
import java.util.Collections;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Map;
import java.util.ResourceBundle;
/**
* Combines multiple resource bundles
*/
public class CombinedResourceBundle extends ResourceBundle {
private final Map<String, String> resources;
public CombinedResourceBundle(final ResourceBundle... bundles) {
this(Arrays.asList(bundles));
}
public CombinedResourceBundle(final Iterable<ResourceBundle> bundles) {
this.resources = new HashMap<>();
bundles.forEach(rb -> rb.getKeys().asIterator().forEachRemaining(key -> resources.put(key, rb.getString(key))));
}
@Override
protected Object handleGetObject(final String key) {
return resources.get(key);
}
@Override
public Enumeration<String> getKeys() {
return Collections.enumeration(resources.keySet());
}
}

View File

@@ -1,12 +1,19 @@
package com.github.gtache.autosubtitle.gui;
import java.nio.file.Path;
/**
* Controller for the main view
*/
public interface MainController {
void extractSubtitles();
void loadVideo(final Path file);
/**
* Selects the given tab
*
* @param index The tab index
*/
void selectTab(final int index);
/**
* @return The model
*/
MainModel model();
}

View File

@@ -1,15 +1,17 @@
package com.github.gtache.autosubtitle.gui;
import com.github.gtache.autosubtitle.subtitle.EditableSubtitle;
import com.github.gtache.autosubtitle.Video;
import java.util.List;
/**
* Model for the main view
*/
public interface MainModel {
Video video();
/**
* @return The currently selected tab index
*/
int selectedTab();
List<EditableSubtitle> subtitles();
EditableSubtitle selectedSubtitle();
/**
* @param index The index of the tab to select
*/
void selectTab(int index);
}

View File

@@ -0,0 +1,29 @@
package com.github.gtache.autosubtitle.gui;
/**
* Controller for the media view
*/
public interface MediaController {
/**
* Plays the media
*/
void play();
/**
* Pauses the media
*/
void pause();
/**
* Seeks the given position in the media
*
* @param position the new position
*/
void seek(long position);
/**
* @return The model for this controller
*/
MediaModel model();
}

View File

@@ -0,0 +1,70 @@
package com.github.gtache.autosubtitle.gui;
import com.github.gtache.autosubtitle.Video;
import com.github.gtache.autosubtitle.subtitle.EditableSubtitle;
import java.util.List;
/**
* Model for the media view
*/
public interface MediaModel {
/**
* @return The current video
*/
Video video();
/**
* Sets the video
*
* @param video the new video
*/
void setVideo(Video video);
/**
* @return The current volume between 0 and 1
*/
double volume();
/**
* Sets the volume
*
* @param volume the new volume
*/
void setVolume(double volume);
/**
* @return Whether the media is playing
*/
boolean isPlaying();
/**
* Sets the playing state
*
* @param playing the new playing state
*/
void setIsPlaying(boolean playing);
/**
* @return The duration of the media
*/
long duration();
/**
* @return The current position in the media
*/
long position();
/**
* Sets the position
*
* @param position the new position
*/
void setPosition(long position);
/**
* @return The current list of subtitles
*/
List<EditableSubtitle> subtitles();
}

View File

@@ -1,79 +1,159 @@
package com.github.gtache.autosubtitle.gui;
import com.github.gtache.autosubtitle.setup.SetupStatus;
/**
* Model for the setup view
*/
public interface SetupModel {
/**
* @return whether the subtitle extractor is installed
* @return the status of the subtitle extractor
*/
boolean isSubtitleExtractorInstalled();
SetupStatus subtitleExtractorStatus();
/**
* Sets whether the subtitle extractor is installed
* Sets the status of the subtitle extractor
*
* @param installed whether the subtitle extractor is installed
* @param status the new status
*/
void setSubtitleExtractorInstalled(boolean installed);
void setSubtitleExtractorStatus(SetupStatus status);
/**
* @return whether the subtitle extractor is installed
*/
default boolean isSubtitleExtractorInstalled() {
return subtitleExtractorStatus().isInstalled();
}
/**
* @return whether an update is available for the subtitle extractor
*/
boolean isSubtitleExtractorUpdateAvailable();
default boolean isSubtitleExtractorUpdateAvailable() {
return subtitleExtractorStatus() == SetupStatus.UPDATE_AVAILABLE;
}
/**
* Sets whether an update is available for the subtitle extractor
*
* @param updateAvailable whether an update is available for the subtitle extractor
* @return the progress of the subtitle extractor setup
*/
void setSubtitleExtractorUpdateAvailable(boolean updateAvailable);
double subtitleExtractorSetupProgress();
/**
* Sets the progress of the subtitle extractor setup
*
* @param progress the new progress
*/
void setSubtitleExtractorSetupProgress(double progress);
/**
* @return the text of the subtitle extractor setup progress
*/
String subtitleExtractorSetupProgressLabel();
/**
* Sets the text of the subtitle extractor setup progress
*
* @param label the new text
*/
void setSubtitleExtractorSetupProgressLabel(String label);
/**
* @return the status of the video converter
*/
SetupStatus videoConverterStatus();
/**
* Sets the status of the video converter
*
* @param status the new status
*/
void setVideoConverterStatus(SetupStatus status);
/**
* @return whether the video converter is installed
*/
boolean isVideoConverterInstalled();
/**
* Sets whether the video converter is installed
*
* @param installed whether the video converter is installed
*/
void setVideoConverterInstalled(boolean installed);
default boolean isVideoConverterInstalled() {
return videoConverterStatus().isInstalled();
}
/**
* @return whether an update is available for the video converter
*/
boolean isVideoConverterUpdateAvailable();
default boolean isVideoConverterUpdateAvailable() {
return videoConverterStatus() == SetupStatus.UPDATE_AVAILABLE;
}
/**
* Sets whether an update is available for the video converter
*
* @param updateAvailable whether an update is available for the video converter
* @return the progress of the video converter setup
*/
void setVideoConverterUpdateAvailable(boolean updateAvailable);
double videoConverterSetupProgress();
/**
* Sets the progress of the video converter setup
*
* @param progress the new progress
*/
void setVideoConverterSetupProgress(double progress);
/**
* @return the text of the video converter setup progress
*/
String videoConverterSetupProgressLabel();
/**
* Sets the text of the video converter setup progress
*
* @param label the new text
*/
void setVideoConverterSetupProgressLabel(String label);
/**
* @return the status of the translator
*/
SetupStatus translatorStatus();
/**
* Sets the status of the translator
*
* @param status the new status
*/
void setTranslatorStatus(SetupStatus status);
/**
* @return whether the translator is installed
*/
boolean isTranslatorInstalled();
/**
* Sets whether the translator is installed
*
* @param installed whether the translator is installed
*/
void setTranslatorInstalled(boolean installed);
default boolean isTranslatorInstalled() {
return translatorStatus().isInstalled();
}
/**
* @return whether an update is available for the translator
*/
boolean isTranslatorUpdateAvailable();
default boolean isTranslatorUpdateAvailable() {
return translatorStatus() == SetupStatus.UPDATE_AVAILABLE;
}
/**
* Sets whether an update is available for the translator
*
* @param updateAvailable whether an update is available for the translator
* @return the progress of the translator setup
*/
void setTranslatorUpdateAvailable(boolean updateAvailable);
double translatorSetupProgress();
/**
* Sets the progress of the translator setup
*
* @param progress the new progress
*/
void setTranslatorSetupProgress(double progress);
/**
* @return the text of the translator setup progress
*/
String translatorSetupProgressLabel();
/**
* Sets the text of the translator setup progress
*
* @param label the new text
*/
void setTranslatorSetupProgressLabel(String label);
}

View File

@@ -0,0 +1,26 @@
package com.github.gtache.autosubtitle.gui;
import java.nio.file.Path;
/**
* Controller for the work view
*/
public interface WorkController {
/**
* Extracts the subtitles for the current video
*/
void extractSubtitles();
/**
* Loads a video
*
* @param file The path to the video
*/
void loadVideo(final Path file);
/**
* @return The model
*/
WorkModel model();
}

View File

@@ -0,0 +1,38 @@
package com.github.gtache.autosubtitle.gui;
import com.github.gtache.autosubtitle.Video;
import com.github.gtache.autosubtitle.subtitle.EditableSubtitle;
import java.util.List;
import java.util.Locale;
/**
* Model for the main view
*/
public interface WorkModel {
/**
* @return The current video
*/
Video video();
/**
* @return The current list of subtitles
*/
List<EditableSubtitle> subtitles();
/**
* @return The original extracted subtitles (used to reset)
*/
List<EditableSubtitle> originalSubtitles();
/**
* @return The currently selected subtitle
*/
EditableSubtitle selectedSubtitle();
/**
* @return The list of selected translations
*/
List<Locale> translations();
}

View File

@@ -0,0 +1,9 @@
package com.github.gtache.autosubtitle.gui.spi;
import java.util.spi.ResourceBundleProvider;
/**
* Provider for MainBundle
*/
public interface MainBundleProvider extends ResourceBundleProvider {
}

View File

@@ -0,0 +1,9 @@
package com.github.gtache.autosubtitle.gui.spi;
import java.util.spi.AbstractResourceBundleProvider;
/**
* Implementation of {@link MainBundleProvider}
*/
public class MainBundleProviderImpl extends AbstractResourceBundleProvider implements MainBundleProvider {
}

View File

@@ -0,0 +1,9 @@
package com.github.gtache.autosubtitle.gui.spi;
import java.util.spi.ResourceBundleProvider;
/**
* Provider for SetupBundle
*/
public interface SetupBundleProvider extends ResourceBundleProvider {
}

View File

@@ -0,0 +1,9 @@
package com.github.gtache.autosubtitle.gui.spi;
import java.util.spi.AbstractResourceBundleProvider;
/**
* Implementation of {@link SetupBundleProvider}
*/
public class SetupBundleProviderImpl extends AbstractResourceBundleProvider implements SetupBundleProvider {
}

View File

@@ -0,0 +1,9 @@
package com.github.gtache.autosubtitle.gui.spi;
import java.util.spi.ResourceBundleProvider;
/**
* Provider for WorkBundle
*/
public interface WorkBundleProvider extends ResourceBundleProvider {
}

View File

@@ -0,0 +1,9 @@
package com.github.gtache.autosubtitle.gui.spi;
import java.util.spi.AbstractResourceBundleProvider;
/**
* Implementation of {@link WorkBundleProviderImpl}
*/
public class WorkBundleProviderImpl extends AbstractResourceBundleProvider implements WorkBundleProvider {
}

View File

@@ -0,0 +1,46 @@
package com.github.gtache.autosubtitle.modules.gui;
import com.github.gtache.autosubtitle.gui.CombinedResourceBundle;
import dagger.Module;
import dagger.Provides;
import javax.inject.Singleton;
import java.io.IOException;
import java.util.ResourceBundle;
/**
* Dagger module for GUI
*/
@Module
public class GuiModule {
@Provides
@Singleton
static ResourceBundle providesBundle() {
return new CombinedResourceBundle(ResourceBundle.getBundle("com.github.gtache.autosubtitle.gui.MainBundle"),
ResourceBundle.getBundle("com.github.gtache.autosubtitle.gui.SetupBundle"),
ResourceBundle.getBundle("com.github.gtache.autosubtitle.gui.WorkBundle"),
ResourceBundle.getBundle("com.github.gtache.autosubtitle.gui.MediaBundle"));
}
@Provides
@Singleton
@Play
static byte[] providesPlayImage() {
try {
return GuiModule.class.getResourceAsStream("/com/github/gtache/autosubtitle/gui/play_64.png").readAllBytes();
} catch (final IOException e) {
throw new RuntimeException(e);
}
}
@Provides
@Singleton
@Pause
static byte[] providesPauseImage() {
try {
return GuiModule.class.getResourceAsStream("/com/github/gtache/autosubtitle/gui/pause_64.png").readAllBytes();
} catch (final IOException e) {
throw new RuntimeException(e);
}
}
}

View File

@@ -0,0 +1,16 @@
package com.github.gtache.autosubtitle.modules.gui;
import javax.inject.Qualifier;
import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.Target;
import static java.lang.annotation.RetentionPolicy.RUNTIME;
@Qualifier
@Documented
@Retention(RUNTIME)
@Target({ElementType.PARAMETER, ElementType.METHOD, ElementType.FIELD})
public @interface Pause {
}

View File

@@ -0,0 +1,16 @@
package com.github.gtache.autosubtitle.modules.gui;
import javax.inject.Qualifier;
import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.Target;
import static java.lang.annotation.RetentionPolicy.RUNTIME;
@Qualifier
@Documented
@Retention(RUNTIME)
@Target({ElementType.PARAMETER, ElementType.METHOD, ElementType.FIELD})
public @interface Play {
}

View File

@@ -0,0 +1,23 @@
import com.github.gtache.autosubtitle.gui.spi.MainBundleProvider;
import com.github.gtache.autosubtitle.gui.spi.MainBundleProviderImpl;
import com.github.gtache.autosubtitle.gui.spi.SetupBundleProvider;
import com.github.gtache.autosubtitle.gui.spi.SetupBundleProviderImpl;
import com.github.gtache.autosubtitle.gui.spi.WorkBundleProvider;
import com.github.gtache.autosubtitle.gui.spi.WorkBundleProviderImpl;
/**
* GUI module for auto-subtitle
*/
module com.github.gtache.autosubtitle.gui {
requires transitive com.github.gtache.autosubtitle.api;
requires transitive dagger;
requires transitive javax.inject;
exports com.github.gtache.autosubtitle.gui;
exports com.github.gtache.autosubtitle.gui.spi;
exports com.github.gtache.autosubtitle.modules.gui;
provides MainBundleProvider with MainBundleProviderImpl;
provides SetupBundleProvider with SetupBundleProviderImpl;
provides WorkBundleProvider with WorkBundleProviderImpl;
}

View File

@@ -1,4 +0,0 @@
main.button.export.label=Export video...
main.button.extract.label=Extract subtitles
main.button.file.label=Open file...
main.button.reset.label=Reset subtitles

View File

@@ -1 +0,0 @@
main.button.file.label=Ouvrir un fichier...

View File

@@ -0,0 +1,2 @@
main.tab.setup.label=Setup
main.tab.work.label=Work

View File

@@ -0,0 +1,2 @@
main.tab.setup.label=Installation
main.tab.work.label=Travail

View File

@@ -0,0 +1 @@
media.volume.label=Volume

View File

@@ -0,0 +1 @@
media.volume.label=Volume

View File

@@ -0,0 +1,18 @@
setup.description.label=Status of the various tools used by the app
setup.install.error.label=An error occurred while installing : {0}
setup.install.error.title=Error installing
setup.menu.install.label=Install
setup.menu.label=Action
setup.menu.reinstall.label=Reinstall
setup.menu.uninstall.label=Uninstall
setup.menu.update.label=Update
setup.reinstall.error.label=An error occurred while reinstalling : {0}
setup.reinstall.error.title=Error reinstalling
setup.status.errored.label=threw an error.
setup.status.installed.label=is installed.
setup.status.not_installed.label=is not installed.
setup.status.update_available.label=has an available update.
setup.uninstall.error.label=An error occurred while uninstalling : {0}
setup.uninstall.error.title=Error uninstalling
setup.update.error.label=An error occurred while updating : {0}
setup.update.error.title=Error updating

View File

@@ -0,0 +1,18 @@
setup.description.label=Statut des outils utilis\u00E9s par l'application
setup.install.error.label=Une erreur s''est produite lors de l''installation: {0}
setup.install.error.title=Erreur d'installation
setup.menu.install.label=Installer
setup.menu.label=Action
setup.menu.reinstall.label=R\u00E9installer
setup.menu.uninstall.label=D\u00E9sinstaller
setup.menu.update.label=Mettre \u00E0 jour
setup.reinstall.error.label=Une erreur s''est produite lors de la r\u00E9installation: {0}
setup.reinstall.error.title=Erreur de r\u00E9installation
setup.status.errored.label=a caus\u00E9 une erreur.
setup.status.installed.label=est install\u00E9.
setup.status.not_installed.label=n'est pas install\u00E9.
setup.status.update_available.label=a une mise \u00E0 jour disponible.
setup.uninstall.error.label=Une erreur s''est produite lors de la d\u00E9sinstallation : {0}
setup.uninstall.error.title=Erreur de d\u00E9sinstallation
setup.update.error.label=Une erreur s''est produite lors de la mise \u00E0 jour : {0}
setup.update.error.title=Erreur de mise \u00E0 jour

View File

@@ -0,0 +1,14 @@
work.button.export.hard.label=Burn video...
work.button.export.hard.tooltip=Burns the subtitles into the video. This means that the subtitles are printed in the image and can't be disabled.
work.button.export.soft.label=Export video...
work.button.export.soft.tooltip=Adds the subtitles to the video. This allows a video to have multiple subtitles and to enable them at will.
work.button.extract.label=Extract subtitles
work.button.file.label=Open video...
work.button.reset.label=Reset subtitles
work.error.export.label=Error during the export : {0}
work.error.export.title=Error exporting
work.table.column.from.label=From
work.table.column.text.label=Text
work.table.column.to.label=To
work.translate.label=Automatic translation (for adding)
work.translate.tooltip=A comma-separated list of ISO 639-3 codes

View File

@@ -0,0 +1,3 @@
work.table.column.from.label=De
work.table.column.text.label=Texte
work.table.column.to.label=\u00C0

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.6 KiB