Adds WhisperX, reworks UI (still needs some work), theoretically usable
This commit is contained in:
@@ -1,17 +1,31 @@
|
||||
package com.github.gtache.autosubtitle.setup.ffmpeg;
|
||||
package com.github.gtache.autosubtitle.archive.ffmpeg;
|
||||
|
||||
import org.apache.commons.compress.archivers.tar.TarArchiveEntry;
|
||||
import com.github.gtache.autosubtitle.archive.Archiver;
|
||||
import org.apache.commons.compress.archivers.ArchiveEntry;
|
||||
import org.apache.commons.compress.archivers.tar.TarArchiveInputStream;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Tar implementation of {@link Decompresser}
|
||||
* Tar implementation of {@link Archiver}
|
||||
*/
|
||||
public class TarDecompresser implements Decompresser {
|
||||
public class TarArchiver implements Archiver {
|
||||
|
||||
@Inject
|
||||
TarArchiver() {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void compress(final List<Path> files, final Path destination) throws IOException {
|
||||
throw new UnsupportedOperationException("Not implemented yet");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void decompress(final Path archive, final Path destination) throws IOException {
|
||||
if (!isPathSupported(archive)) {
|
||||
@@ -38,7 +52,7 @@ public class TarDecompresser implements Decompresser {
|
||||
}
|
||||
}
|
||||
|
||||
private static Path newFile(final Path destinationDir, final TarArchiveEntry entry) throws IOException {
|
||||
private static Path newFile(final Path destinationDir, final ArchiveEntry entry) throws IOException {
|
||||
final var destPath = destinationDir.resolve(entry.getName());
|
||||
|
||||
final var destDirPath = destinationDir.toAbsolutePath().toString();
|
||||
@@ -51,7 +65,7 @@ public class TarDecompresser implements Decompresser {
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isPathSupported(final Path path) {
|
||||
return path.getFileName().toString().endsWith(".tar");
|
||||
public String archiveExtension() {
|
||||
return "tar";
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,45 @@
|
||||
package com.github.gtache.autosubtitle.archive.ffmpeg;
|
||||
|
||||
import com.github.gtache.autosubtitle.archive.Archiver;
|
||||
import org.tukaani.xz.XZInputStream;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import java.io.IOException;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* XZ implementation of {@link Archiver}
|
||||
*/
|
||||
public class XZArchiver implements Archiver {
|
||||
|
||||
@Inject
|
||||
XZArchiver() {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void compress(final List<Path> files, final Path destination) throws IOException {
|
||||
throw new UnsupportedOperationException("Not implemented");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void decompress(final Path archive, final Path destination) throws IOException {
|
||||
if (!isPathSupported(archive)) {
|
||||
throw new IllegalArgumentException("Unsupported path : " + archive);
|
||||
}
|
||||
final var archiveName = archive.getFileName().toString();
|
||||
Files.createDirectories(destination);
|
||||
final var destinationFile = destination.resolve(archiveName.substring(0, archiveName.lastIndexOf(".xz")));
|
||||
try (final var xzIn = new XZInputStream(Files.newInputStream(archive));
|
||||
final var out = Files.newOutputStream(destinationFile)) {
|
||||
xzIn.transferTo(out);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String archiveExtension() {
|
||||
return "xz";
|
||||
}
|
||||
}
|
||||
@@ -8,17 +8,17 @@ import com.github.gtache.autosubtitle.impl.AudioInfoImpl;
|
||||
import com.github.gtache.autosubtitle.impl.FileAudioImpl;
|
||||
import com.github.gtache.autosubtitle.impl.FileVideoImpl;
|
||||
import com.github.gtache.autosubtitle.impl.VideoInfoImpl;
|
||||
import com.github.gtache.autosubtitle.modules.ffmpeg.FFmpegBundledPath;
|
||||
import com.github.gtache.autosubtitle.modules.ffmpeg.FFmpegSystemPath;
|
||||
import com.github.gtache.autosubtitle.modules.setup.ffmpeg.FFmpegBundledPath;
|
||||
import com.github.gtache.autosubtitle.modules.setup.ffmpeg.FFmpegSystemPath;
|
||||
import com.github.gtache.autosubtitle.process.impl.AbstractProcessRunner;
|
||||
import com.github.gtache.autosubtitle.subtitle.SubtitleCollection;
|
||||
import com.github.gtache.autosubtitle.subtitle.converter.SubtitleConverter;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import javax.inject.Singleton;
|
||||
import java.io.IOException;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.time.Duration;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.LinkedHashMap;
|
||||
@@ -32,30 +32,29 @@ import static java.util.Objects.requireNonNull;
|
||||
/**
|
||||
* FFmpeg implementation of {@link VideoConverter}
|
||||
*/
|
||||
@Singleton
|
||||
public class FFmpegVideoConverter extends AbstractProcessRunner implements VideoConverter {
|
||||
|
||||
private static final String TEMP_FILE_PREFIX = "autosubtitle";
|
||||
private final Path bundledPath;
|
||||
private final Path systemPath;
|
||||
private final SubtitleConverter subtitleConverter;
|
||||
private final SubtitleConverter<?> subtitleConverter;
|
||||
|
||||
@Inject
|
||||
FFmpegVideoConverter(@FFmpegBundledPath final Path bundledPath, @FFmpegSystemPath final Path systemPath, final Map<String, SubtitleConverter> subtitleConverters) {
|
||||
this.bundledPath = requireNonNull(bundledPath);
|
||||
this.systemPath = requireNonNull(systemPath);
|
||||
this.subtitleConverter = requireNonNull(subtitleConverters.get("srt"));
|
||||
this.subtitleConverter = subtitleConverters.get("srt");
|
||||
}
|
||||
|
||||
@Override
|
||||
public Video addSoftSubtitles(final Video video, final Collection<SubtitleCollection> subtitles) throws IOException {
|
||||
final var out = getTempFile("mkv"); //Soft ass subtitles are only supported by mkv apparently
|
||||
public Video addSoftSubtitles(final Video video, final Collection<? extends SubtitleCollection<?>> subtitles) throws IOException {
|
||||
final var out = getTempFile(video.info().videoFormat());
|
||||
addSoftSubtitles(video, subtitles, out);
|
||||
return new FileVideoImpl(out, new VideoInfoImpl("mkv", video.info().width(), video.info().height(), video.info().duration()));
|
||||
return new FileVideoImpl(out, new VideoInfoImpl(video.info().videoFormat(), video.info().width(), video.info().height(), video.info().duration()));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addSoftSubtitles(final Video video, final Collection<SubtitleCollection> subtitles, final Path path) throws IOException {
|
||||
public void addSoftSubtitles(final Video video, final Collection<? extends SubtitleCollection<?>> subtitles, final Path path) throws IOException {
|
||||
final var videoPath = getPath(video);
|
||||
final var collectionMap = dumpCollections(subtitles);
|
||||
final var args = new ArrayList<String>();
|
||||
@@ -96,18 +95,18 @@ public class FFmpegVideoConverter extends AbstractProcessRunner implements Video
|
||||
args.add("language=" + c.language().iso3());
|
||||
});
|
||||
args.add(path.toString());
|
||||
runListen(args);
|
||||
runListen(args, Duration.ofHours(1));
|
||||
}
|
||||
|
||||
@Override
|
||||
public Video addHardSubtitles(final Video video, final SubtitleCollection subtitles) throws IOException {
|
||||
public Video addHardSubtitles(final Video video, final SubtitleCollection<?> subtitles) throws IOException {
|
||||
final var out = getTempFile(video.info().videoFormat());
|
||||
addHardSubtitles(video, subtitles, out);
|
||||
return new FileVideoImpl(out, video.info());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addHardSubtitles(final Video video, final SubtitleCollection subtitles, final Path path) throws IOException {
|
||||
public void addHardSubtitles(final Video video, final SubtitleCollection<?> subtitles, final Path path) throws IOException {
|
||||
final var videoPath = getPath(video);
|
||||
final var subtitlesPath = dumpSubtitles(subtitles);
|
||||
final var escapedPath = escapeVF(subtitlesPath.toString());
|
||||
@@ -120,7 +119,7 @@ public class FFmpegVideoConverter extends AbstractProcessRunner implements Video
|
||||
subtitleArg,
|
||||
path.toString()
|
||||
);
|
||||
runListen(args);
|
||||
runListen(args, Duration.ofHours(1));
|
||||
}
|
||||
|
||||
private static String escapeVF(final String path) {
|
||||
@@ -145,7 +144,7 @@ public class FFmpegVideoConverter extends AbstractProcessRunner implements Video
|
||||
"0:v",
|
||||
dumpVideoPath.toString()
|
||||
);
|
||||
runListen(args);
|
||||
runListen(args, Duration.ofHours(1));
|
||||
Files.deleteIfExists(dumpVideoPath);
|
||||
return new FileAudioImpl(audioPath, new AudioInfoImpl("wav", video.info().duration()));
|
||||
}
|
||||
@@ -166,15 +165,15 @@ public class FFmpegVideoConverter extends AbstractProcessRunner implements Video
|
||||
return path;
|
||||
}
|
||||
|
||||
private SequencedMap<SubtitleCollection, Path> dumpCollections(final Collection<SubtitleCollection> collections) throws IOException {
|
||||
final var ret = LinkedHashMap.<SubtitleCollection, Path>newLinkedHashMap(collections.size());
|
||||
private <T extends SubtitleCollection<?>> SequencedMap<T, Path> dumpCollections(final Collection<T> collections) throws IOException {
|
||||
final var ret = LinkedHashMap.<T, Path>newLinkedHashMap(collections.size());
|
||||
for (final var subtitles : collections) {
|
||||
ret.put(subtitles, dumpSubtitles(subtitles));
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
private Path dumpSubtitles(final SubtitleCollection subtitles) throws IOException {
|
||||
private Path dumpSubtitles(final SubtitleCollection<?> subtitles) throws IOException {
|
||||
final var path = getTempFile("srt");
|
||||
Files.writeString(path, subtitleConverter.format(subtitles));
|
||||
return path;
|
||||
|
||||
@@ -4,22 +4,22 @@ import com.github.gtache.autosubtitle.Video;
|
||||
import com.github.gtache.autosubtitle.VideoLoader;
|
||||
import com.github.gtache.autosubtitle.impl.FileVideoImpl;
|
||||
import com.github.gtache.autosubtitle.impl.VideoInfoImpl;
|
||||
import com.github.gtache.autosubtitle.modules.ffmpeg.FFprobeBundledPath;
|
||||
import com.github.gtache.autosubtitle.modules.ffmpeg.FFprobeSystemPath;
|
||||
import com.github.gtache.autosubtitle.modules.setup.ffmpeg.FFprobeBundledPath;
|
||||
import com.github.gtache.autosubtitle.modules.setup.ffmpeg.FFprobeSystemPath;
|
||||
import com.github.gtache.autosubtitle.process.impl.AbstractProcessRunner;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import javax.inject.Singleton;
|
||||
import java.io.IOException;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.time.Duration;
|
||||
import java.util.List;
|
||||
|
||||
import static java.util.Objects.requireNonNull;
|
||||
|
||||
/**
|
||||
* FFprobe implementation of {@link VideoLoader}
|
||||
*/
|
||||
@Singleton
|
||||
public class FFprobeVideoLoader extends AbstractProcessRunner implements VideoLoader {
|
||||
|
||||
private final Path bundledPath;
|
||||
@@ -33,7 +33,7 @@ public class FFprobeVideoLoader extends AbstractProcessRunner implements VideoLo
|
||||
|
||||
@Override
|
||||
public Video loadVideo(final Path path) throws IOException {
|
||||
final var result = run(getFFprobePath(), "-v", "error", "-select_streams", "v", "-show_entries", "stream=width,height,duration", "-of", "csv=p=0", path.toString());
|
||||
final var result = run(List.of(getFFprobePath(), "-v", "error", "-select_streams", "v", "-show_entries", "stream=width,height,duration", "-of", "csv=p=0", path.toString()), Duration.ofSeconds(5));
|
||||
final var resolution = result.output().getLast();
|
||||
final var split = resolution.split(",");
|
||||
final var width = Integer.parseInt(split[0]);
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
package com.github.gtache.autosubtitle.modules.ffmpeg;
|
||||
package com.github.gtache.autosubtitle.modules.setup.ffmpeg;
|
||||
|
||||
import javax.inject.Qualifier;
|
||||
import java.lang.annotation.Documented;
|
||||
@@ -1,4 +1,4 @@
|
||||
package com.github.gtache.autosubtitle.modules.ffmpeg;
|
||||
package com.github.gtache.autosubtitle.modules.setup.ffmpeg;
|
||||
|
||||
import javax.inject.Qualifier;
|
||||
import java.lang.annotation.Documented;
|
||||
@@ -1,4 +1,4 @@
|
||||
package com.github.gtache.autosubtitle.modules.ffmpeg;
|
||||
package com.github.gtache.autosubtitle.modules.setup.ffmpeg;
|
||||
|
||||
import javax.inject.Qualifier;
|
||||
import java.lang.annotation.Documented;
|
||||
@@ -1,4 +1,4 @@
|
||||
package com.github.gtache.autosubtitle.modules.ffmpeg;
|
||||
package com.github.gtache.autosubtitle.modules.setup.ffmpeg;
|
||||
|
||||
import javax.inject.Qualifier;
|
||||
import java.lang.annotation.Documented;
|
||||
@@ -1,24 +1,17 @@
|
||||
package com.github.gtache.autosubtitle.modules.setup.ffmpeg;
|
||||
|
||||
import com.github.gtache.autosubtitle.archive.Archiver;
|
||||
import com.github.gtache.autosubtitle.archive.ffmpeg.TarArchiver;
|
||||
import com.github.gtache.autosubtitle.archive.ffmpeg.XZArchiver;
|
||||
import com.github.gtache.autosubtitle.impl.Architecture;
|
||||
import com.github.gtache.autosubtitle.impl.OS;
|
||||
import com.github.gtache.autosubtitle.modules.ffmpeg.FFBundledRoot;
|
||||
import com.github.gtache.autosubtitle.modules.ffmpeg.FFProbeInstallerPath;
|
||||
import com.github.gtache.autosubtitle.modules.ffmpeg.FFmpegBundledPath;
|
||||
import com.github.gtache.autosubtitle.modules.ffmpeg.FFmpegInstallerPath;
|
||||
import com.github.gtache.autosubtitle.modules.ffmpeg.FFmpegSystemPath;
|
||||
import com.github.gtache.autosubtitle.modules.ffmpeg.FFmpegVersion;
|
||||
import com.github.gtache.autosubtitle.modules.ffmpeg.FFprobeBundledPath;
|
||||
import com.github.gtache.autosubtitle.modules.ffmpeg.FFprobeSystemPath;
|
||||
import com.github.gtache.autosubtitle.modules.impl.ExecutableExtension;
|
||||
import com.github.gtache.autosubtitle.modules.setup.impl.CacheRoot;
|
||||
import com.github.gtache.autosubtitle.modules.setup.impl.ToolsRoot;
|
||||
import com.github.gtache.autosubtitle.modules.setup.impl.VideoConverterSetup;
|
||||
import com.github.gtache.autosubtitle.setup.SetupManager;
|
||||
import com.github.gtache.autosubtitle.setup.ffmpeg.Decompresser;
|
||||
import com.github.gtache.autosubtitle.setup.ffmpeg.FFmpegSetupConfiguration;
|
||||
import com.github.gtache.autosubtitle.setup.ffmpeg.FFmpegSetupManager;
|
||||
import com.github.gtache.autosubtitle.setup.ffmpeg.TarDecompresser;
|
||||
import com.github.gtache.autosubtitle.setup.ffmpeg.XZDecompresser;
|
||||
import com.github.gtache.autosubtitle.setup.ffmpeg.ZipDecompresser;
|
||||
import dagger.Binds;
|
||||
import dagger.Module;
|
||||
import dagger.Provides;
|
||||
@@ -41,20 +34,16 @@ public abstract class FFmpegSetupModule {
|
||||
|
||||
}
|
||||
|
||||
@Binds
|
||||
@StringKey("zip")
|
||||
@IntoMap
|
||||
abstract Decompresser bindsZipDecompresser(final ZipDecompresser decompresser);
|
||||
|
||||
@Binds
|
||||
@StringKey("tar")
|
||||
@IntoMap
|
||||
abstract Decompresser bindsTarDecompresser(final TarDecompresser decompresser);
|
||||
abstract Archiver bindsTarDecompresser(final TarArchiver decompresser);
|
||||
|
||||
@Binds
|
||||
@StringKey("xz")
|
||||
@IntoMap
|
||||
abstract Decompresser bindsXzDecompresser(final XZDecompresser decompresser);
|
||||
abstract Archiver bindsXZDecompresser(final XZArchiver decompresser);
|
||||
|
||||
@Binds
|
||||
@VideoConverterSetup
|
||||
@@ -69,19 +58,19 @@ public abstract class FFmpegSetupModule {
|
||||
|
||||
@Provides
|
||||
@FFmpegInstallerPath
|
||||
static Path providesFFmpegInstallerPath(@FFBundledRoot final Path root, final OS os) {
|
||||
return root.resolve("cache").resolve("ffmpeg-installer" + getInstallerExtension(os));
|
||||
static Path providesFFmpegInstallerPath(@CacheRoot final Path root, final OS os) {
|
||||
return root.resolve(FFMPEG + "-installer" + getInstallerExtension(os));
|
||||
}
|
||||
|
||||
@Provides
|
||||
@FFProbeInstallerPath
|
||||
static Path providesFFProbeInstallerPath(@FFBundledRoot final Path root, final OS os) {
|
||||
return root.resolve("cache").resolve("ffprobe-installer" + getInstallerExtension(os));
|
||||
static Path providesFFProbeInstallerPath(@CacheRoot final Path root, final OS os) {
|
||||
return root.resolve(FFPROBE + "-installer" + getInstallerExtension(os));
|
||||
}
|
||||
|
||||
private static String getInstallerExtension(final OS os) {
|
||||
if (os == OS.LINUX) {
|
||||
return ".tar.gz";
|
||||
return ".tar.xz";
|
||||
} else {
|
||||
return ".zip";
|
||||
}
|
||||
@@ -89,8 +78,8 @@ public abstract class FFmpegSetupModule {
|
||||
|
||||
@Provides
|
||||
@FFBundledRoot
|
||||
static Path providesFFBundledRoot() {
|
||||
return Paths.get("tools", FFMPEG);
|
||||
static Path providesFFBundledRoot(@ToolsRoot final Path root) {
|
||||
return root.resolve(FFMPEG);
|
||||
}
|
||||
|
||||
@Provides
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
package com.github.gtache.autosubtitle.modules.ffmpeg;
|
||||
package com.github.gtache.autosubtitle.modules.setup.ffmpeg;
|
||||
|
||||
import javax.inject.Qualifier;
|
||||
import java.lang.annotation.Documented;
|
||||
@@ -1,4 +1,4 @@
|
||||
package com.github.gtache.autosubtitle.modules.ffmpeg;
|
||||
package com.github.gtache.autosubtitle.modules.setup.ffmpeg;
|
||||
|
||||
import javax.inject.Qualifier;
|
||||
import java.lang.annotation.Documented;
|
||||
@@ -1,4 +1,4 @@
|
||||
package com.github.gtache.autosubtitle.modules.ffmpeg;
|
||||
package com.github.gtache.autosubtitle.modules.setup.ffmpeg;
|
||||
|
||||
import javax.inject.Qualifier;
|
||||
import java.lang.annotation.Documented;
|
||||
@@ -1,4 +1,4 @@
|
||||
package com.github.gtache.autosubtitle.modules.ffmpeg;
|
||||
package com.github.gtache.autosubtitle.modules.setup.ffmpeg;
|
||||
|
||||
import javax.inject.Qualifier;
|
||||
import java.lang.annotation.Documented;
|
||||
@@ -1,27 +0,0 @@
|
||||
package com.github.gtache.autosubtitle.setup.ffmpeg;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.nio.file.Path;
|
||||
|
||||
/**
|
||||
* Unzips files
|
||||
*/
|
||||
public interface Decompresser {
|
||||
|
||||
/**
|
||||
* Unzips an archive to the given destination
|
||||
*
|
||||
* @param archive The archive
|
||||
* @param destination The destination folder
|
||||
* @throws IOException if an error occurs
|
||||
*/
|
||||
void decompress(final Path archive, final Path destination) throws IOException;
|
||||
|
||||
/**
|
||||
* Checks whether the given file is supported by the decompresser
|
||||
*
|
||||
* @param path The file path
|
||||
* @return True if the file is supported
|
||||
*/
|
||||
boolean isPathSupported(final Path path);
|
||||
}
|
||||
@@ -1,5 +1,6 @@
|
||||
package com.github.gtache.autosubtitle.setup.ffmpeg;
|
||||
|
||||
import com.github.gtache.autosubtitle.archive.Archiver;
|
||||
import com.github.gtache.autosubtitle.impl.Architecture;
|
||||
import com.github.gtache.autosubtitle.setup.SetupException;
|
||||
import com.github.gtache.autosubtitle.setup.SetupManager;
|
||||
@@ -13,6 +14,8 @@ import java.io.IOException;
|
||||
import java.net.http.HttpClient;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.time.Duration;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import static com.github.gtache.autosubtitle.impl.Architecture.ARMEL;
|
||||
@@ -26,14 +29,14 @@ import static java.util.Objects.requireNonNull;
|
||||
public class FFmpegSetupManager extends AbstractSetupManager {
|
||||
private static final Logger logger = LogManager.getLogger(FFmpegSetupManager.class);
|
||||
private final FFmpegSetupConfiguration configuration;
|
||||
private final Map<String, Decompresser> decompressers;
|
||||
private final Map<String, Archiver> archivers;
|
||||
|
||||
@Inject
|
||||
FFmpegSetupManager(final FFmpegSetupConfiguration configuration, final Map<String, Decompresser> decompressers,
|
||||
FFmpegSetupManager(final FFmpegSetupConfiguration configuration, final Map<String, Archiver> archivers,
|
||||
final HttpClient httpClient) {
|
||||
super(httpClient);
|
||||
this.configuration = requireNonNull(configuration);
|
||||
this.decompressers = Map.copyOf(decompressers);
|
||||
this.archivers = Map.copyOf(archivers);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -132,7 +135,7 @@ public class FFmpegSetupManager extends AbstractSetupManager {
|
||||
try {
|
||||
final var filename = from.getFileName().toString();
|
||||
final var extension = filename.substring(filename.lastIndexOf('.') + 1);
|
||||
decompressers.get(extension).decompress(from, to);
|
||||
archivers.get(extension).decompress(from, to);
|
||||
} catch (final IOException e) {
|
||||
throw new SetupException(e);
|
||||
}
|
||||
@@ -188,7 +191,7 @@ public class FFmpegSetupManager extends AbstractSetupManager {
|
||||
}
|
||||
|
||||
private boolean checkSystemFFmpeg() throws IOException {
|
||||
final var result = run(configuration.systemFFmpegPath().toString(), "-version");
|
||||
final var result = run(List.of(configuration.systemFFmpegPath().toString(), "-version"), Duration.ofSeconds(5));
|
||||
return result.exitCode() == 0;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,28 +0,0 @@
|
||||
package com.github.gtache.autosubtitle.setup.ffmpeg;
|
||||
|
||||
import org.tukaani.xz.XZInputStream;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
|
||||
/**
|
||||
* XZ implementation of {@link Decompresser}
|
||||
*/
|
||||
public class XZDecompresser implements Decompresser {
|
||||
@Override
|
||||
public void decompress(final Path archive, final Path destination) throws IOException {
|
||||
if (!isPathSupported(archive)) {
|
||||
throw new IllegalArgumentException("Unsupported path : " + archive);
|
||||
}
|
||||
try (final var xzIn = new XZInputStream(Files.newInputStream(archive));
|
||||
final var out = Files.newOutputStream(destination)) {
|
||||
xzIn.transferTo(out);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isPathSupported(final Path path) {
|
||||
return path.getFileName().toString().endsWith(".xz");
|
||||
}
|
||||
}
|
||||
@@ -1,57 +0,0 @@
|
||||
package com.github.gtache.autosubtitle.setup.ffmpeg;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.util.zip.ZipEntry;
|
||||
import java.util.zip.ZipInputStream;
|
||||
|
||||
/**
|
||||
* Zip implementation of {@link Decompresser}
|
||||
*/
|
||||
public class ZipDecompresser implements Decompresser {
|
||||
@Override
|
||||
public void decompress(final Path archive, final Path destination) throws IOException {
|
||||
if (!isPathSupported(archive)) {
|
||||
throw new IllegalArgumentException("Unsupported path : " + archive);
|
||||
}
|
||||
try (final var zis = new ZipInputStream(Files.newInputStream(archive))) {
|
||||
var zipEntry = zis.getNextEntry();
|
||||
while (zipEntry != null) {
|
||||
final var newFile = newFile(destination, zipEntry);
|
||||
if (zipEntry.isDirectory()) {
|
||||
Files.createDirectories(newFile);
|
||||
} else {
|
||||
// fix for Windows-created archives
|
||||
final var parent = newFile.getParent();
|
||||
Files.createDirectories(parent);
|
||||
|
||||
// write file content
|
||||
try (final var fos = Files.newOutputStream(newFile)) {
|
||||
zis.transferTo(fos);
|
||||
}
|
||||
}
|
||||
zipEntry = zis.getNextEntry();
|
||||
}
|
||||
zis.closeEntry();
|
||||
}
|
||||
}
|
||||
|
||||
private static Path newFile(final Path destinationDir, final ZipEntry zipEntry) throws IOException {
|
||||
final var destPath = destinationDir.resolve(zipEntry.getName());
|
||||
|
||||
final var destDirPath = destinationDir.toAbsolutePath().toString();
|
||||
final var destFilePath = destPath.toAbsolutePath().toString();
|
||||
|
||||
if (!destFilePath.startsWith(destDirPath + File.separator)) {
|
||||
throw new IOException("Entry is outside of the target dir: " + zipEntry.getName());
|
||||
}
|
||||
return destPath;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isPathSupported(final Path path) {
|
||||
return path.getFileName().toString().endsWith(".zip");
|
||||
}
|
||||
}
|
||||
@@ -15,4 +15,5 @@ module com.github.gtache.autosubtitle.ffmpeg {
|
||||
|
||||
exports com.github.gtache.autosubtitle.modules.ffmpeg;
|
||||
exports com.github.gtache.autosubtitle.modules.setup.ffmpeg;
|
||||
exports com.github.gtache.autosubtitle.archive.ffmpeg;
|
||||
}
|
||||
@@ -0,0 +1,56 @@
|
||||
package com.github.gtache.autosubtitle.archive.ffmpeg;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.io.TempDir;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.Paths;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.*;
|
||||
|
||||
class TestTarArchiver {
|
||||
|
||||
private final TarArchiver tarArchiver;
|
||||
|
||||
TestTarArchiver() {
|
||||
this.tarArchiver = new TarArchiver();
|
||||
}
|
||||
|
||||
@Test
|
||||
void testIsPathSupported() {
|
||||
assertTrue(tarArchiver.isPathSupported(Path.of("test.tar")));
|
||||
assertFalse(tarArchiver.isPathSupported(Path.of("test")));
|
||||
assertFalse(tarArchiver.isPathSupported(Path.of("test.txt")));
|
||||
assertFalse(tarArchiver.isPathSupported(Path.of("test.tar2")));
|
||||
}
|
||||
|
||||
@Test
|
||||
void testDecompress(@TempDir final Path tempDir) throws IOException {
|
||||
final var file = tempDir.resolve("test.tar");
|
||||
try (final var in = getClass().getResourceAsStream("in.tar")) {
|
||||
Files.copy(in, file);
|
||||
}
|
||||
tarArchiver.decompress(file, tempDir);
|
||||
final var inTxt = tempDir.resolve("in.txt");
|
||||
final var bin = tempDir.resolve("bin");
|
||||
final var binTxt = bin.resolve("bin.txt");
|
||||
final var lib = tempDir.resolve("lib");
|
||||
final var libTxt = lib.resolve("lib.txt");
|
||||
|
||||
assertTrue(Files.exists(inTxt));
|
||||
assertEquals("in", Files.readString(inTxt));
|
||||
assertTrue(Files.exists(bin));
|
||||
assertTrue(Files.exists(binTxt));
|
||||
assertEquals("bin", Files.readString(binTxt));
|
||||
assertTrue(Files.exists(lib));
|
||||
assertTrue(Files.exists(libTxt));
|
||||
assertEquals("lib", Files.readString(libTxt));
|
||||
}
|
||||
|
||||
@Test
|
||||
void testIllegal() {
|
||||
assertThrows(IllegalArgumentException.class, () -> tarArchiver.decompress(Paths.get("file.txt"), Paths.get("target")));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,46 @@
|
||||
package com.github.gtache.autosubtitle.archive.ffmpeg;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.io.TempDir;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.Paths;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.*;
|
||||
|
||||
class TestXZArchiver {
|
||||
|
||||
private final XZArchiver xzArchiver;
|
||||
|
||||
TestXZArchiver() {
|
||||
this.xzArchiver = new XZArchiver();
|
||||
}
|
||||
|
||||
@Test
|
||||
void testIsPathSupported() {
|
||||
assertTrue(xzArchiver.isPathSupported(Path.of("test.xz")));
|
||||
assertFalse(xzArchiver.isPathSupported(Path.of("test")));
|
||||
assertFalse(xzArchiver.isPathSupported(Path.of("test.txt")));
|
||||
assertFalse(xzArchiver.isPathSupported(Path.of("test.xz2")));
|
||||
}
|
||||
|
||||
@Test
|
||||
void testDecompress(@TempDir final Path tempDir) throws IOException {
|
||||
final var file = tempDir.resolve("in.txt.xz");
|
||||
try (final var in = getClass().getResourceAsStream("in.txt.xz")) {
|
||||
Files.copy(in, file);
|
||||
}
|
||||
xzArchiver.decompress(file, tempDir);
|
||||
final var inTxt = tempDir.resolve("in.txt");
|
||||
|
||||
assertTrue(Files.isRegularFile(inTxt));
|
||||
assertEquals("in", Files.readString(inTxt));
|
||||
}
|
||||
|
||||
@Test
|
||||
void testIllegal() {
|
||||
assertThrows(IllegalArgumentException.class, () -> xzArchiver.decompress(Paths.get("file.txt"), Paths.get("target")));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,57 @@
|
||||
package com.github.gtache.autosubtitle.ffmpeg;
|
||||
|
||||
import com.github.gtache.autosubtitle.Video;
|
||||
import com.github.gtache.autosubtitle.VideoInfo;
|
||||
import com.github.gtache.autosubtitle.impl.OS;
|
||||
import com.github.gtache.autosubtitle.subtitle.SubtitleCollection;
|
||||
import com.github.gtache.autosubtitle.subtitle.converter.SubtitleConverter;
|
||||
import org.junit.jupiter.api.AfterEach;
|
||||
import org.junit.jupiter.api.extension.ExtendWith;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.junit.jupiter.MockitoExtension;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.StandardCopyOption;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
@ExtendWith(MockitoExtension.class)
|
||||
class TestFFmpegVideoConverter {
|
||||
|
||||
private final FFmpegVideoConverter converter;
|
||||
private final SubtitleConverter subtitleConverter;
|
||||
private final Video video;
|
||||
private final VideoInfo videoInfo;
|
||||
private final Path tmpFile;
|
||||
private final Path outputPath;
|
||||
private final SubtitleCollection<?> collection;
|
||||
|
||||
TestFFmpegVideoConverter(@Mock final SubtitleConverter subtitleConverter, @Mock final Video video,
|
||||
@Mock final VideoInfo videoInfo, @Mock final SubtitleCollection<?> collection) throws IOException {
|
||||
final var output = (OS.getOS() == OS.WINDOWS ? System.getProperty("java.io.tmpdir") : "/tmp");
|
||||
final var resource = OS.getOS() == OS.WINDOWS ? "fake-ffmpeg.exe" : "fake-ffmpeg.sh";
|
||||
this.video = Objects.requireNonNull(video);
|
||||
this.videoInfo = Objects.requireNonNull(videoInfo);
|
||||
when(video.info()).thenReturn(videoInfo);
|
||||
this.tmpFile = Files.createTempFile("fake-ffmpeg", resource.substring(resource.lastIndexOf('.')));
|
||||
try (final var in = getClass().getResourceAsStream(resource)) {
|
||||
Files.copy(in, tmpFile, StandardCopyOption.REPLACE_EXISTING);
|
||||
}
|
||||
this.outputPath = Path.of(output, "test-ffmpeg-output.txt");
|
||||
this.subtitleConverter = Objects.requireNonNull(subtitleConverter);
|
||||
this.converter = new FFmpegVideoConverter(tmpFile, tmpFile, Map.of("srt", subtitleConverter));
|
||||
this.collection = Objects.requireNonNull(collection);
|
||||
}
|
||||
|
||||
@AfterEach
|
||||
void afterEach() throws IOException {
|
||||
Files.deleteIfExists(tmpFile);
|
||||
Files.deleteIfExists(outputPath);
|
||||
}
|
||||
|
||||
//TODO tests
|
||||
}
|
||||
@@ -0,0 +1,51 @@
|
||||
package com.github.gtache.autosubtitle.ffmpeg;
|
||||
|
||||
import com.github.gtache.autosubtitle.impl.FileVideoImpl;
|
||||
import com.github.gtache.autosubtitle.impl.OS;
|
||||
import com.github.gtache.autosubtitle.impl.VideoInfoImpl;
|
||||
import org.junit.jupiter.api.AfterEach;
|
||||
import org.junit.jupiter.api.Disabled;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.Paths;
|
||||
import java.nio.file.StandardCopyOption;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
|
||||
class TestFFmpegVideoLoader {
|
||||
|
||||
private final FFprobeVideoLoader loader;
|
||||
private final Path tmpFile;
|
||||
private final Path outputPath;
|
||||
|
||||
TestFFmpegVideoLoader() throws IOException {
|
||||
final var output = (OS.getOS() == OS.WINDOWS ? System.getProperty("java.io.tmpdir") : "/tmp");
|
||||
final var resource = OS.getOS() == OS.WINDOWS ? "fake-ffprobe.exe" : "fake-ffprobe.sh";
|
||||
this.tmpFile = Files.createTempFile("fake-ffprobe", resource.substring(resource.lastIndexOf('.')));
|
||||
try (final var in = getClass().getResourceAsStream(resource)) {
|
||||
Files.copy(in, tmpFile, StandardCopyOption.REPLACE_EXISTING);
|
||||
}
|
||||
this.outputPath = Path.of(output, "test-ffprobe-output.txt");
|
||||
this.loader = new FFprobeVideoLoader(tmpFile, tmpFile);
|
||||
}
|
||||
|
||||
@AfterEach
|
||||
void afterEach() throws IOException {
|
||||
Files.deleteIfExists(tmpFile);
|
||||
Files.deleteIfExists(outputPath);
|
||||
}
|
||||
|
||||
@Test
|
||||
@Disabled("Doesn't work")
|
||||
void testLoadVideo() throws IOException {
|
||||
final var in = Paths.get("in.mp4");
|
||||
final var expectedInfo = new VideoInfoImpl("mp4", 1920, 1080, 25000L);
|
||||
final var expected = new FileVideoImpl(in, expectedInfo);
|
||||
final var result = loader.loadVideo(in);
|
||||
assertEquals(expected, result);
|
||||
assertEquals("-v error -select_streams v -show_entries stream=width,height,duration -of csv=p=0 in.mp4", Files.readString(outputPath));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,84 @@
|
||||
package com.github.gtache.autosubtitle.modules.setup.ffmpeg;
|
||||
|
||||
import com.github.gtache.autosubtitle.impl.Architecture;
|
||||
import com.github.gtache.autosubtitle.impl.OS;
|
||||
import com.github.gtache.autosubtitle.setup.ffmpeg.FFmpegSetupConfiguration;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.Paths;
|
||||
|
||||
import static com.github.gtache.autosubtitle.impl.OS.*;
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.mockito.Mockito.mock;
|
||||
|
||||
class TestFFmpegSetupModule {
|
||||
|
||||
private static final String FFMPEG = "ffmpeg";
|
||||
private static final String FFPROBE = "ffprobe";
|
||||
|
||||
private final Path root;
|
||||
private final String extension;
|
||||
|
||||
TestFFmpegSetupModule() {
|
||||
this.root = Paths.get("root");
|
||||
this.extension = "ext";
|
||||
}
|
||||
|
||||
@Test
|
||||
void testFFmpegSetupConfiguration() {
|
||||
final var bundledPath = mock(Path.class);
|
||||
final var systemPath = mock(Path.class);
|
||||
final var ffmpegInstallerPath = mock(Path.class);
|
||||
final var ffprobeInstallerPath = mock(Path.class);
|
||||
final var os = mock(OS.class);
|
||||
final var architecture = mock(Architecture.class);
|
||||
final var expected = new FFmpegSetupConfiguration(root, bundledPath, systemPath, ffmpegInstallerPath, ffprobeInstallerPath, os, architecture);
|
||||
assertEquals(expected, FFmpegSetupModule.providesFFmpegSetupConfiguration(root, bundledPath, systemPath, ffmpegInstallerPath, ffprobeInstallerPath, os, architecture));
|
||||
}
|
||||
|
||||
@Test
|
||||
void testProvidesFFmpegInstallerPath() {
|
||||
assertEquals(root.resolve(FFMPEG + "-installer.tar.xz"), FFmpegSetupModule.providesFFmpegInstallerPath(root, LINUX));
|
||||
assertEquals(root.resolve(FFMPEG + "-installer.zip"), FFmpegSetupModule.providesFFmpegInstallerPath(root, WINDOWS));
|
||||
assertEquals(root.resolve(FFMPEG + "-installer.zip"), FFmpegSetupModule.providesFFmpegInstallerPath(root, MAC));
|
||||
}
|
||||
|
||||
@Test
|
||||
void testProvidesFFProbeInstallerPath() {
|
||||
assertEquals(root.resolve(FFPROBE + "-installer.tar.xz"), FFmpegSetupModule.providesFFProbeInstallerPath(root, LINUX));
|
||||
assertEquals(root.resolve(FFPROBE + "-installer.zip"), FFmpegSetupModule.providesFFProbeInstallerPath(root, WINDOWS));
|
||||
assertEquals(root.resolve(FFPROBE + "-installer.zip"), FFmpegSetupModule.providesFFProbeInstallerPath(root, MAC));
|
||||
}
|
||||
|
||||
@Test
|
||||
void testProvidesBundledRoot() {
|
||||
assertEquals(root.resolve(FFMPEG), FFmpegSetupModule.providesFFBundledRoot(root));
|
||||
}
|
||||
|
||||
@Test
|
||||
void testFFprobeBundledPath() {
|
||||
assertEquals(root.resolve(FFPROBE + extension), FFmpegSetupModule.providesFFProbeBundledPath(root, extension));
|
||||
}
|
||||
|
||||
@Test
|
||||
void testFFprobeSystemPath() {
|
||||
assertEquals(Paths.get(FFPROBE + extension), FFmpegSetupModule.providesFFProbeSystemPath(extension));
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
void testFFmpegBundledPath() {
|
||||
assertEquals(root.resolve(FFMPEG + extension), FFmpegSetupModule.providesFFmpegBundledPath(root, extension));
|
||||
}
|
||||
|
||||
@Test
|
||||
void testFFmpegSystemPath() {
|
||||
assertEquals(Paths.get(FFMPEG + extension), FFmpegSetupModule.providesFFmpegSystemPath(extension));
|
||||
}
|
||||
|
||||
@Test
|
||||
void testVersion() {
|
||||
assertEquals("7.0.1", FFmpegSetupModule.providesFFmpegVersion());
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,62 @@
|
||||
package com.github.gtache.autosubtitle.setup.ffmpeg;
|
||||
|
||||
import com.github.gtache.autosubtitle.impl.Architecture;
|
||||
import com.github.gtache.autosubtitle.impl.OS;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.extension.ExtendWith;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.junit.jupiter.MockitoExtension;
|
||||
|
||||
import java.nio.file.Path;
|
||||
|
||||
import static java.util.Objects.requireNonNull;
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertThrows;
|
||||
|
||||
@ExtendWith(MockitoExtension.class)
|
||||
class TestFFmpegSetupConfiguration {
|
||||
|
||||
private final Path root;
|
||||
private final Path bundledFFmpegPath;
|
||||
private final Path systemFFmpegPath;
|
||||
private final Path ffmpegInstallerPath;
|
||||
private final Path ffprobeInstallerPath;
|
||||
private final OS os;
|
||||
private final Architecture architecture;
|
||||
|
||||
TestFFmpegSetupConfiguration(@Mock final Path root, @Mock final Path bundledFFmpegPath,
|
||||
@Mock final Path systemFFmpegPath, @Mock final Path ffmpegInstallerPath,
|
||||
@Mock final Path ffprobeInstallerPath, @Mock final OS os,
|
||||
@Mock final Architecture architecture) {
|
||||
this.root = requireNonNull(root);
|
||||
this.bundledFFmpegPath = requireNonNull(bundledFFmpegPath);
|
||||
this.systemFFmpegPath = requireNonNull(systemFFmpegPath);
|
||||
this.ffmpegInstallerPath = requireNonNull(ffmpegInstallerPath);
|
||||
this.ffprobeInstallerPath = requireNonNull(ffprobeInstallerPath);
|
||||
this.os = requireNonNull(os);
|
||||
this.architecture = requireNonNull(architecture);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testGetters() {
|
||||
final var config = new FFmpegSetupConfiguration(root, bundledFFmpegPath, systemFFmpegPath, ffmpegInstallerPath, ffprobeInstallerPath, os, architecture);
|
||||
assertEquals(root, config.root());
|
||||
assertEquals(bundledFFmpegPath, config.bundledFFmpegPath());
|
||||
assertEquals(systemFFmpegPath, config.systemFFmpegPath());
|
||||
assertEquals(ffmpegInstallerPath, config.ffmpegInstallerPath());
|
||||
assertEquals(ffprobeInstallerPath, config.ffprobeInstallerPath());
|
||||
assertEquals(os, config.os());
|
||||
assertEquals(architecture, config.architecture());
|
||||
}
|
||||
|
||||
@Test
|
||||
void testIllegal() {
|
||||
assertThrows(NullPointerException.class, () -> new FFmpegSetupConfiguration(null, bundledFFmpegPath, systemFFmpegPath, ffmpegInstallerPath, ffprobeInstallerPath, os, architecture));
|
||||
assertThrows(NullPointerException.class, () -> new FFmpegSetupConfiguration(root, null, systemFFmpegPath, ffmpegInstallerPath, ffprobeInstallerPath, os, architecture));
|
||||
assertThrows(NullPointerException.class, () -> new FFmpegSetupConfiguration(root, bundledFFmpegPath, null, ffmpegInstallerPath, ffprobeInstallerPath, os, architecture));
|
||||
assertThrows(NullPointerException.class, () -> new FFmpegSetupConfiguration(root, bundledFFmpegPath, systemFFmpegPath, null, ffprobeInstallerPath, os, architecture));
|
||||
assertThrows(NullPointerException.class, () -> new FFmpegSetupConfiguration(root, bundledFFmpegPath, systemFFmpegPath, ffmpegInstallerPath, null, os, architecture));
|
||||
assertThrows(NullPointerException.class, () -> new FFmpegSetupConfiguration(root, bundledFFmpegPath, systemFFmpegPath, ffmpegInstallerPath, ffprobeInstallerPath, null, architecture));
|
||||
assertThrows(NullPointerException.class, () -> new FFmpegSetupConfiguration(root, bundledFFmpegPath, systemFFmpegPath, ffmpegInstallerPath, ffprobeInstallerPath, os, null));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,4 @@
|
||||
package com.github.gtache.autosubtitle.setup.ffmpeg;
|
||||
|
||||
class TestFFmpegSetupManager {
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
bin
|
||||
Binary file not shown.
@@ -0,0 +1 @@
|
||||
in
|
||||
Binary file not shown.
@@ -0,0 +1 @@
|
||||
lib
|
||||
Binary file not shown.
@@ -0,0 +1,5 @@
|
||||
$TempDir = [System.IO.Path]::GetTempPath()
|
||||
$Output = "$TempDir\test-ffmpeg-output.txt"
|
||||
|
||||
Write-Output "$args" > $Output
|
||||
exit
|
||||
@@ -0,0 +1,6 @@
|
||||
#!/bin/bash
|
||||
set -o errexit -o noclobber -o pipefail -o nounset
|
||||
|
||||
output=/tmp/test-ffmpeg-output.txt
|
||||
|
||||
echo "$@" >| $output
|
||||
Binary file not shown.
@@ -0,0 +1,6 @@
|
||||
$TempDir = [System.IO.Path]::GetTempPath()
|
||||
$Output = "$TempDir\test-ffprobe-output.txt"
|
||||
|
||||
Write-Output "$args" > $Output
|
||||
Write-Host "1920,1080,25"
|
||||
exit
|
||||
@@ -0,0 +1,7 @@
|
||||
#!/bin/bash
|
||||
set -o errexit -o noclobber -o pipefail -o nounset
|
||||
|
||||
output=/tmp/test-ffprobe-output.txt
|
||||
|
||||
echo "$@" >| $output
|
||||
echo "1920,1080,25"
|
||||
13
ffmpeg/src/test/resources/log4j2-test.xml
Normal file
13
ffmpeg/src/test/resources/log4j2-test.xml
Normal file
@@ -0,0 +1,13 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<Configuration status="INFO">
|
||||
<Appenders>
|
||||
<Console name="Console" target="SYSTEM_OUT">
|
||||
<PatternLayout pattern="%d{HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n"/>
|
||||
</Console>
|
||||
</Appenders>
|
||||
<Loggers>
|
||||
<Root level="info">
|
||||
<AppenderRef ref="Console"/>
|
||||
</Root>
|
||||
</Loggers>
|
||||
</Configuration>
|
||||
Reference in New Issue
Block a user