Merge pull request #615 from manongjohn/update_external_app_handling

Update external app handling
This commit is contained in:
manongjohn 2021-03-22 17:47:13 -04:00 committed by GitHub
commit 63874b4309
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
24 changed files with 318 additions and 237 deletions

View file

@ -27,7 +27,6 @@ jobs:
/home/runner/.ccache /home/runner/.ccache
/home/runner/work/tahoma2d/taoma2d/thirdparty/openh264 /home/runner/work/tahoma2d/taoma2d/thirdparty/openh264
/home/runner/work/tahoma2d/taoma2d/thirdparty/ffmpeg /home/runner/work/tahoma2d/taoma2d/thirdparty/ffmpeg
/home/runner/work/tahoma2d/taoma2d/thirdparty/ffmpeg_shared
/home/runner/work/tahoma2d/taoma2d/thirdparty/opencv /home/runner/work/tahoma2d/taoma2d/thirdparty/opencv
key: ${{ runner.os }}-${{ matrix.compiler }}-${{ github.sha }} key: ${{ runner.os }}-${{ matrix.compiler }}-${{ github.sha }}
restore-keys: | restore-keys: |
@ -48,6 +47,9 @@ jobs:
export CC="ccache ${{ matrix.cc }}" export CC="ccache ${{ matrix.cc }}"
export CXX="ccache ${{ matrix.cxx }}" export CXX="ccache ${{ matrix.cxx }}"
ci-scripts/linux/tahoma-build.sh ci-scripts/linux/tahoma-build.sh
- name: Get 3rd Party Apps
run: |
ci-scripts/linux/tahoma-get3rdpartyapps.sh
- name: Create Package - name: Create Package
run: | run: |
ci-scripts/linux/tahoma-buildpkg.sh ci-scripts/linux/tahoma-buildpkg.sh

View file

@ -18,7 +18,6 @@ jobs:
/Users/runner/.ccache /Users/runner/.ccache
/Users/runner/work/tahoma2d/taoma2d/thirdparty/aom /Users/runner/work/tahoma2d/taoma2d/thirdparty/aom
/Users/runner/work/tahoma2d/taoma2d/thirdparty/ffmpeg /Users/runner/work/tahoma2d/taoma2d/thirdparty/ffmpeg
/Users/runner/work/tahoma2d/taoma2d/thirdparty/ffmpeg_shared
/Users/runner/work/tahoma2d/taoma2d/thirdparty/opencv /Users/runner/work/tahoma2d/taoma2d/thirdparty/opencv
key: ${{ runner.os }}-${{ github.sha }} key: ${{ runner.os }}-${{ github.sha }}
restore-keys: ${{ runner.os }}- restore-keys: ${{ runner.os }}-
@ -34,6 +33,9 @@ jobs:
run: | run: |
export PATH="/usr/local/opt/ccache/libexec:$PATH" export PATH="/usr/local/opt/ccache/libexec:$PATH"
ci-scripts/osx/tahoma-build.sh ci-scripts/osx/tahoma-build.sh
- name: Get 3rd Party Apps
run: |
ci-scripts/osx/tahoma-get3rdpartyapps.sh
- name: Create Package - name: Create Package
run: bash ./ci-scripts/osx/tahoma-buildpkg.sh run: bash ./ci-scripts/osx/tahoma-buildpkg.sh
- uses: actions/upload-artifact@v1 - uses: actions/upload-artifact@v1

View file

@ -60,6 +60,28 @@ after_build:
xcopy /Y /E ..\..\stuff "%CONFIGURATION%\Tahoma2D\tahomastuff" xcopy /Y /E ..\..\stuff "%CONFIGURATION%\Tahoma2D\tahomastuff"
curl -fsSL -o ffmpeg-4.3.1-win64-static-lgpl.zip https://github.com/tahoma2d/FFmpeg/releases/download/v4.3.1/ffmpeg-4.3.1-win64-static-lgpl.zip
7z x ffmpeg-4.3.1-win64-static-lgpl.zip
mkdir %CONFIGURATION%\Tahoma2D\ffmpeg
copy /Y ffmpeg-4.3.1-win64-static-lgpl\bin\ffmpeg.exe %CONFIGURATION%\Tahoma2D\ffmpeg
copy /Y ffmpeg-4.3.1-win64-static-lgpl\bin\ffprobe.exe %CONFIGURATION%\Tahoma2D\ffmpeg
curl -fsSL -o rhubarb-lip-sync-tahoma2d-win.zip https://github.com/tahoma2d/rhubarb-lip-sync/releases/download/v1.10.2/rhubarb-lip-sync-tahoma2d-win.zip
7z x rhubarb-lip-sync-tahoma2d-win.zip
mkdir %CONFIGURATION%\Tahoma2D\rhubarb
copy /Y rhubarb-lip-sync-tahoma2d-win\rhubarb.exe %CONFIGURATION%\Tahoma2D\rhubarb
mkdir %CONFIGURATION%\Tahoma2D\rhubarb\res
xcopy /Y /E rhubarb-lip-sync-tahoma2d-win\res "%CONFIGURATION%\Tahoma2D\rhubarb\res"
artifacts: artifacts:
- path: toonz\$(PLATFORM)\$(CONFIGURATION) - path: toonz\$(PLATFORM)\$(CONFIGURATION)
name: Tahoma2D name: Tahoma2D

View file

