| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241 |
- /*
- * Copyright (C) 2022 The V-Gears Team
- *
- * This file is part of V-Gears
- *
- * V-Gears is free software: you can redistribute it and/or modify it under
- * terms of the GNU General Public License as published by the Free Software
- * Foundation, version 3.0 (GPLv3) of the License.
- *
- * V-Gears is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- */
- #pragma once
- #include <cstdint>
- #include <string>
- #include <vector>
- /**
- * Finding and running the external programs the installer uses to convert audio: FFmpeg (sounds and music) and
- * TiMidity (to render the MIDI music).
- *
- * Programs are searched in this order: the path the user chose, a list of directories (for example a "tools" folder
- * in the installation directory), and the system PATH. Every candidate is run to check that it really is the
- * program and that it can do what the installer needs, so a broken file doesn't hide a good one further down.
- *
- * Programs are run directly with a list of arguments, not through a shell: there is no quoting to get wrong, paths
- * can have spaces, and it works the same on Windows.
- */
- namespace ExternalTools{
- /**
- * What is needed to search for an executable.
- */
- struct Environment{
- /**
- * The PATH variable.
- */
- std::string path;
- /**
- * The PATHEXT variable (Windows): extensions that make a file executable, separated by ';'.
- */
- std::string pathext;
- /**
- * True to search with the rules of Windows (';' separates the PATH entries, a file is executable if it has
- * one of the PATHEXT extensions) and false for the rules of Unix (':' and the executable permission).
- */
- bool windows = false;
- /**
- * Gets the environment of the running system.
- */
- static Environment FromSystem();
- };
- /**
- * Where to look for the programs.
- */
- struct Locations{
- /**
- * Path of FFmpeg that the user chose. Empty if none.
- */
- std::string ffmpeg;
- /**
- * Path of TiMidity that the user chose. Empty if none.
- */
- std::string timidity;
- /**
- * Directories searched before the PATH.
- */
- std::vector<std::string> directories;
- };
- /**
- * Gets the locations used by the installer. Set them before an installation.
- */
- Locations& CurrentLocations();
- /**
- * Lists the executables that could be a program, in the order they are tried.
- *
- * @param[in] name Name of the program, without extension.
- * @param[in] saved_path Path chosen by the user. It is the first candidate if it is a file.
- * @param[in] directories Directories searched before the PATH.
- * @param[in] env The environment.
- */
- std::vector<std::string> Candidates(
- const std::string& name, const std::string& saved_path, const std::vector<std::string>& directories,
- const Environment& env
- );
- /**
- * A program found in the system.
- */
- struct Tool{
- /**
- * Path of the program. Empty if it wasn't found.
- */
- std::string path;
- /**
- * First line of the version of the program.
- */
- std::string version;
- /**
- * True if a working program was found.
- */
- bool usable = false;
- /**
- * Why it can't be used. Empty if it is usable. It's about the first candidate that failed if there were any,
- * and says it wasn't found if there were none.
- */
- std::string problem;
- };
- /**
- * Gets the version number of a tool for the window: "9.0.2-1" from "ffmpeg version 9.0.2-1 Copyright ...", and
- * "2.14.0" from "TiMidity++ version 2.14.0". If there is no "version" word it is the whole version line.
- * Empty if the tool has no version.
- */
- std::string ShortVersion(const Tool& tool);
- /**
- * Result of running a program.
- */
- struct RunResult{
- bool started = false;
- bool finished = false;
- int exit_code = -1;
- /**
- * Standard output and error.
- */
- std::string output;
- };
- /**
- * Runs a program and waits for it.
- *
- * @param[in] program Path of the program.
- * @param[in] arguments Arguments, without quoting.
- * @param[in] timeout_ms Milliseconds to wait before killing it. Negative to wait forever.
- */
- RunResult Run(const std::string& program, const std::vector<std::string>& arguments, int timeout_ms);
- /**
- * Checks that a file is FFmpeg and that it can write ogg files (it has the Vorbis encoder).
- */
- Tool ProbeFfmpeg(const std::string& path);
- /**
- * Checks that a file is TiMidity.
- */
- Tool ProbeTimidity(const std::string& path);
- /**
- * Finds a working FFmpeg.
- */
- Tool FindFfmpeg(const Locations& locations, const Environment& env = Environment::FromSystem());
- /**
- * Finds a working TiMidity.
- */
- Tool FindTimidity(const Locations& locations, const Environment& env = Environment::FromSystem());
- /**
- * Arguments to convert an audio file to ogg with FFmpeg.
- */
- std::vector<std::string> FfmpegArguments(const std::string& input, const std::string& output);
- /**
- * Arguments to convert the audio FFmpeg reads from its standard input to ogg.
- */
- std::vector<std::string> FfmpegStdinArguments(const std::string& output);
- /**
- * Arguments to render a MIDI file with TiMidity to a wav file written to the standard output.
- */
- std::vector<std::string> TimidityArguments(const std::string& midi);
- /**
- * Converts an audio file (wav) to ogg.
- *
- * @param[in] ffmpeg Path of FFmpeg.
- * @param[in] input File to convert.
- * @param[in] output File to create. It is removed if the conversion fails.
- * @param[out] error Reason of the failure. Optional.
- * @return True if the output was created.
- */
- bool ConvertToOgg(
- const std::string& ffmpeg, const std::string& input, const std::string& output, std::string* error = nullptr
- );
- /**
- * Converts a movie to what the game plays: a folder with its frames as JPEG files (00000.jpg,
- * 00001.jpg...), an ogg file with its sound, and movie.xml with the number of frames and the
- * frames per second.
- *
- * @param[in] ffmpeg Path of FFmpeg.
- * @param[in] input The movie.
- * @param[in] directory Folder to create. It is removed if the conversion fails.
- * @param[in] name Name of the movie, which is the name of the ogg file.
- * @param[in] camera Content of the camera file of the movie, which the game uses to draw the
- * models over it. It's written as camera.cam, and the first frame that has a camera in
- * movie.xml. Empty if the movie has no camera.
- * @param[out] error Reason of the failure. Optional.
- * @return True if the frames were created. A movie without sound is converted anyway.
- */
- bool ConvertMovie(
- const std::string& ffmpeg, const std::string& input, const std::string& directory,
- const std::string& name, const std::vector<uint8_t>& camera = {}, std::string* error = nullptr
- );
- /**
- * Converts a MIDI file to ogg: TiMidity renders it and its output is sent to FFmpeg.
- *
- * @param[in] timidity Path of TiMidity.
- * @param[in] ffmpeg Path of FFmpeg.
- * @param[in] midi File to convert.
- * @param[in] output File to create. It is removed if the conversion fails.
- * @param[out] error Reason of the failure. Optional.
- * @return True if the output was created.
- */
- bool ConvertMidiToOgg(
- const std::string& timidity, const std::string& ffmpeg, const std::string& midi, const std::string& output,
- std::string* error = nullptr
- );
- }
|