2017-04-19 19:54:15 +00:00
|
|
|
#include <obs-frontend-api.h>
|
|
|
|
#include <obs-module.h>
|
|
|
|
#include <obs.hpp>
|
|
|
|
#include <util/util.hpp>
|
|
|
|
#include <QAction>
|
|
|
|
#include <QMainWindow>
|
|
|
|
#include <QTimer>
|
|
|
|
#include <QObject>
|
|
|
|
#include "output-timer.hpp"
|
|
|
|
|
|
|
|
using namespace std;
|
|
|
|
|
|
|
|
OutputTimer *ot;
|
|
|
|
|
|
|
|
OutputTimer::OutputTimer(QWidget *parent)
|
2019-09-22 21:19:10 +00:00
|
|
|
: QDialog(parent), ui(new Ui_OutputTimer)
|
2017-04-19 19:54:15 +00:00
|
|
|
{
|
|
|
|
ui->setupUi(this);
|
|
|
|
|
2019-07-27 12:47:10 +00:00
|
|
|
setWindowFlags(windowFlags() & ~Qt::WindowContextHelpButtonHint);
|
|
|
|
|
2017-04-19 19:54:15 +00:00
|
|
|
QObject::connect(ui->outputTimerStream, SIGNAL(clicked()), this,
|
2019-09-22 21:19:10 +00:00
|
|
|
SLOT(StreamingTimerButton()));
|
2017-04-19 19:54:15 +00:00
|
|
|
QObject::connect(ui->outputTimerRecord, SIGNAL(clicked()), this,
|
2019-09-22 21:19:10 +00:00
|
|
|
SLOT(RecordingTimerButton()));
|
2017-06-29 19:01:10 +00:00
|
|
|
QObject::connect(ui->buttonBox->button(QDialogButtonBox::Close),
|
2019-09-22 21:19:10 +00:00
|
|
|
SIGNAL(clicked()), this, SLOT(hide()));
|
2017-04-19 19:54:15 +00:00
|
|
|
|
|
|
|
streamingTimer = new QTimer(this);
|
|
|
|
streamingTimerDisplay = new QTimer(this);
|
|
|
|
|
|
|
|
recordingTimer = new QTimer(this);
|
|
|
|
recordingTimerDisplay = new QTimer(this);
|
|
|
|
}
|
|
|
|
|
2019-09-22 21:19:10 +00:00
|
|
|
void OutputTimer::closeEvent(QCloseEvent *)
|
2017-04-19 19:54:15 +00:00
|
|
|
{
|
|
|
|
obs_frontend_save();
|
|
|
|
}
|
|
|
|
|
|
|
|
void OutputTimer::StreamingTimerButton()
|
|
|
|
{
|
|
|
|
if (!obs_frontend_streaming_active()) {
|
2018-02-19 19:54:37 +00:00
|
|
|
blog(LOG_INFO, "Starting stream due to OutputTimer");
|
2017-04-19 19:54:15 +00:00
|
|
|
obs_frontend_streaming_start();
|
|
|
|
} else if (streamingAlreadyActive) {
|
|
|
|
StreamTimerStart();
|
|
|
|
streamingAlreadyActive = false;
|
|
|
|
} else if (obs_frontend_streaming_active()) {
|
2018-02-19 19:54:37 +00:00
|
|
|
blog(LOG_INFO, "Stopping stream due to OutputTimer");
|
2017-04-19 19:54:15 +00:00
|
|
|
obs_frontend_streaming_stop();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void OutputTimer::RecordingTimerButton()
|
|
|
|
{
|
|
|
|
if (!obs_frontend_recording_active()) {
|
2018-02-19 19:54:37 +00:00
|
|
|
blog(LOG_INFO, "Starting recording due to OutputTimer");
|
2017-04-19 19:54:15 +00:00
|
|
|
obs_frontend_recording_start();
|
|
|
|
} else if (recordingAlreadyActive) {
|
|
|
|
RecordTimerStart();
|
|
|
|
recordingAlreadyActive = false;
|
|
|
|
} else if (obs_frontend_recording_active()) {
|
2018-02-19 19:54:37 +00:00
|
|
|
blog(LOG_INFO, "Stopping recording due to OutputTimer");
|
2017-04-19 19:54:15 +00:00
|
|
|
obs_frontend_recording_stop();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void OutputTimer::StreamTimerStart()
|
|
|
|
{
|
|
|
|
if (!isVisible() && ui->autoStartStreamTimer->isChecked() == false) {
|
|
|
|
streamingAlreadyActive = true;
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
int hours = ui->streamingTimerHours->value();
|
|
|
|
int minutes = ui->streamingTimerMinutes->value();
|
|
|
|
int seconds = ui->streamingTimerSeconds->value();
|
|
|
|
|
2019-09-22 21:19:10 +00:00
|
|
|
int total = (((hours * 3600) + (minutes * 60)) + seconds) * 1000;
|
2017-04-19 19:54:15 +00:00
|
|
|
|
|
|
|
if (total == 0)
|
|
|
|
total = 1000;
|
|
|
|
|
|
|
|
streamingTimer->setInterval(total);
|
|
|
|
streamingTimer->setSingleShot(true);
|
|
|
|
|
|
|
|
QObject::connect(streamingTimer, SIGNAL(timeout()),
|
2019-09-22 21:19:10 +00:00
|
|
|
SLOT(EventStopStreaming()));
|
2017-04-19 19:54:15 +00:00
|
|
|
|
|
|
|
QObject::connect(streamingTimerDisplay, SIGNAL(timeout()), this,
|
2019-09-22 21:19:10 +00:00
|
|
|
SLOT(UpdateStreamTimerDisplay()));
|
2017-04-19 19:54:15 +00:00
|
|
|
|
|
|
|
streamingTimer->start();
|
|
|
|
streamingTimerDisplay->start(1000);
|
|
|
|
ui->outputTimerStream->setText(obs_module_text("Stop"));
|
|
|
|
|
|
|
|
UpdateStreamTimerDisplay();
|
2019-09-22 21:19:10 +00:00
|
|
|
|
|
|
|
ui->outputTimerStream->setChecked(true);
|
2017-04-19 19:54:15 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void OutputTimer::RecordTimerStart()
|
|
|
|
{
|
|
|
|
if (!isVisible() && ui->autoStartRecordTimer->isChecked() == false) {
|
|
|
|
recordingAlreadyActive = true;
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
int hours = ui->recordingTimerHours->value();
|
|
|
|
int minutes = ui->recordingTimerMinutes->value();
|
|
|
|
int seconds = ui->recordingTimerSeconds->value();
|
|
|
|
|
2019-09-22 21:19:10 +00:00
|
|
|
int total = (((hours * 3600) + (minutes * 60)) + seconds) * 1000;
|
2017-04-19 19:54:15 +00:00
|
|
|
|
|
|
|
if (total == 0)
|
|
|
|
total = 1000;
|
|
|
|
|
|
|
|
recordingTimer->setInterval(total);
|
|
|
|
recordingTimer->setSingleShot(true);
|
|
|
|
|
|
|
|
QObject::connect(recordingTimer, SIGNAL(timeout()),
|
2019-09-22 21:19:10 +00:00
|
|
|
SLOT(EventStopRecording()));
|
2017-04-19 19:54:15 +00:00
|
|
|
|
|
|
|
QObject::connect(recordingTimerDisplay, SIGNAL(timeout()), this,
|
2019-09-22 21:19:10 +00:00
|
|
|
SLOT(UpdateRecordTimerDisplay()));
|
2017-04-19 19:54:15 +00:00
|
|
|
|
|
|
|
recordingTimer->start();
|
|
|
|
recordingTimerDisplay->start(1000);
|
|
|
|
ui->outputTimerRecord->setText(obs_module_text("Stop"));
|
|
|
|
|
|
|
|
UpdateRecordTimerDisplay();
|
2019-09-22 21:19:10 +00:00
|
|
|
|
|
|
|
ui->outputTimerRecord->setChecked(true);
|
2017-04-19 19:54:15 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void OutputTimer::StreamTimerStop()
|
|
|
|
{
|
|
|
|
streamingAlreadyActive = false;
|
|
|
|
|
|
|
|
if (!isVisible() && streamingTimer->isActive() == false)
|
|
|
|
return;
|
|
|
|
|
|
|
|
if (streamingTimer->isActive())
|
|
|
|
streamingTimer->stop();
|
|
|
|
|
|
|
|
ui->outputTimerStream->setText(obs_module_text("Start"));
|
|
|
|
|
|
|
|
if (streamingTimerDisplay->isActive())
|
|
|
|
streamingTimerDisplay->stop();
|
|
|
|
|
|
|
|
ui->streamTime->setText("00:00:00");
|
2019-09-22 21:19:10 +00:00
|
|
|
ui->outputTimerStream->setChecked(false);
|
2017-04-19 19:54:15 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void OutputTimer::RecordTimerStop()
|
|
|
|
{
|
|
|
|
recordingAlreadyActive = false;
|
|
|
|
|
|
|
|
if (!isVisible() && recordingTimer->isActive() == false)
|
|
|
|
return;
|
|
|
|
|
|
|
|
if (recordingTimer->isActive())
|
|
|
|
recordingTimer->stop();
|
|
|
|
|
|
|
|
ui->outputTimerRecord->setText(obs_module_text("Start"));
|
|
|
|
|
|
|
|
if (recordingTimerDisplay->isActive())
|
|
|
|
recordingTimerDisplay->stop();
|
|
|
|
|
|
|
|
ui->recordTime->setText("00:00:00");
|
2019-09-22 21:19:10 +00:00
|
|
|
ui->outputTimerRecord->setChecked(false);
|
2017-04-19 19:54:15 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void OutputTimer::UpdateStreamTimerDisplay()
|
|
|
|
{
|
|
|
|
int remainingTime = streamingTimer->remainingTime() / 1000;
|
|
|
|
|
|
|
|
int seconds = remainingTime % 60;
|
|
|
|
int minutes = (remainingTime % 3600) / 60;
|
|
|
|
int hours = remainingTime / 3600;
|
|
|
|
|
|
|
|
QString text;
|
|
|
|
text.sprintf("%02d:%02d:%02d", hours, minutes, seconds);
|
|
|
|
ui->streamTime->setText(text);
|
|
|
|
}
|
|
|
|
|
|
|
|
void OutputTimer::UpdateRecordTimerDisplay()
|
|
|
|
{
|
2019-09-22 21:19:10 +00:00
|
|
|
int remainingTime = 0;
|
|
|
|
|
|
|
|
if (obs_frontend_recording_paused() &&
|
|
|
|
ui->pauseRecordTimer->isChecked())
|
|
|
|
remainingTime = recordingTimeLeft / 1000;
|
|
|
|
else
|
|
|
|
remainingTime = recordingTimer->remainingTime() / 1000;
|
2017-04-19 19:54:15 +00:00
|
|
|
|
|
|
|
int seconds = remainingTime % 60;
|
|
|
|
int minutes = (remainingTime % 3600) / 60;
|
|
|
|
int hours = remainingTime / 3600;
|
|
|
|
|
|
|
|
QString text;
|
|
|
|
text.sprintf("%02d:%02d:%02d", hours, minutes, seconds);
|
|
|
|
ui->recordTime->setText(text);
|
|
|
|
}
|
|
|
|
|
2019-09-22 21:19:10 +00:00
|
|
|
void OutputTimer::PauseRecordingTimer()
|
|
|
|
{
|
|
|
|
if (!ui->pauseRecordTimer->isChecked())
|
|
|
|
return;
|
|
|
|
|
|
|
|
if (recordingTimer->isActive()) {
|
|
|
|
recordingTimeLeft = recordingTimer->remainingTime();
|
|
|
|
recordingTimer->stop();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void OutputTimer::UnpauseRecordingTimer()
|
|
|
|
{
|
|
|
|
if (!ui->pauseRecordTimer->isChecked())
|
|
|
|
return;
|
|
|
|
|
|
|
|
if (!recordingTimer->isActive())
|
|
|
|
recordingTimer->start(recordingTimeLeft);
|
|
|
|
}
|
|
|
|
|
2017-04-19 19:54:15 +00:00
|
|
|
void OutputTimer::ShowHideDialog()
|
|
|
|
{
|
|
|
|
if (!isVisible()) {
|
|
|
|
setVisible(true);
|
|
|
|
QTimer::singleShot(250, this, SLOT(show()));
|
|
|
|
} else {
|
|
|
|
setVisible(false);
|
|
|
|
QTimer::singleShot(250, this, SLOT(hide()));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void OutputTimer::EventStopStreaming()
|
|
|
|
{
|
2018-02-19 19:54:37 +00:00
|
|
|
blog(LOG_INFO, "Stopping stream due to OutputTimer timeout");
|
2017-04-19 19:54:15 +00:00
|
|
|
obs_frontend_streaming_stop();
|
|
|
|
}
|
|
|
|
|
|
|
|
void OutputTimer::EventStopRecording()
|
|
|
|
{
|
2018-02-19 19:54:37 +00:00
|
|
|
blog(LOG_INFO, "Stopping recording due to OutputTimer timeout");
|
2017-04-19 19:54:15 +00:00
|
|
|
obs_frontend_recording_stop();
|
|
|
|
}
|
|
|
|
|
|
|
|
static void SaveOutputTimer(obs_data_t *save_data, bool saving, void *)
|
|
|
|
{
|
|
|
|
if (saving) {
|
|
|
|
obs_data_t *obj = obs_data_create();
|
|
|
|
|
|
|
|
obs_data_set_int(obj, "streamTimerHours",
|
2019-09-22 21:19:10 +00:00
|
|
|
ot->ui->streamingTimerHours->value());
|
2017-04-19 19:54:15 +00:00
|
|
|
obs_data_set_int(obj, "streamTimerMinutes",
|
2019-09-22 21:19:10 +00:00
|
|
|
ot->ui->streamingTimerMinutes->value());
|
2017-04-19 19:54:15 +00:00
|
|
|
obs_data_set_int(obj, "streamTimerSeconds",
|
2019-09-22 21:19:10 +00:00
|
|
|
ot->ui->streamingTimerSeconds->value());
|
2017-04-19 19:54:15 +00:00
|
|
|
|
|
|
|
obs_data_set_int(obj, "recordTimerHours",
|
2019-09-22 21:19:10 +00:00
|
|
|
ot->ui->recordingTimerHours->value());
|
2017-04-19 19:54:15 +00:00
|
|
|
obs_data_set_int(obj, "recordTimerMinutes",
|
2019-09-22 21:19:10 +00:00
|
|
|
ot->ui->recordingTimerMinutes->value());
|
2017-04-19 19:54:15 +00:00
|
|
|
obs_data_set_int(obj, "recordTimerSeconds",
|
2019-09-22 21:19:10 +00:00
|
|
|
ot->ui->recordingTimerSeconds->value());
|
2017-04-19 19:54:15 +00:00
|
|
|
|
|
|
|
obs_data_set_bool(obj, "autoStartStreamTimer",
|
2019-09-22 21:19:10 +00:00
|
|
|
ot->ui->autoStartStreamTimer->isChecked());
|
2017-04-19 19:54:15 +00:00
|
|
|
obs_data_set_bool(obj, "autoStartRecordTimer",
|
2019-09-22 21:19:10 +00:00
|
|
|
ot->ui->autoStartRecordTimer->isChecked());
|
|
|
|
|
|
|
|
obs_data_set_bool(obj, "pauseRecordTimer",
|
|
|
|
ot->ui->pauseRecordTimer->isChecked());
|
2017-04-19 19:54:15 +00:00
|
|
|
|
|
|
|
obs_data_set_obj(save_data, "output-timer", obj);
|
|
|
|
|
|
|
|
obs_data_release(obj);
|
|
|
|
} else {
|
2019-09-22 21:19:10 +00:00
|
|
|
obs_data_t *obj = obs_data_get_obj(save_data, "output-timer");
|
2017-04-19 19:54:15 +00:00
|
|
|
|
|
|
|
if (!obj)
|
|
|
|
obj = obs_data_create();
|
|
|
|
|
|
|
|
ot->ui->streamingTimerHours->setValue(
|
2019-09-22 21:19:10 +00:00
|
|
|
obs_data_get_int(obj, "streamTimerHours"));
|
2017-04-19 19:54:15 +00:00
|
|
|
ot->ui->streamingTimerMinutes->setValue(
|
2019-09-22 21:19:10 +00:00
|
|
|
obs_data_get_int(obj, "streamTimerMinutes"));
|
2017-04-19 19:54:15 +00:00
|
|
|
ot->ui->streamingTimerSeconds->setValue(
|
2019-09-22 21:19:10 +00:00
|
|
|
obs_data_get_int(obj, "streamTimerSeconds"));
|
2017-04-19 19:54:15 +00:00
|
|
|
|
|
|
|
ot->ui->recordingTimerHours->setValue(
|
2019-09-22 21:19:10 +00:00
|
|
|
obs_data_get_int(obj, "recordTimerHours"));
|
2017-04-19 19:54:15 +00:00
|
|
|
ot->ui->recordingTimerMinutes->setValue(
|
2019-09-22 21:19:10 +00:00
|
|
|
obs_data_get_int(obj, "recordTimerMinutes"));
|
2017-04-19 19:54:15 +00:00
|
|
|
ot->ui->recordingTimerSeconds->setValue(
|
2019-09-22 21:19:10 +00:00
|
|
|
obs_data_get_int(obj, "recordTimerSeconds"));
|
2017-04-19 19:54:15 +00:00
|
|
|
|
|
|
|
ot->ui->autoStartStreamTimer->setChecked(
|
2019-09-22 21:19:10 +00:00
|
|
|
obs_data_get_bool(obj, "autoStartStreamTimer"));
|
2017-04-19 19:54:15 +00:00
|
|
|
ot->ui->autoStartRecordTimer->setChecked(
|
2019-09-22 21:19:10 +00:00
|
|
|
obs_data_get_bool(obj, "autoStartRecordTimer"));
|
|
|
|
|
|
|
|
ot->ui->pauseRecordTimer->setChecked(
|
|
|
|
obs_data_get_bool(obj, "pauseRecordTimer"));
|
2017-04-19 19:54:15 +00:00
|
|
|
|
|
|
|
obs_data_release(obj);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-09-22 21:19:10 +00:00
|
|
|
extern "C" void FreeOutputTimer() {}
|
2017-04-19 19:54:15 +00:00
|
|
|
|
|
|
|
static void OBSEvent(enum obs_frontend_event event, void *)
|
|
|
|
{
|
|
|
|
if (event == OBS_FRONTEND_EVENT_EXIT) {
|
|
|
|
obs_frontend_save();
|
|
|
|
FreeOutputTimer();
|
|
|
|
} else if (event == OBS_FRONTEND_EVENT_STREAMING_STARTED) {
|
|
|
|
ot->StreamTimerStart();
|
|
|
|
} else if (event == OBS_FRONTEND_EVENT_STREAMING_STOPPING) {
|
|
|
|
ot->StreamTimerStop();
|
|
|
|
} else if (event == OBS_FRONTEND_EVENT_RECORDING_STARTED) {
|
|
|
|
ot->RecordTimerStart();
|
|
|
|
} else if (event == OBS_FRONTEND_EVENT_RECORDING_STOPPING) {
|
|
|
|
ot->RecordTimerStop();
|
2019-09-22 21:19:10 +00:00
|
|
|
} else if (event == OBS_FRONTEND_EVENT_RECORDING_PAUSED) {
|
|
|
|
ot->PauseRecordingTimer();
|
|
|
|
} else if (event == OBS_FRONTEND_EVENT_RECORDING_UNPAUSED) {
|
|
|
|
ot->UnpauseRecordingTimer();
|
2017-04-19 19:54:15 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
extern "C" void InitOutputTimer()
|
|
|
|
{
|
2019-09-22 21:19:10 +00:00
|
|
|
QAction *action = (QAction *)obs_frontend_add_tools_menu_qaction(
|
|
|
|
obs_module_text("OutputTimer"));
|
2017-04-19 19:54:15 +00:00
|
|
|
|
|
|
|
obs_frontend_push_ui_translation(obs_module_get_string);
|
|
|
|
|
2019-09-22 21:19:10 +00:00
|
|
|
QMainWindow *window = (QMainWindow *)obs_frontend_get_main_window();
|
2017-04-19 19:54:15 +00:00
|
|
|
|
|
|
|
ot = new OutputTimer(window);
|
|
|
|
|
2019-09-22 21:19:10 +00:00
|
|
|
auto cb = []() { ot->ShowHideDialog(); };
|
2017-04-19 19:54:15 +00:00
|
|
|
|
|
|
|
obs_frontend_pop_ui_translation();
|
|
|
|
|
|
|
|
obs_frontend_add_save_callback(SaveOutputTimer, nullptr);
|
|
|
|
obs_frontend_add_event_callback(OBSEvent, nullptr);
|
|
|
|
|
|
|
|
action->connect(action, &QAction::triggered, cb);
|
|
|
|
}
|