Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

add support for automatically merging encode segments via helper script #219

Open
wants to merge 8 commits into
base: master
Choose a base branch
from
2 changes: 2 additions & 0 deletions src/program/Config.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,7 @@ void Config::save(const std::string& gamepath) {
settings.setValue("autosave_frames", autosave_frames);
settings.setValue("autosave_count", autosave_count);
settings.setValue("auto_restart", auto_restart);
settings.setValue("merge_dump_segments", merge_dump_segments);

settings.beginGroup("keymapping");

Expand Down Expand Up @@ -195,6 +196,7 @@ void Config::load(const std::string& gamepath) {
autosave_frames = settings.value("autosave_frames", autosave_frames).toInt();
autosave_count = settings.value("autosave_count", autosave_count).toInt();
auto_restart = settings.value("auto_restart", auto_restart).toBool();
merge_dump_segments = settings.value("merge_dump_segments", merge_dump_segments).toBool();

/* Load key mapping */

Expand Down
3 changes: 3 additions & 0 deletions src/program/Config.h
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,9 @@ class Config {

/* Were we started up with the -d option? */
bool dumping;

/* Are we supposed to merge the segments after dumping? */
bool merge_dump_segments = false;

/* Path of the libraries used by the game */
std::string libdir;
Expand Down
20 changes: 19 additions & 1 deletion src/program/GameLoop.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
#include "GameLoop.h"
#include "utils.h"
#include "AutoSave.h"
#include "MergeHelperScript.h"

#include "../shared/sockethelpers.h"
#include "../shared/SharedConfig.h"
Expand All @@ -43,6 +44,7 @@
#include <sys/stat.h> // stat
#include <sys/wait.h> // waitpid
#include <X11/X.h>
#include <stdlib.h> //system()

#include <sys/personality.h>
#ifndef HAVE_PERSONALITY
Expand Down Expand Up @@ -1108,6 +1110,8 @@ bool GameLoop::processEvent(uint8_t type, struct HotKey &hk)
* allows to start a new encode on the same frame
*/
sendMessage(MSGN_STOP_ENCODE);
if (context->config.merge_dump_segments)
mergeSegments();
}
emit sharedConfigChanged();
return false;
Expand Down Expand Up @@ -1421,7 +1425,10 @@ void GameLoop::loopExit()
emit statusChanged();

return;
}
}
/* If we're not restarting, then check if we need to merge the dumps */
else if (context->config.sc.av_dumping && context->config.merge_dump_segments)
mergeSegments();

if (movie.modifiedSinceLastSave) {

Expand Down Expand Up @@ -1451,3 +1458,14 @@ void GameLoop::loopExit()
context->status = Context::INACTIVE;
emit statusChanged();
}

void GameLoop::mergeSegments()
{
std::ostringstream mergeCommand;
mergeCommand << "bash -c '";
mergeCommand << MERGE_HELPER_SCRIPT;
mergeCommand << "' -- ";
mergeCommand << context->config.dumpfile;
sleep(2); //make sure encode has time to finish before merging
system(mergeCommand.str().c_str());
}
2 changes: 2 additions & 0 deletions src/program/GameLoop.h
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,8 @@ class GameLoop : public QObject {
bool haveFocus();

void loopExit();

void mergeSegments();

signals:
void statusChanged();
Expand Down
54 changes: 54 additions & 0 deletions src/program/MergeHelperScript.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
/*
Copyright 2015-2019 Clément Gallet <[email protected]>

This file is part of libTAS.

libTAS is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.

libTAS 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.

You should have received a copy of the GNU General Public License
along with libTAS. If not, see <http://www.gnu.org/licenses/>.
*/

#ifndef MERGE_HELPER_SCRIPT_HEADER
#define MERGE_HELPER_SCRIPT_HEADER

/* Embeds Bash helper script as a C++11 raw string.
*
* This avoids having to cart around the script as a separate file.
*
* A "raw" string also avoids having to deal with escape sequences.
* However, if your syntax highlighter isn't aware of raw strings,
* then this may look a bit like a train wreck. */

/*try to avoid using single-quoted strings within the script, it may make it harder to run later.*/

const static char* MERGE_HELPER_SCRIPT = R"(

# absolute path to the first video (eg. /home/user/tasproject01/video.avi) is passed as command line argument 1

VID_PATH=$1
VID_EXT=$(echo $VID_PATH | sed "s/^.*\././g")
VID_DIR=$(dirname $VID_PATH)
VID_NAME=$(basename -s $VID_EXT $VID_PATH)

getChunks(){
for i in $(ls -v "$VID_DIR"/"$VID_NAME"_*"$VID_EXT")
do
echo file $i
done
}

sync
ffmpeg -f concat -safe 0 -i <(getChunks) -c copy -y $VID_DIR/$VID_NAME-merged.mkv

)";

#endif
12 changes: 12 additions & 0 deletions src/program/ui/EncodeWindow.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,9 @@ EncodeWindow::EncodeWindow(Context* c, QWidget *parent, Qt::WindowFlags flags) :
connect(audioBitrate, static_cast<void (QSpinBox::*)(int)>(&QSpinBox::valueChanged), this, &EncodeWindow::slotUpdate);

ffmpegOptions = new QLineEdit();

mergeCheck = new QCheckBox("Automatically merge dump segments");
connect(mergeCheck, &QAbstractButton::clicked, this, &EncodeWindow::slotMerge);

QGroupBox *codecGroupBox = new QGroupBox(tr("Encode codec settings"));
QGridLayout *encodeCodecLayout = new QGridLayout;
Expand All @@ -86,6 +89,8 @@ EncodeWindow::EncodeWindow(Context* c, QWidget *parent, Qt::WindowFlags flags) :

encodeCodecLayout->addWidget(new QLabel(tr("ffmpeg options:")), 2, 0);
encodeCodecLayout->addWidget(ffmpegOptions, 2, 1, 1, 4);
encodeCodecLayout->addWidget(mergeCheck, 3, 1, 1, 4);


encodeCodecLayout->setColumnMinimumWidth(2, 50);
encodeCodecLayout->setColumnStretch(2, 1);
Expand Down Expand Up @@ -128,6 +133,8 @@ void EncodeWindow::update_config()

/* Set ffmpeg options */
ffmpegOptions->setText(context->config.ffmpegoptions.c_str());

mergeCheck->setChecked(context->config.merge_dump_segments);

if (context->config.ffmpegoptions.empty()) {
slotUpdate();
Expand Down Expand Up @@ -167,3 +174,8 @@ void EncodeWindow::slotBrowseEncodePath()
if (!filename.isNull())
encodePath->setText(filename);
}

void EncodeWindow::slotMerge(bool checked)
{
context->config.merge_dump_segments = checked;
}
5 changes: 5 additions & 0 deletions src/program/ui/EncodeWindow.h
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,8 @@
#include <QLineEdit>
#include <QComboBox>
#include <QSpinBox>
#include <QCheckBox>


#include "../Context.h"

Expand All @@ -47,11 +49,14 @@ class EncodeWindow : public QDialog {
QComboBox *audioChoice;
QSpinBox *audioBitrate;
QLineEdit *ffmpegOptions;
QCheckBox *mergeCheck;


private slots:
void slotBrowseEncodePath();
void slotUpdate();
void slotOk();
void slotMerge(bool checked);
};

#endif