@ -1,3 +1,4 @@
#!/bin/bash
cd thirdparty cd thirdparty
echo ">>> Cloning openH264" echo ">>> Cloning openH264"
@ -15,10 +16,9 @@ sudo make install
cd .. cd ..
echo ">>> Cloning ffmpeg" echo ">>> Cloning ffmpeg"
git clone https://git.ffmpeg.org/ffmpeg.git ffmpeg git clone https://github.com/tahoma2d/ffmpeg ffmpeg
cp -R ffmpeg ffmpeg_shared
cd ffmpeg_shared cd ffmpeg
echo "*" >| .gitignore echo "*" >| .gitignore
echo ">>> Configuring to build ffmpeg (shared)" echo ">>> Configuring to build ffmpeg (shared)"
@ -65,56 +65,3 @@ echo ">>> Installing ffmpeg (shared)"
sudo make install sudo make install
sudo ldconfig sudo ldconfig
echo ">>> Configuring to build ffmpeg (static)"
cd ../ffmpeg
echo "*" >| .gitignore
export PKG_CONFIG_PATH=/usr/local/lib/pkgconfig
./configure --prefix=/usr/local \
--cc="$CC" \
--cxx="$CXX" \
--pkg-config-flags="--static" \
--extra-cflags="-I/usr/local/include -static" \
--extra-ldflags="-L/usr/local/lib -static" \
--extra-ldexeflags="-static" \
--enable-static \
--enable-cross-compile \
--enable-pic \
--disable-shared \
--enable-libopenh264 \
--enable-pthreads \
--enable-version3 \
--enable-avresample \
--enable-libmp3lame \
--enable-libopus \
--enable-libsnappy \
--enable-libtheora \
--enable-libvorbis \
--enable-libvpx \
--enable-libwebp \
--enable-lzma \
--enable-libfreetype \
--enable-libopencore-amrnb \
--enable-libopencore-amrwb \
--enable-libspeex \
--disable-ffplay \
--disable-htmlpages \
--disable-manpages \
--disable-podpages \
--disable-txtpages \
--disable-libjack \
--disable-indev=jack
echo ">>> Building ffmpeg (static)"
make
echo ">>> Installing to tahoma2d/thirdparty/ffmpeg/bin"
if [ ! -d bin ]
then
mkdir bin
fi
cp ffmpeg ffprobe bin/

View file

@ -1,7 +1,8 @@
#!/bin/bash
cd thirdparty cd thirdparty
echo ">>> Cloning opencv" echo ">>> Cloning opencv"
git clone https://github.com/opencv/opencv.git git clone https://github.com/tahoma2d/opencv
cd opencv cd opencv
echo "*" >| .gitignore echo "*" >| .gitignore

View file

@ -35,14 +35,26 @@ mv appdir/usr/share/tahoma2d/stuff Tahoma2D/tahomastuff
chmod -R 777 Tahoma2D/tahomastuff chmod -R 777 Tahoma2D/tahomastuff
rmdir appdir/usr/share/tahoma2d rmdir appdir/usr/share/tahoma2d
if [ -d ../../thirdparty/ffmpeg/bin ] if [ -d ../../thirdparty/apps/ffmpeg/bin ]
then then
echo ">>> Copying FFmpeg to Tahoma2D/ffmpeg" echo ">>> Copying FFmpeg to Tahoma2D/ffmpeg"
if [ -d Tahoma2D/ffmpeg ] if [ -d Tahoma2D/ffmpeg ]
then then
rm -rf Tahoma2D/ffmpeg rm -rf Tahoma2D/ffmpeg
fi fi
cp -R ../../thirdparty/ffmpeg/bin Tahoma2D/ffmpeg mkdir -p Tahoma2D/ffmpeg
cp -R ../../thirdparty/apps/ffmpeg/bin/ffmpeg ../../thirdparty/apps/ffmpeg/bin/ffprobe Tahoma2D/ffmpeg
fi
if [ -d ../../thirdparty/apps/rhubarb ]
then
echo ">>> Copying Rhubarb Lip Sync to Tahoma2D/rhubarb"
if [ -d Tahoma2D/rhubarb ]
then
rm -rf Tahoma2D/rhubarb
fi
mkdir -p Tahoma2D/rhubarb
cp -R ../../thirdparty/apps/rhubarb/rhubarb ../../thirdparty/apps/rhubarb/res Tahoma2D/rhubarb
fi fi
echo ">>> Creating Tahoma2D/Tahoma2D.AppImage" echo ">>> Creating Tahoma2D/Tahoma2D.AppImage"

View file

@ -0,0 +1,28 @@
#!/bin/bash
cd thirdparty
if [ ! -d apps ]
then
mkdir apps
fi
cd apps
echo "*" >| .gitignore
echo ">>> Getting FFmpeg"
if [ -d ffmpeg ]
then
rm -rf ffmpeg
fi
wget https://github.com/tahoma2d/FFmpeg/releases/download/v4.3.1/ffmpeg-4.3.1-linux-static-lgpl.zip
unzip ffmpeg-4.3.1-linux-static-lgpl.zip
mv ffmpeg-4.3.1-linux-static-lgpl ffmpeg
echo ">>> Getting Rhubarb Lip Sync"
if [ -d rhubarb ]
then
rm -rf rhubarb ]
fi
wget https://github.com/tahoma2d/rhubarb-lip-sync/releases/download/v1.10.2/rhubarb-lip-sync-tahoma2d-linux.zip
unzip rhubarb-lip-sync-tahoma2d-linux.zip -d rhubarb

View file

@ -1,3 +1,4 @@
#!/bin/bash
sudo add-apt-repository --yes ppa:beineri/opt-qt597-xenial sudo add-apt-repository --yes ppa:beineri/opt-qt597-xenial
sudo add-apt-repository --yes ppa:achadwick/mypaint-testing sudo add-apt-repository --yes ppa:achadwick/mypaint-testing
sudo apt-get update sudo apt-get update

