Rework to avoid using preferences object to retrieve options
This commit is contained in:
@@ -2,7 +2,6 @@ package com.github.gtache.autosubtitle.subtitle.extractor.whisper;
|
||||
|
||||
import com.github.gtache.autosubtitle.Audio;
|
||||
import com.github.gtache.autosubtitle.File;
|
||||
import com.github.gtache.autosubtitle.Language;
|
||||
import com.github.gtache.autosubtitle.Video;
|
||||
import com.github.gtache.autosubtitle.impl.OS;
|
||||
import com.github.gtache.autosubtitle.process.ProcessRunner;
|
||||
@@ -13,7 +12,7 @@ import com.github.gtache.autosubtitle.subtitle.converter.SubtitleConverter;
|
||||
import com.github.gtache.autosubtitle.subtitle.converter.SubtitleConverterProvider;
|
||||
import com.github.gtache.autosubtitle.subtitle.extractor.ExtractEvent;
|
||||
import com.github.gtache.autosubtitle.subtitle.extractor.ExtractException;
|
||||
import com.github.gtache.autosubtitle.subtitle.extractor.ExtractionModel;
|
||||
import com.github.gtache.autosubtitle.subtitle.extractor.ExtractOptions;
|
||||
import com.github.gtache.autosubtitle.subtitle.extractor.SubtitleExtractor;
|
||||
import com.github.gtache.autosubtitle.subtitle.extractor.SubtitleExtractorListener;
|
||||
import com.github.gtache.autosubtitle.subtitle.extractor.impl.ExtractEventImpl;
|
||||
@@ -79,41 +78,41 @@ public abstract class AbstractWhisperSubtitleExtractor implements SubtitleExtrac
|
||||
|
||||
|
||||
@Override
|
||||
public SubtitleCollection<Subtitle> extract(final Video video, final Language language, final ExtractionModel model) throws ExtractException {
|
||||
return extract(new AudioOrVideo(video), language, model);
|
||||
public SubtitleCollection<Subtitle> extract(final Video video, final ExtractOptions options) throws ExtractException {
|
||||
return extract(new AudioOrVideo(video), options);
|
||||
}
|
||||
|
||||
@Override
|
||||
public SubtitleCollection<Subtitle> extract(final Audio audio, final Language language, final ExtractionModel model) throws ExtractException {
|
||||
return extract(new AudioOrVideo(audio), language, model);
|
||||
public SubtitleCollection<Subtitle> extract(final Audio audio, final ExtractOptions options) throws ExtractException {
|
||||
return extract(new AudioOrVideo(audio), options);
|
||||
}
|
||||
|
||||
private SubtitleCollection<Subtitle> extract(final AudioOrVideo av, final Language language, final ExtractionModel model) throws ExtractException {
|
||||
private SubtitleCollection<Subtitle> extract(final AudioOrVideo av, final ExtractOptions options) throws ExtractException {
|
||||
if (av.inner() instanceof final File f) {
|
||||
return extract(f.path(), language, model, av.info().duration());
|
||||
return extract(f.path(), options, av.info().duration());
|
||||
} else {
|
||||
try {
|
||||
return dumpExtract(av, language, model);
|
||||
return dumpExtract(av, options);
|
||||
} catch (final IOException e) {
|
||||
throw new ExtractException(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private SubtitleCollection<Subtitle> dumpExtract(final AudioOrVideo av, final Language language, final ExtractionModel model) throws ExtractException, IOException {
|
||||
private SubtitleCollection<Subtitle> dumpExtract(final AudioOrVideo av, final ExtractOptions options) throws ExtractException, IOException {
|
||||
final var path = Files.createTempFile(AUTOSUBTITLE, "." + av.info().format());
|
||||
try (final var in = av.getInputStream()) {
|
||||
Files.copy(in, path, StandardCopyOption.REPLACE_EXISTING);
|
||||
return extract(path, language, model, av.info().duration());
|
||||
return extract(path, options, av.info().duration());
|
||||
} finally {
|
||||
Files.deleteIfExists(path);
|
||||
}
|
||||
}
|
||||
|
||||
private SubtitleCollection<Subtitle> extract(final Path path, final Language language, final ExtractionModel model, final long duration) throws ExtractException {
|
||||
private SubtitleCollection<Subtitle> extract(final Path path, final ExtractOptions options, final long duration) throws ExtractException {
|
||||
try {
|
||||
final var outputDir = Files.createTempDirectory(AUTOSUBTITLE);
|
||||
final var args = createArgs(path, language, model, outputDir);
|
||||
final var args = createArgs(path, options, outputDir);
|
||||
final var processListener = processRunner.startListen(args);
|
||||
var oldProgress = -1.0;
|
||||
var line = processListener.readLine();
|
||||
@@ -129,7 +128,7 @@ public abstract class AbstractWhisperSubtitleExtractor implements SubtitleExtrac
|
||||
final var filename = path.getFileName().toString();
|
||||
final var subtitleFilename = filename.substring(0, filename.lastIndexOf('.')) + ".json";
|
||||
final var subtitleFile = outputDir.resolve(subtitleFilename);
|
||||
return parseResult(subtitleFile);
|
||||
return parseResult(subtitleFile, options);
|
||||
} else {
|
||||
throw new ExtractException("Error extracting subtitles: " + result.output());
|
||||
}
|
||||
@@ -138,9 +137,9 @@ public abstract class AbstractWhisperSubtitleExtractor implements SubtitleExtrac
|
||||
}
|
||||
}
|
||||
|
||||
private SubtitleCollection<Subtitle> parseResult(final Path subtitleFile) throws ExtractException {
|
||||
private SubtitleCollection<Subtitle> parseResult(final Path subtitleFile, final ExtractOptions options) throws ExtractException {
|
||||
try {
|
||||
return converter.parse(subtitleFile);
|
||||
return converter.parse(subtitleFile, options.parseOptions());
|
||||
} catch (final ParseException e) {
|
||||
throw new ExtractException(e);
|
||||
}
|
||||
@@ -175,12 +174,11 @@ public abstract class AbstractWhisperSubtitleExtractor implements SubtitleExtrac
|
||||
* Creates the command line arguments for Whisper
|
||||
*
|
||||
* @param path the path to the file
|
||||
* @param language the language
|
||||
* @param model the model
|
||||
* @param options the extraction options
|
||||
* @param outputDir the output directory
|
||||
* @return the list of arguments
|
||||
*/
|
||||
protected abstract List<String> createArgs(final Path path, final Language language, final ExtractionModel model, final Path outputDir);
|
||||
protected abstract List<String> createArgs(final Path path, final ExtractOptions options, final Path outputDir);
|
||||
|
||||
/**
|
||||
* @return the path to the python executable
|
||||
|
||||
@@ -5,7 +5,6 @@ module com.github.gtache.autosubtitle.whisper.common {
|
||||
requires transitive com.github.gtache.autosubtitle.conda;
|
||||
requires transitive java.net.http;
|
||||
requires org.apache.logging.log4j;
|
||||
requires transitive com.google.gson;
|
||||
requires transitive java.compiler; //Don't know why dagger generates @Generated here, need to debug
|
||||
|
||||
exports com.github.gtache.autosubtitle.whisper;
|
||||
|
||||
@@ -2,7 +2,6 @@ package com.github.gtache.autosubtitle.subtitle.extractor.whisper;
|
||||
|
||||
import com.github.gtache.autosubtitle.Audio;
|
||||
import com.github.gtache.autosubtitle.AudioInfo;
|
||||
import com.github.gtache.autosubtitle.Language;
|
||||
import com.github.gtache.autosubtitle.Video;
|
||||
import com.github.gtache.autosubtitle.VideoInfo;
|
||||
import com.github.gtache.autosubtitle.impl.FileAudioImpl;
|
||||
@@ -13,11 +12,12 @@ import com.github.gtache.autosubtitle.process.ProcessRunner;
|
||||
import com.github.gtache.autosubtitle.subtitle.Subtitle;
|
||||
import com.github.gtache.autosubtitle.subtitle.SubtitleCollection;
|
||||
import com.github.gtache.autosubtitle.subtitle.converter.ParseException;
|
||||
import com.github.gtache.autosubtitle.subtitle.converter.ParseOptions;
|
||||
import com.github.gtache.autosubtitle.subtitle.converter.SubtitleConverter;
|
||||
import com.github.gtache.autosubtitle.subtitle.converter.SubtitleConverterProvider;
|
||||
import com.github.gtache.autosubtitle.subtitle.extractor.ExtractEvent;
|
||||
import com.github.gtache.autosubtitle.subtitle.extractor.ExtractException;
|
||||
import com.github.gtache.autosubtitle.subtitle.extractor.ExtractionModel;
|
||||
import com.github.gtache.autosubtitle.subtitle.extractor.ExtractOptions;
|
||||
import com.github.gtache.autosubtitle.subtitle.extractor.SubtitleExtractorListener;
|
||||
import com.github.gtache.autosubtitle.subtitle.extractor.impl.ExtractEventImpl;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
@@ -52,15 +52,16 @@ class TestAbstractWhisperSubtitleExtractor {
|
||||
|
||||
private final AudioInfo audioInfo;
|
||||
private final VideoInfo videoInfo;
|
||||
private final ExtractionModel extractionModel;
|
||||
private final ExtractOptions options;
|
||||
private final ParseOptions parseOptions;
|
||||
private final SubtitleCollection<Subtitle> collection;
|
||||
|
||||
|
||||
TestAbstractWhisperSubtitleExtractor(@Mock final SubtitleConverterProvider converterProvider, @Mock final SubtitleConverter<Subtitle> converter,
|
||||
@Mock final ProcessRunner processRunner, @Mock final ProcessListener processListener,
|
||||
@Mock final ProcessResult processResult, @Mock final VideoInfo videoInfo,
|
||||
@Mock final AudioInfo audioInfo, @Mock final ExtractionModel extractionModel,
|
||||
@Mock final SubtitleCollection<Subtitle> collection) {
|
||||
@Mock final AudioInfo audioInfo, @Mock final ExtractOptions options,
|
||||
@Mock final ParseOptions parseOptions, @Mock final SubtitleCollection<Subtitle> collection) {
|
||||
this.venvPath = Path.of("venv");
|
||||
this.os = OS.LINUX;
|
||||
this.converterProvider = Objects.requireNonNull(converterProvider);
|
||||
@@ -70,7 +71,8 @@ class TestAbstractWhisperSubtitleExtractor {
|
||||
this.processResult = Objects.requireNonNull(processResult);
|
||||
this.audioInfo = Objects.requireNonNull(audioInfo);
|
||||
this.videoInfo = Objects.requireNonNull(videoInfo);
|
||||
this.extractionModel = Objects.requireNonNull(extractionModel);
|
||||
this.options = Objects.requireNonNull(options);
|
||||
this.parseOptions = Objects.requireNonNull(parseOptions);
|
||||
this.collection = Objects.requireNonNull(collection);
|
||||
}
|
||||
|
||||
@@ -81,6 +83,7 @@ class TestAbstractWhisperSubtitleExtractor {
|
||||
when(processListener.join(Duration.ofHours(1))).thenReturn(processResult);
|
||||
when(audioInfo.format()).thenReturn("mp3");
|
||||
when(videoInfo.format()).thenReturn("mp4");
|
||||
when(options.parseOptions()).thenReturn(parseOptions);
|
||||
this.extractor = new DummyWhisperSubtitleExtractor(venvPath, converterProvider, processRunner, os);
|
||||
}
|
||||
|
||||
@@ -126,7 +129,7 @@ class TestAbstractWhisperSubtitleExtractor {
|
||||
final var audio = mock(Audio.class);
|
||||
when(audio.info()).thenReturn(audioInfo);
|
||||
when(audio.getInputStream()).thenThrow(IOException.class);
|
||||
assertThrows(ExtractException.class, () -> extractor.extract(audio, Language.EN, extractionModel));
|
||||
assertThrows(ExtractException.class, () -> extractor.extract(audio, options));
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -134,16 +137,16 @@ class TestAbstractWhisperSubtitleExtractor {
|
||||
final var path = Paths.get("path");
|
||||
final var audio = new FileAudioImpl(path, audioInfo);
|
||||
doThrow(IOException.class).when(processListener).readLine();
|
||||
assertThrows(ExtractException.class, () -> extractor.extract(audio, Language.EN, extractionModel));
|
||||
assertThrows(ExtractException.class, () -> extractor.extract(audio, options));
|
||||
}
|
||||
|
||||
@Test
|
||||
void testExtractAudioFileParseException() throws ParseException {
|
||||
final var path = Paths.get("path.path");
|
||||
final var audio = new FileAudioImpl(path, audioInfo);
|
||||
doThrow(ParseException.class).when(converter).parse(any(Path.class));
|
||||
assertThrows(ExtractException.class, () -> extractor.extract(audio, Language.EN, extractionModel));
|
||||
verify(converter).parse(any(Path.class));
|
||||
doThrow(ParseException.class).when(converter).parse(any(Path.class), eq(parseOptions));
|
||||
assertThrows(ExtractException.class, () -> extractor.extract(audio, options));
|
||||
verify(converter).parse(any(Path.class), eq(parseOptions));
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -151,7 +154,7 @@ class TestAbstractWhisperSubtitleExtractor {
|
||||
final var path = Paths.get("path");
|
||||
final var audio = new FileAudioImpl(path, audioInfo);
|
||||
when(processResult.exitCode()).thenReturn(1);
|
||||
assertThrows(ExtractException.class, () -> extractor.extract(audio, Language.EN, extractionModel));
|
||||
assertThrows(ExtractException.class, () -> extractor.extract(audio, options));
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -159,7 +162,7 @@ class TestAbstractWhisperSubtitleExtractor {
|
||||
final var video = mock(Video.class);
|
||||
when(video.info()).thenReturn(videoInfo);
|
||||
when(video.getInputStream()).thenThrow(IOException.class);
|
||||
assertThrows(ExtractException.class, () -> extractor.extract(video, Language.EN, extractionModel));
|
||||
assertThrows(ExtractException.class, () -> extractor.extract(video, options));
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -168,8 +171,8 @@ class TestAbstractWhisperSubtitleExtractor {
|
||||
when(video.info()).thenReturn(videoInfo);
|
||||
final var in = new ByteArrayInputStream("test".getBytes());
|
||||
when(video.getInputStream()).thenReturn(in);
|
||||
when(converter.parse(any(Path.class))).thenReturn(collection);
|
||||
assertEquals(collection, extractor.extract(video, Language.EN, extractionModel));
|
||||
when(converter.parse(any(Path.class), eq(parseOptions))).thenReturn(collection);
|
||||
assertEquals(collection, extractor.extract(video, options));
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -179,11 +182,11 @@ class TestAbstractWhisperSubtitleExtractor {
|
||||
when(videoInfo.duration()).thenReturn(100000L);
|
||||
final var in = new ByteArrayInputStream("test".getBytes());
|
||||
when(video.getInputStream()).thenReturn(in);
|
||||
when(converter.parse(any(Path.class))).thenReturn(collection);
|
||||
when(converter.parse(any(Path.class), eq(parseOptions))).thenReturn(collection);
|
||||
when(processListener.readLine()).thenReturn("Progress: 1.7abcd", "[00:12.234 --> 00:13.234] Hello", "98%|bbb", "abcd", null);
|
||||
final var listener = mock(SubtitleExtractorListener.class);
|
||||
extractor.addListener(listener);
|
||||
assertEquals(collection, extractor.extract(video, Language.EN, extractionModel));
|
||||
assertEquals(collection, extractor.extract(video, options));
|
||||
verify(listener).listen(new ExtractEventImpl("Progress: 1.7abcd", 0.017));
|
||||
verify(listener).listen(new ExtractEventImpl("[00:12.234 --> 00:13.234] Hello", 0.13234));
|
||||
verify(listener).listen(new ExtractEventImpl("98%|bbb", 0.98));
|
||||
@@ -208,8 +211,8 @@ class TestAbstractWhisperSubtitleExtractor {
|
||||
}
|
||||
|
||||
@Override
|
||||
protected List<String> createArgs(final Path path, final Language language, final ExtractionModel model, final Path outputDir) {
|
||||
return List.of(path.toString(), language.toString(), model.toString(), outputDir.toString());
|
||||
protected List<String> createArgs(final Path path, final ExtractOptions options, final Path outputDir) {
|
||||
return List.of(path.toString(), options.toString(), outputDir.toString());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user