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

UI: Add frontend event and output signal for replay buffer saving #8955

Open
wants to merge 3 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions UI/obs-frontend-api/obs-frontend-api.h
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,8 @@ enum obs_frontend_event {
OBS_FRONTEND_EVENT_SCENE_COLLECTION_RENAMED,
OBS_FRONTEND_EVENT_THEME_CHANGED,
OBS_FRONTEND_EVENT_SCREENSHOT_TAKEN,

OBS_FRONTEND_EVENT_REPLAY_BUFFER_SAVING,
};

/* ------------------------------------------------------------------------- */
Expand Down
33 changes: 33 additions & 0 deletions UI/window-basic-main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2911,6 +2911,35 @@ void OBSBasic::CreateHotkeys()
LoadHotkeyPair(replayBufHotkeys, "OBSBasic.StartReplayBuffer",
"OBSBasic.StopReplayBuffer");

auto replayBufferCallback = [](void *data, obs_hotkey_id,
obs_hotkey_t *, bool pressed) {
OBSBasic *basic = static_cast<OBSBasic *>(data);
if (basic->outputHandler->ReplayBufferActive() && pressed) {
blog(LOG_INFO, "Saving replay buffer due to hotkey");
basic->ReplayBufferSave();
}
};

replayBufSaveHotkey = obs_hotkey_register_frontend(
"OBSBasic.SaveReplayBuffer", Str("Basic.Main.SaveReplay"),
replayBufferCallback, this);
Penwy marked this conversation as resolved.
Show resolved Hide resolved

const char *exists = config_get_string(basicConfig, "Hotkeys",
"OBSBasic.SaveReplayBuffer");
if (exists) {
LoadHotkey(replayBufSaveHotkey, "OBSBasic.SaveReplayBuffer");
} else {
OBSDataArrayAutoRelease array = obs_data_get_array(
LoadHotkeyData("ReplayBuffer"), "ReplayBuffer.Save");
obs_hotkey_load(replayBufSaveHotkey, array);

OBSDataAutoRelease newData = obs_data_create();
obs_data_set_array(newData, "bindings", array);
config_set_string(basicConfig, "Hotkeys",
"OBSBasic.SaveReplayBuffer",
obs_data_get_json(newData));
}