View file

@ -1,3 +1,4 @@
#!/bin/bash
cd thirdparty cd thirdparty
echo ">>> Cloning aom" echo ">>> Cloning aom"
@ -25,10 +26,9 @@ sudo make install
cd ../.. cd ../..
echo ">>> Cloning ffmpeg" echo ">>> Cloning ffmpeg"
git clone https://git.ffmpeg.org/ffmpeg.git ffmpeg git clone https://github.com/tahoma2d/ffmpeg
cp -R ffmpeg ffmpeg_shared
cd ffmpeg_shared cd ffmpeg
echo "*" >| .gitignore echo "*" >| .gitignore
echo ">>> Configuring to build ffmpeg (shared)" echo ">>> Configuring to build ffmpeg (shared)"
@ -73,37 +73,3 @@ make -j7 # runs 7 jobs in parallel
echo ">>> Installing ffmpeg (shared)" echo ">>> Installing ffmpeg (shared)"
sudo make install sudo make install
echo ">>> Configuring to build ffmpeg (static)"
cd ../ffmpeg
echo "*" >| .gitignore
export PKG_CONFIG_PATH=/usr/local/lib/pkgconfig
export SDKROOT=`xcrun --show-sdk-path`
./configure --prefix=/usr/local \
--pkg-config-flags="--static" \
--enable-static \
--disable-shared \
--enable-pic \
--enable-pthreads \
--enable-version3 \
--enable-videotoolbox \
--enable-avresample \
--enable-libaom \
--enable-libxml2 \
--enable-libvpx \
--disable-ffplay \
--disable-sdl2 \
--disable-libjack \
--disable-libxcb \
--disable-indev=jack
echo ">>> Building ffmpeg (static)"
make -j7 # runs 7 jobs in parallel
echo ">>> Installing to tahoma2d/thirdparty/ffmpeg/bin"
if [ ! -d bin ]
then
mkdir bin
fi
cp ffmpeg ffprobe bin/

View file

@ -1,7 +1,8 @@
#!/bin/bash
cd thirdparty cd thirdparty
echo ">>> Cloning opencv" echo ">>> Cloning opencv"
git clone https://github.com/opencv/opencv.git git clone https://github.com/tahoma2d/opencv
cd opencv cd opencv
echo "*" >| .gitignore echo "*" >| .gitignore

View file

@ -22,7 +22,7 @@ fi
cp -R stuff $TOONZDIR/Tahoma2D.app/tahomastuff cp -R stuff $TOONZDIR/Tahoma2D.app/tahomastuff
chmod -R 777 $TOONZDIR/Tahoma2D.app/tahomastuff chmod -R 777 $TOONZDIR/Tahoma2D.app/tahomastuff
if [ -d thirdparty/ffmpeg/bin ] if [ -d thirdparty/apps/ffmpeg/bin ]
then then
echo ">>> Copying FFmpeg to $TOONZDIR/Tahoma2D.app/ffmpeg" echo ">>> Copying FFmpeg to $TOONZDIR/Tahoma2D.app/ffmpeg"
if [ -d $TOONZDIR/Tahoma2D.app/ffmpeg ] if [ -d $TOONZDIR/Tahoma2D.app/ffmpeg ]
@ -30,7 +30,20 @@ then
# In case of prior builds, replace ffmpeg folder # In case of prior builds, replace ffmpeg folder
rm -rf $TOONZDIR/Tahoma2D.app/ffmpeg rm -rf $TOONZDIR/Tahoma2D.app/ffmpeg
fi fi
cp -R thirdparty/ffmpeg/bin $TOONZDIR/Tahoma2D.app/ffmpeg mkdir $TOONZDIR/Tahoma2D.app/ffmpeg
cp -R thirdparty/apps/ffmpeg/bin/ffmpeg thirdparty/apps/ffmpeg/bin/ffprobe $TOONZDIR/Tahoma2D.app/ffmpeg
fi
if [ -d thirdparty/apps/rhubarb ]
then
echo ">>> Copying Rhubarb Lip Sync to $TOONZDIR/Tahoma2D.app/rhubarb"
if [ -d $TOONZDIR/Tahoma2D.app/rhubarb ]
then
# In case of prior builds, replace rhubarb folder
rm -rf $TOONZDIR/Tahoma2D.app/rhubarb
fi
mkdir $TOONZDIR/Tahoma2D.app/rhubarb
cp -R thirdparty/apps/rhubarb/rhubarb thirdparty/apps/rhubarb/res $TOONZDIR/Tahoma2D.app/rhubarb
fi fi
if [ -d thirdparty/canon/Framework ] if [ -d thirdparty/canon/Framework ]
@ -77,3 +90,4 @@ echo ">>> Creating Tahoma2D-osx.dmg"
$QTDIR/bin/macdeployqt $TOONZDIR/Tahoma2D.app -dmg -verbose=0 $QTDIR/bin/macdeployqt $TOONZDIR/Tahoma2D.app -dmg -verbose=0
mv $TOONZDIR/Tahoma2D.dmg $TOONZDIR/../Tahoma2D-osx.dmg mv $TOONZDIR/Tahoma2D.dmg $TOONZDIR/../Tahoma2D-osx.dmg

View file

