UI: Add pause support

Adds support for pausing recordings.  When settings are eligible for
recordings, a pause button will appear next to the recording button.  If
the settings are not eligible, it will warn the user in the output
settings that they cannot pause recordings if those settings are used.
This commit is contained in:
jp9000
2019-07-07 15:47:29 -07:00
parent 942ca6f709
commit eab10d48b2
22 changed files with 385 additions and 42 deletions

View File

@@ -2112,6 +2112,17 @@ void OBSBasic::CreateHotkeys()
LoadHotkeyPair(recordingHotkeys, "OBSBasic.StartRecording",
"OBSBasic.StopRecording");
pauseHotkeys = obs_hotkey_pair_register_frontend(
"OBSBasic.PauseRecording", Str("Basic.Main.PauseRecording"),
"OBSBasic.UnpauseRecording", Str("Basic.Main.UnpauseRecording"),
MAKE_CALLBACK(basic.pause && !basic.pause->isChecked(),
basic.PauseRecording, "Pausing recording"),
MAKE_CALLBACK(basic.pause && basic.pause->isChecked(),
basic.UnpauseRecording, "Unpausing recording"),
this, this);
LoadHotkeyPair(pauseHotkeys, "OBSBasic.PauseRecording",
"OBSBasic.UnpauseRecording");
replayBufHotkeys = obs_hotkey_pair_register_frontend(
"OBSBasic.StartReplayBuffer",
Str("Basic.Main.StartReplayBuffer"),
@@ -2169,6 +2180,7 @@ void OBSBasic::ClearHotkeys()
{
obs_hotkey_pair_unregister(streamingHotkeys);
obs_hotkey_pair_unregister(recordingHotkeys);
obs_hotkey_pair_unregister(pauseHotkeys);
obs_hotkey_pair_unregister(replayBufHotkeys);
obs_hotkey_pair_unregister(togglePreviewHotkeys);
obs_hotkey_unregister(forceStreamingStopHotkey);
@@ -5319,6 +5331,7 @@ void OBSBasic::RecordingStart()
api->on_event(OBS_FRONTEND_EVENT_RECORDING_STARTED);
OnActivate();
UpdatePause();
blog(LOG_INFO, RECORDING_START);
}
@@ -5385,11 +5398,46 @@ void OBSBasic::RecordingStop(int code, QString last_error)
AutoRemux();
OnDeactivate();
UpdatePause(false);
}
#define RP_NO_HOTKEY_TITLE QTStr("Output.ReplayBuffer.NoHotkey.Title")
#define RP_NO_HOTKEY_TEXT QTStr("Output.ReplayBuffer.NoHotkey.Msg")
extern volatile bool recording_paused;
extern volatile bool replaybuf_active;
void OBSBasic::ShowReplayBufferPauseWarning()
{
auto msgBox = []() {
QMessageBox msgbox(App()->GetMainWindow());
msgbox.setWindowTitle(QTStr("Output.ReplayBuffer."
"PauseWarning.Title"));
msgbox.setText(QTStr("Output.ReplayBuffer."
"PauseWarning.Text"));
msgbox.setIcon(QMessageBox::Icon::Information);
msgbox.addButton(QMessageBox::Ok);
QCheckBox *cb = new QCheckBox(QTStr("DoNotShowAgain"));
msgbox.setCheckBox(cb);
msgbox.exec();
if (cb->isChecked()) {
config_set_bool(App()->GlobalConfig(), "General",
"WarnedAboutReplayBufferPausing", true);
config_save_safe(App()->GlobalConfig(), "tmp", nullptr);
}
};
bool warned = config_get_bool(App()->GlobalConfig(), "General",
"WarnedAboutReplayBufferPausing");
if (!warned) {
QMetaObject::invokeMethod(App(), "Exec", Qt::QueuedConnection,
Q_ARG(VoidFunc, msgBox));
}
}
void OBSBasic::StartReplayBuffer()
{
if (!outputHandler || !outputHandler->replayBuffer)
@@ -5423,8 +5471,12 @@ void OBSBasic::StartReplayBuffer()
api->on_event(OBS_FRONTEND_EVENT_REPLAY_BUFFER_STARTING);
SaveProject();
if (!outputHandler->StartReplayBuffer())
if (!outputHandler->StartReplayBuffer()) {
replayBufferButton->setChecked(false);
} else if (os_atomic_load_bool(&recording_paused)) {
ShowReplayBufferPauseWarning();
}
}
void OBSBasic::ReplayBufferStopping()
@@ -7295,3 +7347,106 @@ void OBSBasic::UpdatePatronJson(const QString &text, const QString &error)
patronJson = QT_TO_UTF8(text);
}
void OBSBasic::PauseRecording()
{
if (!pause || !outputHandler || !outputHandler->fileOutput)
return;
obs_output_t *output = outputHandler->fileOutput;
if (obs_output_pause(output, true)) {
pause->setChecked(true);
os_atomic_set_bool(&recording_paused, true);
if (api)
api->on_event(OBS_FRONTEND_EVENT_RECORDING_PAUSED);
if (os_atomic_load_bool(&replaybuf_active))
ShowReplayBufferPauseWarning();
}
}
void OBSBasic::UnpauseRecording()
{
if (!pause || !outputHandler || !outputHandler->fileOutput)
return;
obs_output_t *output = outputHandler->fileOutput;
if (obs_output_pause(output, false)) {
pause->setChecked(false);
os_atomic_set_bool(&recording_paused, false);
if (api)
api->on_event(OBS_FRONTEND_EVENT_RECORDING_UNPAUSED);
}
}
void OBSBasic::PauseToggled()
{
if (!pause || !outputHandler || !outputHandler->fileOutput)
return;
obs_output_t *output = outputHandler->fileOutput;
bool enable = !obs_output_paused(output);
if (obs_output_pause(output, enable)) {
os_atomic_set_bool(&recording_paused, enable);
if (api)
api->on_event(
enable ? OBS_FRONTEND_EVENT_RECORDING_PAUSED
: OBS_FRONTEND_EVENT_RECORDING_UNPAUSED);
if (enable && os_atomic_load_bool(&replaybuf_active))
ShowReplayBufferPauseWarning();
} else {
pause->setChecked(!enable);
}
}
void OBSBasic::UpdatePause(bool activate)
{
if (!activate || !outputHandler || !outputHandler->RecordingActive()) {
pause.reset();
return;
}
const char *mode = config_get_string(basicConfig, "Output", "Mode");
bool adv = astrcmpi(mode, "Advanced") == 0;
bool shared;
if (adv) {
const char *recType =
config_get_string(basicConfig, "AdvOut", "RecType");
if (astrcmpi(recType, "FFmpeg") == 0) {
shared = config_get_bool(basicConfig, "AdvOut",
"FFOutputToFile");
} else {
const char *recordEncoder = config_get_string(
basicConfig, "AdvOut", "RecEncoder");
shared = astrcmpi(recordEncoder, "none") == 0;
}
} else {
const char *quality = config_get_string(
basicConfig, "SimpleOutput", "RecQuality");
shared = strcmp(quality, "Stream") == 0;
}
if (!shared) {
pause.reset(new QPushButton());
pause->setAccessibleName(QTStr("Basic.Main.PauseRecording"));
pause->setToolTip(QTStr("Basic.Main.PauseRecording"));
pause->setCheckable(true);
pause->setChecked(false);
pause->setProperty("themeID",
QVariant(QStringLiteral("pauseIconSmall")));
connect(pause.data(), &QAbstractButton::clicked, this,
&OBSBasic::PauseToggled);
ui->recordingLayout->addWidget(pause.data());
} else {
pause.reset();
}
}