2016-09-08 18:19:01 +12:00
|
|
|
#include <memory>
|
|
|
|
|
|
|
|
#include "tmachine.h"
|
|
|
|
#include "tsio_mp3.h"
|
|
|
|
#include "tsystem.h"
|
|
|
|
#include "tfilepath_io.h"
|
|
|
|
#include "tsound_t.h"
|
2020-10-11 07:06:49 +13:00
|
|
|
#include "tenv.h"
|
2016-09-08 18:19:01 +12:00
|
|
|
#include "toonz/preferences.h"
|
|
|
|
#include "toonz/toonzfolders.h"
|
|
|
|
#include <QDir>
|
|
|
|
#include <QProcess>
|
|
|
|
|
|
|
|
//==============================================================================
|
|
|
|
|
|
|
|
TSoundTrackReaderMp3::TSoundTrackReaderMp3(const TFilePath &fp)
|
|
|
|
: TSoundTrackReader(fp) {}
|
|
|
|
|
|
|
|
//------------------------------------------------------------------------------
|
|
|
|
|
|
|
|
TSoundTrackP TSoundTrackReaderMp3::load() {
|
|
|
|
FfmpegAudio *ffmepegAudio = new FfmpegAudio();
|
|
|
|
TFilePath tempFile = ffmepegAudio->getRawAudio(m_path);
|
|
|
|
|
|
|
|
Tifstream is(tempFile);
|
|
|
|
|
|
|
|
if (!is)
|
|
|
|
throw TException(L"Unable to load the RAW file " + m_path.getWideString() +
|
|
|
|
L" : doesn't exist");
|
|
|
|
|
|
|
|
is.seekg(0, std::ios_base::end);
|
|
|
|
long sampleCount = is.tellg() / 4;
|
|
|
|
is.seekg(0, std::ios_base::beg);
|
|
|
|
|
|
|
|
TSoundTrack *track = new TSoundTrackStereo16(44100, 2, sampleCount);
|
|
|
|
is.read((char *)track->getRawData(), sampleCount * 4);
|
|
|
|
return track;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool FfmpegAudio::checkFfmpeg() {
|
|
|
|
// check the user defined path in preferences first
|
|
|
|
QString path = Preferences::instance()->getFfmpegPath() + "/ffmpeg";
|
|
|
|
#if defined(_WIN32)
|
|
|
|
path = path + ".exe";
|
|
|
|
#endif
|
|
|
|
if (TSystem::doesExistFileOrLevel(TFilePath(path))) return true;
|
|
|
|
|
2020-11-06 07:51:52 +13:00
|
|
|
// check the Tahoma2D root directory next
|
2016-09-08 18:19:01 +12:00
|
|
|
path = QDir::currentPath() + "/ffmpeg";
|
|
|
|
#if defined(_WIN32)
|
|
|
|
path = path + ".exe";
|
|
|
|
#endif
|
|
|
|
if (TSystem::doesExistFileOrLevel(TFilePath(path))) {
|
2019-12-05 00:44:58 +13:00
|
|
|
Preferences::instance()->setValue(ffmpegPath, QDir::currentPath());
|
2016-09-08 18:19:01 +12:00
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2020-10-11 07:06:49 +13:00
|
|
|
#ifdef MACOSX
|
|
|
|
path = QDir::currentPath() + "/" +
|
|
|
|
QString::fromStdString(TEnv::getApplicationFileName()) +
|
|
|
|
".app/ffmpeg/ffmpeg";
|
|
|
|
if (TSystem::doesExistFileOrLevel(TFilePath(path))) {
|
|
|
|
Preferences::instance()->setValue(
|
|
|
|
ffmpegPath, QDir::currentPath() + "/" +
|
|
|
|
QString::fromStdString(TEnv::getApplicationFileName()) +
|
|
|
|
".app/ffmpeg/");
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
2020-05-23 02:17:41 +12:00
|
|
|
#if defined(LINUX) || defined(FREEBSD)
|
2020-10-11 07:06:49 +13:00
|
|
|
QString currentPath = TEnv::getWorkingDirectory().getQString();
|
|
|
|
path = currentPath + "/ffmpeg/ffmpeg";
|
|
|
|
if (TSystem::doesExistFileOrLevel(TFilePath(path))) {
|
|
|
|
Preferences::instance()->setValue(ffmpegPath, currentPath + "/ffmpeg/");
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
2016-09-08 18:19:01 +12:00
|
|
|
// give up
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
TFilePath FfmpegAudio::getFfmpegCache() {
|
|
|
|
QString cacheRoot = ToonzFolder::getCacheRootFolder().getQString();
|
|
|
|
if (!TSystem::doesExistFileOrLevel(TFilePath(cacheRoot + "/ffmpeg"))) {
|
|
|
|
TSystem::mkDir(TFilePath(cacheRoot + "/ffmpeg"));
|
|
|
|
}
|
|
|
|
std::string ffmpegPath =
|
|
|
|
TFilePath(cacheRoot + "/ffmpeg").getQString().toStdString();
|
|
|
|
return TFilePath(cacheRoot + "/ffmpeg");
|
|
|
|
}
|
|
|
|
|
|
|
|
void FfmpegAudio::runFfmpeg(QStringList args) {
|
|
|
|
// write the file
|
|
|
|
QString m_ffmpegPath = Preferences::instance()->getFfmpegPath();
|
|
|
|
std::string strFfmpegPath = m_ffmpegPath.toStdString();
|
|
|
|
QProcess ffmpeg;
|
|
|
|
ffmpeg.start(m_ffmpegPath + "/ffmpeg", args);
|
|
|
|
ffmpeg.waitForFinished(30000);
|
|
|
|
QString results = ffmpeg.readAllStandardError();
|
|
|
|
results += ffmpeg.readAllStandardOutput();
|
|
|
|
int exitCode = ffmpeg.exitCode();
|
|
|
|
ffmpeg.close();
|
|
|
|
std::string strResults = results.toStdString();
|
|
|
|
}
|
|
|
|
|
|
|
|
TFilePath FfmpegAudio::getRawAudio(TFilePath path) {
|
|
|
|
std::string name = path.getName();
|
|
|
|
TFilePath outPath = getFfmpegCache() + TFilePath(name + ".raw");
|
|
|
|
std::string strPath = path.getQString().toStdString();
|
|
|
|
std::string strOutPath = outPath.getQString().toStdString();
|
|
|
|
QStringList args;
|
|
|
|
args << "-i";
|
|
|
|
args << path.getQString();
|
|
|
|
args << "-f";
|
|
|
|
args << "s16le";
|
|
|
|
args << "-ac";
|
|
|
|
args << "2";
|
|
|
|
args << "-ar";
|
|
|
|
args << "44100";
|
|
|
|
args << "-y";
|
|
|
|
args << outPath.getQString();
|
|
|
|
runFfmpeg(args);
|
|
|
|
return outPath;
|
|
|
|
}
|