|
justburner |
64e039 |
#include "thirdparty.h"
|
|
justburner |
64e039 |
|
|
justburner |
64e039 |
// TnzLib includes
|
|
justburner |
64e039 |
#include "toonz/preferences.h"
|
|
justburner |
64e039 |
|
|
justburner |
64e039 |
// TnzCore includes
|
|
justburner |
64e039 |
#include "tsystem.h"
|
|
justburner |
64e039 |
#include "tmsgcore.h"
|
|
justburner |
64e039 |
|
|
justburner |
64e039 |
// QT includes
|
|
justburner |
64e039 |
#include <qcoreapplication></qcoreapplication>
|
|
justburner |
64e039 |
#include <qeventloop></qeventloop>
|
|
justburner |
64e039 |
#include <qtimer></qtimer>
|
|
justburner |
64e039 |
|
|
justburner |
64e039 |
namespace ThirdParty {
|
|
justburner |
64e039 |
|
|
justburner |
64e039 |
//-----------------------------------------------------------------------------
|
|
justburner |
64e039 |
|
|
justburner |
64e039 |
void initialize() {
|
|
justburner |
64e039 |
// Auto detect FFmpeg
|
|
justburner |
64e039 |
if (!ThirdParty::checkFFmpeg()) {
|
|
justburner |
64e039 |
QString path = ThirdParty::autodetectFFmpeg();
|
|
justburner |
64e039 |
if (!path.isEmpty()) ThirdParty::setFFmpegDir(path);
|
|
justburner |
64e039 |
}
|
|
justburner |
64e039 |
|
|
justburner |
64e039 |
// Auto detect Rhubarb
|
|
justburner |
64e039 |
if (!ThirdParty::checkRhubarb()) {
|
|
justburner |
64e039 |
QString path = ThirdParty::autodetectRhubarb();
|
|
justburner |
64e039 |
if (!path.isEmpty()) ThirdParty::setRhubarbDir(path);
|
|
justburner |
64e039 |
}
|
|
justburner |
64e039 |
}
|
|
justburner |
64e039 |
|
|
justburner |
64e039 |
//=============================================================================
|
|
justburner |
64e039 |
// FFmpeg interface
|
|
justburner |
64e039 |
//-----------------------------------------------------------------------------
|
|
justburner |
64e039 |
|
|
justburner |
64e039 |
#ifdef _WIN32
|
|
justburner |
64e039 |
#define FFMPEG_EXE "/ffmpeg.exe"
|
|
justburner |
64e039 |
#define FFPROBE_EXE "/ffprobe.exe"
|
|
justburner |
64e039 |
#else
|
|
justburner |
64e039 |
#define FFMPEG_EXE "/ffmpeg"
|
|
justburner |
64e039 |
#define FFPROBE_EXE "/ffprobe"
|
|
justburner |
64e039 |
#endif
|
|
justburner |
64e039 |
|
|
justburner |
64e039 |
//-----------------------------------------------------------------------------
|
|
justburner |
64e039 |
|
|
justburner |
64e039 |
void getFFmpegVideoSupported(QStringList &exts) {
|
|
justburner |
64e039 |
exts.append("gif");
|
|
justburner |
64e039 |
exts.append("mp4");
|
|
justburner |
64e039 |
exts.append("webm");
|
|
justburner |
64e039 |
}
|
|
justburner |
64e039 |
|
|
justburner |
64e039 |
//-----------------------------------------------------------------------------
|
|
justburner |
64e039 |
|
|
justburner |
64e039 |
void getFFmpegAudioSupported(QStringList &exts) {
|
|
justburner |
64e039 |
exts.append("mp3");
|
|
justburner |
64e039 |
exts.append("ogg");
|
|
justburner |
64e039 |
exts.append("flac");
|
|
justburner |
64e039 |
}
|
|
justburner |
64e039 |
|
|
justburner |
64e039 |
//-----------------------------------------------------------------------------
|
|
justburner |
64e039 |
|
|
justburner |
64e039 |
bool findFFmpeg(QString dir) {
|
|
justburner |
64e039 |
// Relative path
|
|
justburner |
64e039 |
if (dir.isEmpty() || dir.at(0) == ".") {
|
|
justburner |
64e039 |
dir = QCoreApplication::applicationDirPath() + "/" + dir;
|
|
justburner |
64e039 |
}
|
|
justburner |
64e039 |
|
|
justburner |
64e039 |
// Check if both executables exist
|
|
justburner |
64e039 |
return TSystem::doesExistFileOrLevel(TFilePath(dir + FFMPEG_EXE)) &&
|
|
justburner |
64e039 |
TSystem::doesExistFileOrLevel(TFilePath(dir + FFPROBE_EXE));
|
|
justburner |
64e039 |
}
|
|
justburner |
64e039 |
|
|
justburner |
64e039 |
//-----------------------------------------------------------------------------
|
|
justburner |
64e039 |
|
|
justburner |
64e039 |
bool checkFFmpeg() {
|
|
justburner |
64e039 |
// Path in preferences
|
|
justburner |
64e039 |
return findFFmpeg(Preferences::instance()->getFfmpegPath());
|
|
justburner |
64e039 |
}
|
|
justburner |
64e039 |
|
|
justburner |
64e039 |
//-----------------------------------------------------------------------------
|
|
justburner |
64e039 |
|
|
justburner |
64e039 |
QString autodetectFFmpeg() {
|
|
justburner |
64e039 |
QString dir = Preferences::instance()->getFfmpegPath();
|
|
justburner |
64e039 |
if (findFFmpeg(dir)) return dir;
|
|
justburner |
64e039 |
|
|
justburner |
64e039 |
if (findFFmpeg(".")) return ".";
|
|
justburner |
64e039 |
if (findFFmpeg("./ffmpeg")) return "./ffmpeg";
|
|
justburner |
64e039 |
if (findFFmpeg("./ffmpeg/bin")) return "./ffmpeg/bin";
|
|
justburner |
64e039 |
if (findFFmpeg("./FFmpeg")) return "./FFmpeg";
|
|
justburner |
64e039 |
if (findFFmpeg("./FFmpeg/bin")) return "./FFmpeg/bin";
|
|
justburner |
64e039 |
|
|
justburner |
64e039 |
#ifndef _WIN32
|
|
justburner |
64e039 |
if (findFFmpeg("/usr/local/bin")) return "/usr/local/bin";
|
|
justburner |
64e039 |
if (findFFmpeg("/usr/bin")) return "/usr/bin";
|
|
justburner |
64e039 |
if (findFFmpeg("/bin")) return "/bin";
|
|
justburner |
64e039 |
#endif
|
|
justburner |
64e039 |
|
|
justburner |
64e039 |
return "";
|
|
justburner |
64e039 |
}
|
|
justburner |
64e039 |
|
|
justburner |
64e039 |
//-----------------------------------------------------------------------------
|
|
justburner |
64e039 |
|
|
justburner |
64e039 |
QString getFFmpegDir() {
|
|
justburner |
64e039 |
return Preferences::instance()->getStringValue(ffmpegPath);
|
|
justburner |
64e039 |
}
|
|
justburner |
64e039 |
|
|
justburner |
64e039 |
//-----------------------------------------------------------------------------
|
|
justburner |
64e039 |
|
|
justburner |
64e039 |
void setFFmpegDir(const QString &dir) {
|
|
justburner |
64e039 |
QString path = Preferences::instance()->getFfmpegPath();
|
|
justburner |
64e039 |
if (path != dir) Preferences::instance()->setValue(ffmpegPath, dir);
|
|
justburner |
64e039 |
}
|
|
justburner |
64e039 |
|
|
justburner |
64e039 |
//-----------------------------------------------------------------------------
|
|
justburner |
64e039 |
|
|
justburner |
64e039 |
int getFFmpegTimeout() {
|
|
justburner |
64e039 |
return Preferences::instance()->getIntValue(ffmpegTimeout);
|
|
justburner |
64e039 |
}
|
|
justburner |
64e039 |
|
|
justburner |
64e039 |
//-----------------------------------------------------------------------------
|
|
justburner |
64e039 |
|
|
justburner |
64e039 |
void setFFmpegTimeout(int secs) {
|
|
justburner |
64e039 |
int timeout = Preferences::instance()->getIntValue(ffmpegTimeout);
|
|
justburner |
64e039 |
if (secs != timeout) Preferences::instance()->setValue(ffmpegTimeout, secs);
|
|
justburner |
64e039 |
}
|
|
justburner |
64e039 |
|
|
justburner |
64e039 |
//-----------------------------------------------------------------------------
|
|
justburner |
64e039 |
|
|
justburner |
64e039 |
void runFFmpeg(QProcess &process, const QStringList &arguments) {
|
|
justburner |
64e039 |
QString dir = Preferences::instance()->getFfmpegPath();
|
|
justburner |
64e039 |
if (dir.at(0) == '.') // Relative path
|
|
justburner |
64e039 |
dir = QCoreApplication::applicationDirPath() + "/" + dir;
|
|
justburner |
64e039 |
|
|
justburner |
64e039 |
process.start(dir + FFMPEG_EXE, arguments);
|
|
justburner |
64e039 |
}
|
|
justburner |
64e039 |
|
|
justburner |
64e039 |
//-----------------------------------------------------------------------------
|
|
justburner |
64e039 |
|
|
justburner |
64e039 |
void runFFprobe(QProcess &process, const QStringList &arguments) {
|
|
justburner |
64e039 |
QString dir = Preferences::instance()->getFfmpegPath();
|
|
justburner |
64e039 |
if (dir.at(0) == '.') // Relative path
|
|
justburner |
64e039 |
dir = QCoreApplication::applicationDirPath() + "/" + dir;
|
|
justburner |
64e039 |
|
|
justburner |
64e039 |
process.start(dir + FFPROBE_EXE, arguments);
|
|
justburner |
64e039 |
}
|
|
justburner |
64e039 |
|
|
justburner |
64e039 |
//-----------------------------------------------------------------------------
|
|
justburner |
64e039 |
|
|
justburner |
64e039 |
void runFFmpegAudio(QProcess &process, QString srcPath, QString dstPath,
|
|
justburner |
64e039 |
int samplerate, int bpp, int channels) {
|
|
justburner |
64e039 |
QStringList args;
|
|
justburner |
64e039 |
args << "-y";
|
|
justburner |
64e039 |
args << "-i";
|
|
justburner |
64e039 |
args << srcPath;
|
|
justburner |
64e039 |
args << "-f";
|
|
justburner |
64e039 |
switch (bpp) {
|
|
justburner |
64e039 |
case 8: // unsigned
|
|
justburner |
64e039 |
args << "u8";
|
|
justburner |
64e039 |
break;
|
|
justburner |
64e039 |
case 16:
|
|
justburner |
64e039 |
args << "s16le";
|
|
justburner |
64e039 |
break;
|
|
justburner |
64e039 |
case 24:
|
|
justburner |
64e039 |
args << "s24le";
|
|
justburner |
64e039 |
break;
|
|
justburner |
64e039 |
case 32: // floating-point
|
|
justburner |
64e039 |
args << "f32le";
|
|
justburner |
64e039 |
break;
|
|
justburner |
64e039 |
default:
|
|
justburner |
64e039 |
return;
|
|
justburner |
64e039 |
}
|
|
justburner |
64e039 |
args << "-ac";
|
|
justburner |
64e039 |
args << QString::number(channels);
|
|
justburner |
64e039 |
args << "-ar";
|
|
justburner |
64e039 |
args << QString::number(samplerate);
|
|
justburner |
64e039 |
args << dstPath;
|
|
justburner |
64e039 |
|
|
justburner |
64e039 |
ThirdParty::runFFmpeg(process, args);
|
|
justburner |
64e039 |
}
|
|
justburner |
64e039 |
|
|
justburner |
64e039 |
//-----------------------------------------------------------------------------
|
|
justburner |
64e039 |
|
|
justburner |
64e039 |
bool readFFmpegAudio(QProcess &process, QByteArray &rawData) {
|
|
justburner |
64e039 |
if (!process.waitForStarted()) return false;
|
|
justburner |
64e039 |
if (!process.waitForFinished(30000)) return false;
|
|
justburner |
64e039 |
bool success = (process.exitCode() == 0);
|
|
justburner |
64e039 |
|
|
justburner |
64e039 |
if (success) rawData = process.readAllStandardOutput();
|
|
justburner |
64e039 |
process.close();
|
|
justburner |
64e039 |
|
|
justburner |
64e039 |
return success;
|
|
justburner |
64e039 |
}
|
|
justburner |
64e039 |
|
|
justburner |
64e039 |
//=============================================================================
|
|
justburner |
64e039 |
// Rhubarb interface
|
|
justburner |
64e039 |
//-----------------------------------------------------------------------------
|
|
justburner |
64e039 |
|
|
justburner |
64e039 |
#ifdef _WIN32
|
|
justburner |
64e039 |
#define RHUBARB_EXE "/rhubarb.exe"
|
|
justburner |
64e039 |
#else
|
|
justburner |
64e039 |
#define RHUBARB_EXE "/rhubarb"
|
|
justburner |
64e039 |
#endif
|
|
justburner |
64e039 |
|
|
justburner |
64e039 |
//-----------------------------------------------------------------------------
|
|
justburner |
64e039 |
|
|
justburner |
64e039 |
bool findRhubarb(QString dir) {
|
|
justburner |
64e039 |
// Rhubarb executable
|
|
justburner |
64e039 |
|
|
justburner |
64e039 |
// Relative path
|
|
justburner |
64e039 |
if (dir.isEmpty() || dir.at(0) == ".") {
|
|
justburner |
64e039 |
dir = QCoreApplication::applicationDirPath() + "/" + dir;
|
|
justburner |
64e039 |
}
|
|
justburner |
64e039 |
|
|
justburner |
64e039 |
// Check if executable exist
|
|
justburner |
64e039 |
return TSystem::doesExistFileOrLevel(TFilePath(dir + RHUBARB_EXE));
|
|
justburner |
64e039 |
}
|
|
justburner |
64e039 |
|
|
justburner |
64e039 |
//-----------------------------------------------------------------------------
|
|
justburner |
64e039 |
|
|
justburner |
64e039 |
bool checkRhubarb() {
|
|
justburner |
64e039 |
// Path in preferences
|
|
justburner |
64e039 |
return findRhubarb(Preferences::instance()->getRhubarbPath());
|
|
justburner |
64e039 |
}
|
|
justburner |
64e039 |
|
|
justburner |
64e039 |
//-----------------------------------------------------------------------------
|
|
justburner |
64e039 |
|
|
justburner |
64e039 |
QString autodetectRhubarb() {
|
|
justburner |
64e039 |
QString dir = Preferences::instance()->getRhubarbPath();
|
|
justburner |
64e039 |
if (findRhubarb(dir)) return dir;
|
|
justburner |
64e039 |
|
|
justburner |
64e039 |
if (findRhubarb(".")) return ".";
|
|
justburner |
64e039 |
if (findRhubarb("./rhubarb")) return "./rhubarb";
|
|
justburner |
64e039 |
if (findRhubarb("./rhubarb/bin")) return "./rhubarb/bin";
|
|
justburner |
64e039 |
if (findRhubarb("./Rhubarb-Lip-Sync")) return "./Rhubarb-Lip-Sync";
|
|
justburner |
64e039 |
|
|
justburner |
64e039 |
#ifndef _WIN32
|
|
justburner |
64e039 |
if (findRhubarb("/usr/local/bin")) return "/usr/local/bin";
|
|
justburner |
64e039 |
if (findRhubarb("/usr/bin")) return "/usr/bin";
|
|
justburner |
64e039 |
if (findRhubarb("/bin")) return "/bin";
|
|
justburner |
64e039 |
#endif
|
|
justburner |
64e039 |
|
|
justburner |
64e039 |
return "";
|
|
justburner |
64e039 |
}
|
|
justburner |
64e039 |
|
|
justburner |
64e039 |
//-----------------------------------------------------------------------------
|
|
justburner |
64e039 |
|
|
justburner |
64e039 |
void runRhubarb(QProcess &process, const QStringList &arguments) {
|
|
justburner |
64e039 |
QString dir = Preferences::instance()->getRhubarbPath();
|
|
justburner |
64e039 |
if (dir.at(0) == '.') // Relative path
|
|
justburner |
64e039 |
dir = QCoreApplication::applicationDirPath() + "/" + dir;
|
|
justburner |
64e039 |
|
|
justburner |
64e039 |
process.start(dir + RHUBARB_EXE, arguments);
|
|
justburner |
64e039 |
}
|
|
justburner |
64e039 |
|
|
justburner |
64e039 |
//-----------------------------------------------------------------------------
|
|
justburner |
64e039 |
|
|
justburner |
64e039 |
QString getRhubarbDir() {
|
|
justburner |
64e039 |
return Preferences::instance()->getStringValue(rhubarbPath);
|
|
justburner |
64e039 |
}
|
|
justburner |
64e039 |
|
|
justburner |
64e039 |
//-----------------------------------------------------------------------------
|
|
justburner |
64e039 |
|
|
justburner |
64e039 |
void setRhubarbDir(const QString &dir) {
|
|
justburner |
64e039 |
QString path = Preferences::instance()->getRhubarbPath();
|
|
justburner |
64e039 |
if (path != dir) Preferences::instance()->setValue(rhubarbPath, dir);
|
|
justburner |
64e039 |
}
|
|
justburner |
64e039 |
|
|
justburner |
64e039 |
//-----------------------------------------------------------------------------
|
|
justburner |
64e039 |
|
|
justburner |
64e039 |
int getRhubarbTimeout() {
|
|
justburner |
64e039 |
return Preferences::instance()->getIntValue(rhubarbTimeout);
|
|
justburner |
64e039 |
}
|
|
justburner |
64e039 |
|
|
justburner |
64e039 |
//-----------------------------------------------------------------------------
|
|
justburner |
64e039 |
|
|
justburner |
64e039 |
void setRhubarbTimeout(int secs) {
|
|
justburner |
64e039 |
int timeout = Preferences ::instance()->getIntValue(rhubarbTimeout);
|
|
justburner |
64e039 |
if (secs != timeout) Preferences::instance()->setValue(rhubarbTimeout, secs);
|
|
justburner |
64e039 |
}
|
|
justburner |
64e039 |
|
|
justburner |
64e039 |
//-----------------------------------------------------------------------------
|
|
justburner |
64e039 |
|
|
justburner |
64e039 |
int waitAsyncProcess(const QProcess &process, int timeout) {
|
|
justburner |
64e039 |
QEventLoop eloop;
|
|
justburner |
64e039 |
QTimer timer;
|
|
justburner |
64e039 |
timer.connect(&timer, &QTimer::timeout, &eloop, [&eloop] { eloop.exit(-2); });
|
|
justburner |
64e039 |
QMetaObject::Connection con1 = process.connect(
|
|
justburner |
64e039 |
&process, &QProcess::errorOccurred, &eloop, [&eloop] { eloop.exit(-1); });
|
|
justburner |
64e039 |
QMetaObject::Connection con2 = process.connect(
|
|
justburner |
64e039 |
&process,
|
|
justburner |
64e039 |
static_cast<void (qprocess::*)(int,="" qprocess::exitstatus)="">(</void>
|
|
justburner |
64e039 |
&QProcess::finished),
|
|
justburner |
64e039 |
&eloop, &QEventLoop::quit);
|
|
justburner |
64e039 |
if (timeout >= 0) timer.start(timeout);
|
|
justburner |
64e039 |
|
|
justburner |
64e039 |
int result = eloop.exec();
|
|
justburner |
64e039 |
process.disconnect(con1);
|
|
justburner |
64e039 |
process.disconnect(con2);
|
|
justburner |
64e039 |
|
|
justburner |
64e039 |
return result;
|
|
justburner |
64e039 |
}
|
|
justburner |
64e039 |
|
|
justburner |
64e039 |
//-----------------------------------------------------------------------------
|
|
justburner |
64e039 |
|
|
justburner |
64e039 |
} // namespace ThirdParty
|