@ -0,0 +1,28 @@
#!/bin/bash
cd thirdparty
if [ ! -d apps ]
then
mkdir apps
fi
cd apps
echo "*" >| .gitignore
echo ">>> Getting FFmpeg"
if [ -d ffmpeg ]
then
rm -rf ffmpeg
fi
wget https://github.com/tahoma2d/FFmpeg/releases/download/v4.3.1/ffmpeg-4.3.1-macos64-static-lgpl.zip
unzip ffmpeg-4.3.1-macos64-static-lgpl.zip
mv ffmpeg-4.3.1-macos64-static-lgpl ffmpeg
echo ">>> Getting Rhubarb Lip Sync"
if [ -d rhubarb ]
then
rm -rf rhubarb
fi
wget https://github.com/tahoma2d/rhubarb-lip-sync/releases/download/v1.10.2/rhubarb-lip-sync-tahoma2d-osx.zip
unzip rhubarb-lip-sync-tahoma2d-osx.zip -d rhubarb

View file

@ -0,0 +1,9 @@
Rhubarb Lip Sync is released under the MIT License (MIT).
Copyright (c) 2015-2016 Daniel Wolf
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

View file

@ -0,0 +1,7 @@
Tahoma2D ships with Rhubarb Lip Sync, and uses Rhubarb Lip Sync through command line commands.
Tahoma2D does not directly use Rhubarb Lip Sync libraries or code.
Rhubarb Lip Sync source code can be found at:
https://github.com/tahoma2d/rhubarb-lip-sync
or
https://github.com/DanielSWolf/rhubarb-lip-sync

View file

@ -1044,6 +1044,20 @@ bool TSystem::showDocument(const TFilePath &path) {
#endif #endif
} }
QString TSystem::findFileLocation(QStringList folderList, QString fileName) {
if (folderList.isEmpty()) return "";
QStringList::iterator it;
for (it = folderList.begin(); it != folderList.end(); it++) {
QString path = *it + "/" + fileName;
TFilePath fp(path);
if (TSystem::doesExistFileOrLevel(fp) && !TFileStatus(fp).isDirectory())
return *it;
}
return "";
}
#else #else
#include <windows.h> #include <windows.h>

View file

