From b0a1cdfce2d7ff9587bb28bf91134ffdd0dfcaa5 Mon Sep 17 00:00:00 2001 From: johni0702 Date: Sun, 1 Jan 2017 14:13:21 +0100 Subject: [PATCH] Search for ffmpeg executable in common locations to simplify setup --- docs/content.md | 4 ++ .../com/replaymod/render/VideoWriter.java | 64 ++++++++++++++++++- 2 files changed, 65 insertions(+), 3 deletions(-) diff --git a/docs/content.md b/docs/content.md index d0638e91..48c3e401 100644 --- a/docs/content.md +++ b/docs/content.md @@ -32,6 +32,10 @@ Next, download this **Batch Script** to quickly install FFmpeg: { @@ -46,8 +56,8 @@ public class VideoWriter implements FrameConsumer { .replace("%BITRATE%", String.valueOf(settings.getBitRate())) .replace("%FILTERS%", settings.getVideoFilters()); - String executable = settings.getExportCommand().isEmpty() ? "ffmpeg" : settings.getExportCommand(); - System.out.println("Starting " + settings.getExportCommand() + " with args: " + commandArgs); + String executable = settings.getExportCommand().isEmpty() ? findFFmpeg() : settings.getExportCommand(); + System.out.println("Starting " + executable + " with args: " + commandArgs); String[] cmdline = new CommandLine(executable).addArguments(commandArgs).toStrings(); process = new ProcessBuilder(cmdline).directory(outputFolder).start(); File exportLogFile = new File(Minecraft.getMinecraft().mcDataDir, "export.log"); @@ -58,6 +68,54 @@ public class VideoWriter implements FrameConsumer { channel = Channels.newChannel(outputStream); } + private String findFFmpeg() { + switch (Util.getOSType()) { + case WINDOWS: + // Allow windows users to unpack the ffmpeg archive into a sub-folder of their .minecraft folder + File inDotMinecraft = new File(Minecraft.getMinecraft().mcDataDir, "ffmpeg/bin/ffmpeg.exe"); + if (inDotMinecraft.exists()) { + LOGGER.debug("FFmpeg found in .minecraft/ffmpeg"); + return inDotMinecraft.getAbsolutePath(); + } + break; + case OSX: + // The PATH doesn't seem to be set as expected on OSX, therefore we check some common locations ourselves + for (String path : new String[]{"/usr/local/bin/ffmpeg", "/usr/bin/ffmpeg"}) { + File file = new File(path); + if (file.exists()) { + LOGGER.debug("Found FFmpeg at {}", path); + return path; + } else { + LOGGER.debug("FFmpeg not located at {}", path); + } + } + // Homebrew doesn't seem to reliably symlink its installed binaries either + File homebrewFolder = new File("/usr/local/Cellar/ffmpeg"); + String[] homebrewVersions = homebrewFolder.list(); + if (homebrewVersions != null) { + Optional latestOpt = Arrays.stream(homebrewVersions) + .map(ComparableVersion::new) // Convert file name to comparable version + .sorted(Comparator.reverseOrder()) // Sort for latest version + .map(ComparableVersion::toString) // Convert back to file name + .map(v -> new File(new File(homebrewFolder, v), "bin/ffmpeg")) // Convert to binary files + .filter(File::exists) // Filter invalid installations (missing executable) + .findFirst(); // Take first one + if (latestOpt.isPresent()) { + File latest = latestOpt.get(); + LOGGER.debug("Found {} versions of FFmpeg installed with homebrew, chose {}", + homebrewVersions.length, latest); + return latest.getAbsolutePath(); + } + } + break; + case LINUX: // Linux users are entrusted to have their PATH configured correctly (most package manager do this) + case SOLARIS: // Never heard of anyone running this mod on Solaris having any problems + case UNKNOWN: // Unknown OS, just try to use "ffmpeg" + } + LOGGER.debug("Using default FFmpeg executable"); + return "ffmpeg"; + } + @Override public void close() throws IOException { IOUtils.closeQuietly(outputStream);