if (vcamEnabled) {
vcamHotkeys = obs_hotkey_pair_register_frontend(
"OBSBasic.StartVirtualCam",
Expand Down Expand Up @@ -3028,6 +3057,7 @@ void OBSBasic::ClearHotkeys()
obs_hotkey_unregister(splitFileHotkey);
obs_hotkey_unregister(addChapterHotkey);
obs_hotkey_pair_unregister(replayBufHotkeys);
obs_hotkey_unregister(replayBufSaveHotkey);
obs_hotkey_pair_unregister(vcamHotkeys);
obs_hotkey_pair_unregister(togglePreviewHotkeys);
obs_hotkey_pair_unregister(contextBarHotkeys);
Expand Down Expand Up @@ -7973,6 +8003,9 @@ void OBSBasic::ReplayBufferSave()
if (!outputHandler->ReplayBufferActive())
return;

if (api)
api->on_event(OBS_FRONTEND_EVENT_REPLAY_BUFFER_SAVING);

calldata_t cd = {0};
proc_handler_t *ph =
obs_output_get_proc_handler(outputHandler->replayBuffer);
Expand Down
2 changes: 1 addition & 1 deletion UI/window-basic-main.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -458,7 +458,7 @@ class OBSBasic : public OBSMainWindow {
replayBufHotkeys, vcamHotkeys, togglePreviewHotkeys,
contextBarHotkeys;
obs_hotkey_id forceStreamingStopHotkey, splitFileHotkey,
addChapterHotkey;
addChapterHotkey, replayBufSaveHotkey;

void InitDefaultTransitions();
void InitTransition(obs_source_t *transition);
Expand Down
4 changes: 4 additions & 0 deletions docs/sphinx/reference-frontend-api.rst
Original file line number Diff line number Diff line change
Expand Up @@ -150,6 +150,10 @@ Structures/Enumerations

Triggered when the replay buffer has fully stopped.

- **OBS_FRONTEND_EVENT_REPLAY_BUFFER_SAVING**

Triggered when the replay buffer is saving.

- **OBS_FRONTEND_EVENT_REPLAY_BUFFER_SAVED**

Triggered when the replay buffer has been saved.
Expand Down
1 change: 0 additions & 1 deletion plugins/obs-ffmpeg/data/locale/en-US.ini
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,6 @@ MediaFileFilter.AudioFiles="Audio Files"
MediaFileFilter.AllFiles="All Files"

ReplayBuffer="Replay Buffer"
ReplayBuffer.Save="Save Replay"

HelperProcessFailed="Unable to start the recording helper process. Check that OBS files have not been blocked or removed by any 3rd party antivirus / security software."
UnableToWritePath="Unable to write to %1. Make sure you're using a recording path which your user account is allowed to write to and that there is sufficient disk space."
Expand Down
30 changes: 9 additions & 21 deletions plugins/obs-ffmpeg/obs-ffmpeg-mux.c
Original file line number Diff line number Diff line change
Expand Up @@ -971,32 +971,21 @@ static const char *replay_buffer_getname(void *type)
return obs_module_text("ReplayBuffer");
}

static void replay_buffer_hotkey(void *data, obs_hotkey_id id,
obs_hotkey_t *hotkey, bool pressed)
static void save_replay_proc(void *data, calldata_t *cd)
{
UNUSED_PARAMETER(id);
UNUSED_PARAMETER(hotkey);

if (!pressed)
return;

struct ffmpeg_muxer *stream = data;

if (os_atomic_load_bool(&stream->active)) {
obs_encoder_t *vencoder =
obs_output_get_video_encoder(stream->output);
if (obs_encoder_paused(vencoder)) {
info("Could not save buffer because encoders paused");
info("Could not save buffer because the encoder is paused");
return;
}

stream->save_ts = os_gettime_ns() / 1000LL;
}
}

static void save_replay_proc(void *data, calldata_t *cd)
{
replay_buffer_hotkey(data, 0, NULL, true);
UNUSED_PARAMETER(cd);
}

Expand All @@ -1013,27 +1002,20 @@ static void *replay_buffer_create(obs_data_t *settings, obs_output_t *output)
struct ffmpeg_muxer *stream = bzalloc(sizeof(*stream));
stream->output = output;

stream->hotkey =
obs_hotkey_register_output(output, "ReplayBuffer.Save",
obs_module_text("ReplayBuffer.Save"),
replay_buffer_hotkey, stream);

proc_handler_t *ph = obs_output_get_proc_handler(output);
proc_handler_add(ph, "void save()", save_replay_proc, stream);
proc_handler_add(ph, "void get_last_replay(out string path)",
get_last_replay, stream);

signal_handler_t *sh = obs_output_get_signal_handler(output);
signal_handler_add(sh, "void saved()");
signal_handler_add(sh, "void saving(ptr output)");

return stream;
}

static void replay_buffer_destroy(void *data)
{
struct ffmpeg_muxer *stream = data;
if (stream->hotkey)
obs_hotkey_unregister(stream->hotkey);
ffmpeg_mux_destroy(data);
}

Expand Down Expand Up @@ -1223,6 +1205,12 @@ static void replay_buffer_save(struct ffmpeg_muxer *stream)
int64_t audio_offsets[MAX_AUDIO_MIXES] = {0};
int64_t audio_dts_offsets[MAX_AUDIO_MIXES] = {0};

calldata_t cd = {0};
calldata_set_ptr(&cd, "output", stream->output);
signal_handler_t *sh = obs_output_get_signal_handler(stream->output);
signal_handler_signal(sh, "saving", &cd);
calldata_free(&cd);

for (size_t i = 0; i < num_packets; i++) {
struct encoder_packet *pkt;
pkt = deque_data(&stream->packets, i * size);
Expand Down
Loading