@ -14,94 +14,87 @@
Ffmpeg::Ffmpeg() { Ffmpeg::Ffmpeg() {
m_ffmpegPath = Preferences::instance()->getFfmpegPath(); m_ffmpegPath = Preferences::instance()->getFfmpegPath();
m_ffmpegTimeout = Preferences::instance()->getFfmpegTimeout() * 1000; m_ffmpegTimeout = Preferences::instance()->getFfmpegTimeout();
if (m_ffmpegTimeout > 0)
m_ffmpegTimeout * 1000;
else
m_ffmpegTimeout = -1;
std::string strPath = m_ffmpegPath.toStdString(); std::string strPath = m_ffmpegPath.toStdString();
m_intermediateFormat = "png"; m_intermediateFormat = "png";
} }
Ffmpeg::~Ffmpeg() {} Ffmpeg::~Ffmpeg() {}
bool Ffmpeg::checkFfmpeg() { bool Ffmpeg::checkFfmpeg() {
// check the user defined path in preferences first QString exe = "ffmpeg";
QString path = Preferences::instance()->getFfmpegPath() + "/ffmpeg";
#if defined(_WIN32) #if defined(_WIN32)
path = path + ".exe"; exe = exe + ".exe";
#endif #endif
// check the user defined path in preferences first
QString path = Preferences::instance()->getFfmpegPath() + "/" + exe;
if (TSystem::doesExistFileOrLevel(TFilePath(path))) return true; if (TSystem::doesExistFileOrLevel(TFilePath(path))) return true;
// check the Tahoma root directory next // Let's try and autodetect the exe included with release
path = QDir::currentPath() + "/ffmpeg"; QStringList folderList;
#if defined(_WIN32)
path = path + ".exe"; folderList.append(".");
#endif folderList.append("./ffmpeg"); // ffmpeg folder
if (TSystem::doesExistFileOrLevel(TFilePath(path))) {
Preferences::instance()->setValue(ffmpegPath, QDir::currentPath());
return true;
}
#ifdef MACOSX #ifdef MACOSX
path = QDir::currentPath() + "/" + // Look inside app
folderList.append("./" +
QString::fromStdString(TEnv::getApplicationFileName()) + QString::fromStdString(TEnv::getApplicationFileName()) +
".app/ffmpeg/ffmpeg"; ".app/ffmpeg"); // ffmpeg folder
if (TSystem::doesExistFileOrLevel(TFilePath(path))) { #elif defined LINUX
Preferences::instance()->setValue( // Need to account for symbolic links
ffmpegPath, QDir::currentPath() + "/" + folderList.append(TEnv::getWorkingDirectory().getQString() +
QString::fromStdString(TEnv::getApplicationFileName()) + "/ffmpeg"); // ffmpeg folder
".app/ffmpeg/");
return true;
}
#endif #endif
#ifdef LINUX QString exePath = TSystem::findFileLocation(folderList, exe);
QString currentPath = TEnv::getWorkingDirectory().getQString();
path = currentPath + "/ffmpeg/ffmpeg"; if (!exePath.isEmpty()) {
if (TSystem::doesExistFileOrLevel(TFilePath(path))) { Preferences::instance()->setValue(ffmpegPath, exePath);
Preferences::instance()->setValue(ffmpegPath, currentPath + "/ffmpeg/");
return true; return true;
} }
#endif
// give up // give up
return false; return false;
} }
bool Ffmpeg::checkFfprobe() { bool Ffmpeg::checkFfprobe() {
// check the user defined path in preferences first QString exe = "ffprobe";
QString path = Preferences::instance()->getFfmpegPath() + "/ffprobe";
#if defined(_WIN32) #if defined(_WIN32)
path = path + ".exe"; exe = exe + ".exe";
#endif #endif
// check the user defined path in preferences first
QString path = Preferences::instance()->getFfmpegPath() + "/" + exe;
if (TSystem::doesExistFileOrLevel(TFilePath(path))) return true; if (TSystem::doesExistFileOrLevel(TFilePath(path))) return true;
// check the Tahoma root directory next // Let's try and autodetect the exe included with release
path = QDir::currentPath() + "/ffprobe"; QStringList folderList;
#if defined(_WIN32)
path = path + ".exe"; folderList.append(".");
#endif folderList.append("./ffmpeg"); // ffmpeg folder
if (TSystem::doesExistFileOrLevel(TFilePath(path))) {
Preferences::instance()->setValue(ffmpegPath, QDir::currentPath());
return true;
}
#ifdef MACOSX #ifdef MACOSX
path = QDir::currentPath() + "/" + // Look inside app
folderList.append("./" +
QString::fromStdString(TEnv::getApplicationFileName()) + QString::fromStdString(TEnv::getApplicationFileName()) +
".app/ffmpeg/ffprobe"; ".app/ffmpeg"); // ffmpeg folder
if (TSystem::doesExistFileOrLevel(TFilePath(path))) { #elif defined LINUX
Preferences::instance()->setValue( // Need to account for symbolic links
ffmpegPath, QDir::currentPath() + "/" + folderList.append(TEnv::getWorkingDirectory().getQString() +
QString::fromStdString(TEnv::getApplicationFileName()) + "/ffmpeg"); // ffmpeg folder
".app/ffmpeg/");
return true;
}
#endif #endif
#ifdef LINUX QString exePath = TSystem::findFileLocation(folderList, exe);
QString currentPath = TEnv::getWorkingDirectory().getQString();
path = currentPath + "/ffmpeg/ffprobe"; if (!exePath.isEmpty()) {
if (TSystem::doesExistFileOrLevel(TFilePath(path))) { Preferences::instance()->setValue(ffmpegPath, exePath);
Preferences::instance()->setValue(ffmpegPath, currentPath + "/ffmpeg/");
return true; return true;
} }
#endif
// give up // give up
return false; return false;

View file

@ -46,7 +46,7 @@ public:
private: private:
QString m_intermediateFormat, m_ffmpegPath, m_audioPath, m_audioFormat; QString m_intermediateFormat, m_ffmpegPath, m_audioPath, m_audioFormat;
int m_frameCount = 0, m_lx, m_ly, m_bpp, m_bitsPerSample, m_channelCount, int m_frameCount = 0, m_lx, m_ly, m_bpp, m_bitsPerSample, m_channelCount,
m_ffmpegTimeout = 30000, m_frameNumberOffset = -1; m_ffmpegTimeout = -1, m_frameNumberOffset = -1;
double m_frameRate = 24.0; double m_frameRate = 24.0;
bool m_ffmpegExists = false, m_ffprobeExists = false, m_hasSoundTrack = false; bool m_ffmpegExists = false, m_ffprobeExists = false, m_hasSoundTrack = false;
TFilePath m_path; TFilePath m_path;

View file

@ -282,6 +282,8 @@ public:
QString getFfmpegPath() const { return getStringValue(ffmpegPath); } QString getFfmpegPath() const { return getStringValue(ffmpegPath); }
int getFfmpegTimeout() { return getIntValue(ffmpegTimeout); } int getFfmpegTimeout() { return getIntValue(ffmpegTimeout); }
QString getFastRenderPath() const { return getStringValue(fastRenderPath); } QString getFastRenderPath() const { return getStringValue(fastRenderPath); }
QString getRhubarbPath() const { return getStringValue(rhubarbPath); }
int getRhubarbTimeout() { return getIntValue(rhubarbTimeout); }
// Drawing tab // Drawing tab
QString getScanLevelType() const { return getStringValue(scanLevelType); } QString getScanLevelType() const { return getStringValue(scanLevelType); }

View file

@ -74,6 +74,8 @@ enum PreferencesItemId {
ffmpegPath, ffmpegPath,
ffmpegTimeout, ffmpegTimeout,
fastRenderPath, fastRenderPath,
rhubarbPath,
rhubarbTimeout,
//---------- //----------
// Drawing // Drawing

View file

@ -263,6 +263,8 @@ DVAPI TFilePath toLocalPath(const TFilePath &fp);
DVAPI bool showDocument(const TFilePath &fp); DVAPI bool showDocument(const TFilePath &fp);
DVAPI QString findFileLocation(QStringList folderList, QString fileName);
#ifndef TNZCORE_LIGHT #ifndef TNZCORE_LIGHT
DVAPI QDateTime getFileTime(const TFilePath &path); DVAPI QDateTime getFileTime(const TFilePath &path);
DVAPI QString getHostName(); DVAPI QString getHostName();

View file

@ -433,7 +433,7 @@ LipSyncPopup::LipSyncPopup()
QHBoxLayout *optionsLay = new QHBoxLayout(this); QHBoxLayout *optionsLay = new QHBoxLayout(this);
optionsLay->setMargin(10); optionsLay->setMargin(10);
optionsLay->setSpacing(15); optionsLay->setSpacing(15);
QHBoxLayout* insertAtLay = new QHBoxLayout(this); QHBoxLayout *insertAtLay = new QHBoxLayout(this);
insertAtLay->setMargin(0); insertAtLay->setMargin(0);
insertAtLay->setSpacing(4); insertAtLay->setSpacing(4);
m_insertAtLabel = new QLabel(tr("Insert at Frame: ")); m_insertAtLabel = new QLabel(tr("Insert at Frame: "));
@ -477,6 +477,8 @@ LipSyncPopup::LipSyncPopup()
SLOT(setPage(int))); SLOT(setPage(int)));
assert(ret); assert(ret);
m_rhubarbPath = "";
} }
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
@ -515,6 +517,9 @@ void LipSyncPopup::showEvent(QShowEvent *) {
m_isEditingLevel = app->getCurrentFrame()->isEditingLevel(); m_isEditingLevel = app->getCurrentFrame()->isEditingLevel();
m_startAt->setValue(row + 1); m_startAt->setValue(row + 1);
m_startAt->clearFocus(); m_startAt->clearFocus();
if (checkRhubarb()) m_rhubarbPath = Preferences::instance()->getRhubarbPath();
TXshLevelHandle *level = app->getCurrentLevel(); TXshLevelHandle *level = app->getCurrentLevel();
m_sl = level->getSimpleLevel(); m_sl = level->getSimpleLevel();
if (!m_sl) { if (!m_sl) {
@ -548,7 +553,6 @@ void LipSyncPopup::showEvent(QShowEvent *) {
} }
refreshSoundLevels(); refreshSoundLevels();
onLevelChanged(-1); onLevelChanged(-1);
findRhubarb();
} }
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
@ -686,53 +690,47 @@ void LipSyncPopup::saveAudio() {
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
QString LipSyncPopup::findRhubarb() { bool LipSyncPopup::checkRhubarb() {
QString path = QDir::currentPath() + "/rhubarb/rhubarb"; QString exe = "rhubarb";
bool found = false;
#if defined(_WIN32) #if defined(_WIN32)
path = path + ".exe"; exe = exe + ".exe";
#endif #endif
// check the user defined path in preferences first
QString path = Preferences::instance()->getRhubarbPath() + "/" + exe;
if (TSystem::doesExistFileOrLevel(TFilePath(path))) return true;
// Let's try and autodetect the exe included with release
QStringList folderList;
folderList.append(".");
folderList.append("./rhubarb"); // rhubarb folder
#ifdef MACOSX #ifdef MACOSX
path = QDir::currentPath() + "/" + // Look inside app
folderList.append("./" +
QString::fromStdString(TEnv::getApplicationFileName()) + QString::fromStdString(TEnv::getApplicationFileName()) +
".app/rhubarb/rhubarb"; ".app/rhubarb"); // rhubarb folder
if (TSystem::doesExistFileOrLevel(TFilePath(path))) { #elif defined LINUX
found = true; // Need to account for symbolic links
} folderList.append(TEnv::getWorkingDirectory().getQString() +
"/rhubarb"); // rhubarb folder
#endif #endif
std::string sPath = path.toStdString(); QString exePath = TSystem::findFileLocation(folderList, exe);
if (!found && TSystem::doesExistFileOrLevel(TFilePath(path))) {
found = true; if (!exePath.isEmpty()) {
Preferences::instance()->setValue(rhubarbPath, exePath);
return true;
} }
if (found) { // give up
m_tabBarContainer->show(); return false;
if (m_tabBar->currentIndex() != m_stackedChooser->currentIndex())
m_tabBar->setCurrentIndex(m_stackedChooser->currentIndex());
int index = m_soundLevels->currentIndex();
int count = m_soundLevels->count();
if (index == count - 1) {
m_audioFile->show();
} else {
m_audioFile->hide();
}
setPage(m_stackedChooser->currentIndex());
return path;
} else {
m_tabBarContainer->hide();
setPage(1);
return QString("");
}
} }
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
void LipSyncPopup::runRhubarb() { void LipSyncPopup::runRhubarb() {
QString path = findRhubarb();
QString cacheRoot = ToonzFolder::getCacheRootFolder().getQString(); QString cacheRoot = ToonzFolder::getCacheRootFolder().getQString();
if (!TSystem::doesExistFileOrLevel(TFilePath(cacheRoot + "/rhubarb"))) { if (!TSystem::doesExistFileOrLevel(TFilePath(cacheRoot + "/rhubarb"))) {
TSystem::mkDir(TFilePath(cacheRoot + "/rhubarb")); TSystem::mkDir(TFilePath(cacheRoot + "/rhubarb"));
@ -772,17 +770,35 @@ void LipSyncPopup::runRhubarb() {
m_progressDialog->show(); m_progressDialog->show();
connect(m_rhubarb, &QProcess::readyReadStandardError, this, connect(m_rhubarb, &QProcess::readyReadStandardError, this,
&LipSyncPopup::onOutputReady); &LipSyncPopup::onOutputReady);
m_rhubarb->start(path, args);
QString rhubarbExe = m_rhubarbPath + "/rhubarb";
#ifdef _WIN32
rhubarbExe = rhubarbExe + ".exe";
#endif
m_rhubarb->start(rhubarbExe, args);
} }
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
void LipSyncPopup::onOutputReady() { void LipSyncPopup::onOutputReady() {
QString output = m_rhubarb->readAllStandardError().simplified(); QString output = m_rhubarb->readAllStandardError().simplified();
int index = output.lastIndexOf("%"); output = output.replace("\\n", "\n")
QString newString = output.mid(index - 2, 2); .replace("\\\\", "\\")
m_progressDialog->setValue(newString.toInt()); .replace("\\\"", "")
qDebug() << "output: " << output; .replace("\"", "");
QStringList outputList =
output.mid(2, (output.size() - 4)).split(", ", QString::SkipEmptyParts);
if (outputList.size()) {
QStringList outputType = outputList.at(0).split(": ");
if (outputType.at(1) == "progress") {
QStringList outputValue = outputList.at(1).split(": ");
double progress = outputValue.at(1).toDouble() * 100.0;
m_progressDialog->setValue(progress);
} else if (outputType.at(1) == "failure") {
QStringList outputReason = outputList.at(1).split(": ");
DVGui::warning(tr("Rhubarb Processing Error:\n\n") + outputReason.at(1));
}
}
} }
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
@ -811,8 +827,19 @@ void LipSyncPopup::onApplyButton() {
if (m_stackedChooser->currentIndex() == 0) { if (m_stackedChooser->currentIndex() == 0) {
bool hasAudio = setAudioFile(); bool hasAudio = setAudioFile();
if (!hasAudio) return; if (!hasAudio) return;
if (m_rhubarbPath.isEmpty() || m_rhubarbPath.isNull()) {
DVGui::warning(
tr("Rhubarb not found, please set the location in Preferences and "
"restart."));
return;
}
runRhubarb(); runRhubarb();
m_rhubarb->waitForFinished(); int rhubarbTimeout = Preferences::instance()->getRhubarbTimeout();
if (rhubarbTimeout > 0)
rhubarbTimeout * 1000;
else
rhubarbTimeout = -1;
m_rhubarb->waitForFinished(rhubarbTimeout);
m_progressDialog->hide(); m_progressDialog->hide();
QString results = m_rhubarb->readAllStandardError(); QString results = m_rhubarb->readAllStandardError();
results += m_rhubarb->readAllStandardOutput(); results += m_rhubarb->readAllStandardOutput();
@ -820,12 +847,8 @@ void LipSyncPopup::onApplyButton() {
int exitCode = -1; int exitCode = -1;
if (m_rhubarb->exitStatus() == QProcess::NormalExit) { if (m_rhubarb->exitStatus() == QProcess::NormalExit) {
exitCode = m_rhubarb->exitCode(); exitCode = m_rhubarb->exitCode();
if (exitCode != 0) { // onOuputReady will handle displaying any error messages from rhubarb
DVGui::warning( if (exitCode != 0) return;
tr("An error occurred processing the audio. Please check the audio "
"and try again."));
return;
}
} }
std::string strResults = results.toStdString(); std::string strResults = results.toStdString();
m_startAt->setValue(std::max(1, m_startFrame)); m_startAt->setValue(std::max(1, m_startFrame));

View file

@ -78,6 +78,7 @@ class LipSyncPopup final : public DVGui::Dialog {
bool m_deleteFile = false; bool m_deleteFile = false;
DVGui::ProgressDialog *m_progressDialog; DVGui::ProgressDialog *m_progressDialog;
QProcess *m_rhubarb; QProcess *m_rhubarb;
QString m_rhubarbPath;
QFrame *m_audioFrame; QFrame *m_audioFrame;
QFrame *m_dataFrame; QFrame *m_dataFrame;
QStackedWidget *m_stackedChooser; QStackedWidget *m_stackedChooser;
@ -93,7 +94,7 @@ protected:
void refreshSoundLevels(); void refreshSoundLevels();
void saveAudio(); void saveAudio();
void runRhubarb(); void runRhubarb();
QString findRhubarb(); bool checkRhubarb();
public slots: public slots:
void onApplyButton(); void onApplyButton();

View file

@ -1042,9 +1042,11 @@ QString PreferencesPopup::getUIString(PreferencesItemId id) {
{defaultProjectPath, tr("Default Project Path:")}, {defaultProjectPath, tr("Default Project Path:")},
// Import / Export // Import / Export
{ffmpegPath, tr("FFmpeg Path:")}, {ffmpegPath, tr("Executable Directory:")},
{ffmpegTimeout, tr("FFmpeg Timeout:")}, {ffmpegTimeout, tr("Import/Export Timeout (seconds):")},
{fastRenderPath, tr("Fast Render Path:")}, {fastRenderPath, tr("Fast Render Output Directory:")},
{rhubarbPath, tr("Executable Directory:")},
{rhubarbTimeout, tr("Analyze Audio Timeout (seconds):")},
// Drawing // Drawing
{scanLevelType, tr("Scan File Format:")}, {scanLevelType, tr("Scan File Format:")},
@ -1269,9 +1271,9 @@ PreferencesPopup::PreferencesPopup()
m_categoryList = new QListWidget(this); m_categoryList = new QListWidget(this);
QStringList categories; QStringList categories;
categories << tr("General") << tr("Interface") << tr("Visualization") categories << tr("General") << tr("Interface") << tr("Visualization")
<< tr("Loading") << tr("Saving") << tr("Import/Export") << tr("Loading") << tr("Saving") << tr("Drawing") << tr("Tools")
<< tr("Drawing") << tr("Tools") << tr("Scene") << tr("Animation") << tr("Scene") << tr("Animation") << tr("Preview")
<< tr("Preview") << tr("Onion Skin") << tr("Colors") << tr("Onion Skin") << tr("Colors") << tr("3rd Party Apps")
<< tr("Version Control") << tr("Touch/Tablet Settings"); << tr("Version Control") << tr("Touch/Tablet Settings");
m_categoryList->addItems(categories); m_categoryList->addItems(categories);
m_categoryList->setFixedWidth(160); m_categoryList->setFixedWidth(160);
@ -1284,7 +1286,6 @@ PreferencesPopup::PreferencesPopup()
m_stackedWidget->addWidget(createVisualizationPage()); m_stackedWidget->addWidget(createVisualizationPage());
m_stackedWidget->addWidget(createLoadingPage()); m_stackedWidget->addWidget(createLoadingPage());
m_stackedWidget->addWidget(createSavingPage()); m_stackedWidget->addWidget(createSavingPage());
m_stackedWidget->addWidget(createImportExportPage());
m_stackedWidget->addWidget(createDrawingPage()); m_stackedWidget->addWidget(createDrawingPage());
m_stackedWidget->addWidget(createToolsPage()); m_stackedWidget->addWidget(createToolsPage());
m_stackedWidget->addWidget(createXsheetPage()); m_stackedWidget->addWidget(createXsheetPage());
@ -1292,6 +1293,7 @@ PreferencesPopup::PreferencesPopup()
m_stackedWidget->addWidget(createPreviewPage()); m_stackedWidget->addWidget(createPreviewPage());
m_stackedWidget->addWidget(createOnionSkinPage()); m_stackedWidget->addWidget(createOnionSkinPage());
m_stackedWidget->addWidget(createColorsPage()); m_stackedWidget->addWidget(createColorsPage());
m_stackedWidget->addWidget(createImportExportPage());
m_stackedWidget->addWidget(createVersionControlPage()); m_stackedWidget->addWidget(createVersionControlPage());
m_stackedWidget->addWidget(createTouchTabletPage()); m_stackedWidget->addWidget(createTouchTabletPage());
// createImportPrefsPage() must always be last // createImportPrefsPage() must always be last
@ -1603,6 +1605,8 @@ QWidget* PreferencesPopup::createSavingPage() {
insertUI(resetUndoOnSavingLevel, lay); insertUI(resetUndoOnSavingLevel, lay);
insertUI(doNotShowPopupSaveScene, lay); insertUI(doNotShowPopupSaveScene, lay);
insertUI(fastRenderPath, lay);
lay->setRowStretch(lay->rowCount(), 1); lay->setRowStretch(lay->rowCount(), 1);
widget->setLayout(lay); widget->setLayout(lay);
return widget; return widget;
@ -1619,26 +1623,21 @@ QWidget* PreferencesPopup::createImportExportPage() {
QWidget* widget = new QWidget(this); QWidget* widget = new QWidget(this);
QGridLayout* lay = new QGridLayout(); QGridLayout* lay = new QGridLayout();
setupLayout(lay); setupLayout(lay);
putLabel(tr("External applications used by Tahoma2D.\nThese come bundled "
"with Tahoma2D, but you can set path to a different version."),
lay);
putLabel( QGridLayout* ffmpegOptionsLay = insertGroupBox(tr("FFmpeg"), lay);
tr("Tahoma2D can use FFmpeg for additional file formats.\n") + {
tr("FFmpeg is bundled with Tahoma2D,\n") + insertUI(ffmpegPath, ffmpegOptionsLay);
tr("but you can provide the path to a different ffmpeg location."), insertUI(ffmpegTimeout, ffmpegOptionsLay);
lay); }
insertUI(ffmpegPath, lay);
putLabel(tr("Number of seconds to wait for FFmpeg to complete processing the " QGridLayout* rhubarbOptionsLay = insertGroupBox(tr("Rhubarb Lip Sync"), lay);
"output:"), {
lay); insertUI(rhubarbPath, rhubarbOptionsLay);
putLabel( insertUI(rhubarbTimeout, rhubarbOptionsLay);
tr("Note: FFmpeg begins working once all images have been processed."), }
lay);
insertUI(ffmpegTimeout, lay);
putLabel(tr("Please indicate where you would like exports from Fast "
"Render (MP4) to go."),
lay);
insertUI(fastRenderPath, lay);
lay->setRowStretch(lay->rowCount(), 1); lay->setRowStretch(lay->rowCount(), 1);
insertFootNote(lay); insertFootNote(lay);
@ -2135,6 +2134,7 @@ void PreferencesPopup::onImport() {
srcDir.getQString()); srcDir.getQString());
else { else {
QString origFfmpegPath = Preferences::instance()->getFfmpegPath(); QString origFfmpegPath = Preferences::instance()->getFfmpegPath();
QString origRhubarbPath = Preferences::instance()->getRhubarbPath();
QFileInfoList fil = QDir(toQString(srcDir)).entryInfoList(); QFileInfoList fil = QDir(toQString(srcDir)).entryInfoList();
int i; int i;
@ -2155,6 +2155,7 @@ void PreferencesPopup::onImport() {
// it to find it again otherwise it will point to old location // it to find it again otherwise it will point to old location
Preferences::instance()->load(); Preferences::instance()->load();
Preferences::instance()->setValue(ffmpegPath, origFfmpegPath); Preferences::instance()->setValue(ffmpegPath, origFfmpegPath);
Preferences::instance()->setValue(rhubarbPath, origRhubarbPath);
} }
if (useLegacy) { if (useLegacy) {

View file

@ -446,9 +446,12 @@ void Preferences::definePreferenceItems() {
// Import / Export // Import / Export
define(ffmpegPath, "ffmpegPath", QMetaType::QString, ""); define(ffmpegPath, "ffmpegPath", QMetaType::QString, "");
define(ffmpegTimeout, "ffmpegTimeout", QMetaType::Int, 600, 1, define(ffmpegTimeout, "ffmpegTimeout", QMetaType::Int, 0, 0,
std::numeric_limits<int>::max()); std::numeric_limits<int>::max());
define(fastRenderPath, "fastRenderPath", QMetaType::QString, "desktop"); define(fastRenderPath, "fastRenderPath", QMetaType::QString, "desktop");
define(rhubarbPath, "rhubarbPath", QMetaType::QString, "");
define(rhubarbTimeout, "rhubarbTimeout", QMetaType::Int, 0, 0,
std::numeric_limits<int>::max());
// Drawing // Drawing
define(scanLevelType, "scanLevelType", QMetaType::QString, "tif"); define(scanLevelType, "scanLevelType", QMetaType::QString, "tif");