From c0ea2461db85de9af2af069b686193193bd2c1f1 Mon Sep 17 00:00:00 2001 From: Penwywern Date: Mon, 22 May 2023 13:08:44 +0200 Subject: [PATCH 1/3] obs-ffmpeg: Add replay buffer saving output signal --- plugins/obs-ffmpeg/obs-ffmpeg-mux.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/plugins/obs-ffmpeg/obs-ffmpeg-mux.c b/plugins/obs-ffmpeg/obs-ffmpeg-mux.c index f152b2849e3e1a..f9cb1f33d8751d 100644 --- a/plugins/obs-ffmpeg/obs-ffmpeg-mux.c +++ b/plugins/obs-ffmpeg/obs-ffmpeg-mux.c @@ -963,6 +963,7 @@ static void *replay_buffer_create(obs_data_t *settings, obs_output_t *output) 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; } @@ -1154,6 +1155,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); From 620858d2580247dfa55005b6fc4c57a45b554e5c Mon Sep 17 00:00:00 2001 From: Penwywern Date: Mon, 22 May 2023 10:49:04 +0200 Subject: [PATCH 2/3] frontend: Add replay buffer saving frontend event --- docs/sphinx/reference-frontend-api.rst | 4 ++++ frontend/api/obs-frontend-api.h | 2 ++ frontend/widgets/OBSBasic_ReplayBuffer.cpp | 2 ++ 3 files changed, 8 insertions(+) diff --git a/docs/sphinx/reference-frontend-api.rst b/docs/sphinx/reference-frontend-api.rst index 6ef7854d12fa78..b4983669bc2d74 100644 --- a/docs/sphinx/reference-frontend-api.rst +++ b/docs/sphinx/reference-frontend-api.rst @@ -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. diff --git a/frontend/api/obs-frontend-api.h b/frontend/api/obs-frontend-api.h index 54cc6bf5669dbf..d5c34ee2aa1c7d 100644 --- a/frontend/api/obs-frontend-api.h +++ b/frontend/api/obs-frontend-api.h @@ -65,6 +65,8 @@ enum obs_frontend_event { OBS_FRONTEND_EVENT_CANVAS_ADDED, OBS_FRONTEND_EVENT_CANVAS_REMOVED, + + OBS_FRONTEND_EVENT_REPLAY_BUFFER_SAVING, }; /* ------------------------------------------------------------------------- */ diff --git a/frontend/widgets/OBSBasic_ReplayBuffer.cpp b/frontend/widgets/OBSBasic_ReplayBuffer.cpp index 8d95f2210677ba..12dc179f8c4ac3 100644 --- a/frontend/widgets/OBSBasic_ReplayBuffer.cpp +++ b/frontend/widgets/OBSBasic_ReplayBuffer.cpp @@ -147,6 +147,8 @@ void OBSBasic::ReplayBufferSave() if (!outputHandler->ReplayBufferActive()) return; + OnEvent(OBS_FRONTEND_EVENT_REPLAY_BUFFER_SAVING); + calldata_t cd = {0}; proc_handler_t *ph = obs_output_get_proc_handler(outputHandler->replayBuffer); proc_handler_call(ph, "save", &cd); From f3c16624d30837cb102a3f347f162d115ff74cff Mon Sep 17 00:00:00 2001 From: Penwywern Date: Mon, 22 May 2023 20:13:10 +0200 Subject: [PATCH 3/3] frontend: Register the replay buffer save hotkey in the frontend Existing registering of the save hotkey in obs-ffmpeg makes it impossible for it to trigger a frontend event, and is inconsistent with other existing output hotkeys. This registers the save hotkey in the frontend and removes the registration in obs-ffmpeg, and adds a "due to hotkey" log message, like other output hotkeys. --- frontend/widgets/OBSBasic.hpp | 2 +- frontend/widgets/OBSBasic_Hotkeys.cpp | 24 ++++++++++++++++++++++++ plugins/obs-ffmpeg/data/locale/en-US.ini | 1 - plugins/obs-ffmpeg/obs-ffmpeg-mux.c | 20 ++------------------ 4 files changed, 27 insertions(+), 20 deletions(-) diff --git a/frontend/widgets/OBSBasic.hpp b/frontend/widgets/OBSBasic.hpp index 18ccb370a041e9..4b550f8ba72320 100644 --- a/frontend/widgets/OBSBasic.hpp +++ b/frontend/widgets/OBSBasic.hpp @@ -492,7 +492,7 @@ private slots: obs_hotkey_pair_id streamingHotkeys, recordingHotkeys, pauseHotkeys, replayBufHotkeys, vcamHotkeys, togglePreviewHotkeys, contextBarHotkeys; - obs_hotkey_id forceStreamingStopHotkey, splitFileHotkey, addChapterHotkey; + obs_hotkey_id forceStreamingStopHotkey, splitFileHotkey, addChapterHotkey, replayBufSaveHotkey; void InitHotkeys(); void CreateHotkeys(); diff --git a/frontend/widgets/OBSBasic_Hotkeys.cpp b/frontend/widgets/OBSBasic_Hotkeys.cpp index 3be00aeeed9169..f635ae5fa39b6a 100644 --- a/frontend/widgets/OBSBasic_Hotkeys.cpp +++ b/frontend/widgets/OBSBasic_Hotkeys.cpp @@ -206,6 +206,30 @@ void OBSBasic::CreateHotkeys() this, this); LoadHotkeyPair(replayBufHotkeys, "OBSBasic.StartReplayBuffer", "OBSBasic.StopReplayBuffer"); + auto replayBufferCallback = [](void *data, obs_hotkey_id, obs_hotkey_t *, bool pressed) { + OBSBasic *basic = static_cast(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); + + const char *exists = config_get_string(activeConfiguration, "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(activeConfiguration, "Hotkeys", "OBSBasic.SaveReplayBuffer", + obs_data_get_json(newData)); + } + if (vcamEnabled) { vcamHotkeys = obs_hotkey_pair_register_frontend( "OBSBasic.StartVirtualCam", Str("Basic.Main.StartVirtualCam"), "OBSBasic.StopVirtualCam", diff --git a/plugins/obs-ffmpeg/data/locale/en-US.ini b/plugins/obs-ffmpeg/data/locale/en-US.ini index 2331d1e4917b1b..d74426cabb3a4c 100644 --- a/plugins/obs-ffmpeg/data/locale/en-US.ini +++ b/plugins/obs-ffmpeg/data/locale/en-US.ini @@ -100,7 +100,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." diff --git a/plugins/obs-ffmpeg/obs-ffmpeg-mux.c b/plugins/obs-ffmpeg/obs-ffmpeg-mux.c index f9cb1f33d8751d..b0f3072309ef24 100644 --- a/plugins/obs-ffmpeg/obs-ffmpeg-mux.c +++ b/plugins/obs-ffmpeg/obs-ffmpeg-mux.c @@ -914,30 +914,20 @@ 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); } @@ -954,9 +944,6 @@ 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); @@ -970,9 +957,6 @@ static void *replay_buffer_create(obs_data_t *settings, obs_output_t *output) static void replay_buffer_destroy(void *data) { - struct ffmpeg_muxer *stream = data; - if (stream->hotkey) - obs_hotkey_unregister(stream->hotkey); ffmpeg_mux_destroy(data); }