From 71920c484bfaf25b5ca07259f37fb3ec4e26478c Mon Sep 17 00:00:00 2001 From: tt2468 Date: Fri, 7 Jun 2024 01:06:27 -0700 Subject: [PATCH] eventhandler: Add `RecordFileChanged` event When a file split happens, this will fire with the new file name --- src/eventhandler/EventHandler.cpp | 30 +++++++++++------------ src/eventhandler/EventHandler.h | 4 +++ src/eventhandler/EventHandler_Outputs.cpp | 22 +++++++++++++++++ 3 files changed, 41 insertions(+), 15 deletions(-) diff --git a/src/eventhandler/EventHandler.cpp b/src/eventhandler/EventHandler.cpp index cf862b62..05e46ab6 100644 --- a/src/eventhandler/EventHandler.cpp +++ b/src/eventhandler/EventHandler.cpp @@ -27,11 +27,11 @@ EventHandler::EventHandler() signal_handler_t *coreSignalHandler = obs_get_signal_handler(); if (coreSignalHandler) { - signal_handler_connect(coreSignalHandler, "source_create", SourceCreatedMultiHandler, this); - signal_handler_connect(coreSignalHandler, "source_destroy", SourceDestroyedMultiHandler, this); - signal_handler_connect(coreSignalHandler, "source_remove", SourceRemovedMultiHandler, this); - signal_handler_connect(coreSignalHandler, "source_rename", SourceRenamedMultiHandler, this); - signal_handler_connect(coreSignalHandler, "source_update", SourceUpdatedMultiHandler, this); + coreSignals.emplace_back(coreSignalHandler, "source_create", SourceCreatedMultiHandler, this); + coreSignals.emplace_back(coreSignalHandler, "source_destroy", SourceDestroyedMultiHandler, this); + coreSignals.emplace_back(coreSignalHandler, "source_remove", SourceRemovedMultiHandler, this); + coreSignals.emplace_back(coreSignalHandler, "source_rename", SourceRenamedMultiHandler, this); + coreSignals.emplace_back(coreSignalHandler, "source_update", SourceUpdatedMultiHandler, this); } else { blog(LOG_ERROR, "[EventHandler::EventHandler] Unable to get libobs signal handler!"); } @@ -45,16 +45,7 @@ EventHandler::~EventHandler() obs_frontend_remove_event_callback(OnFrontendEvent, this); - signal_handler_t *coreSignalHandler = obs_get_signal_handler(); - if (coreSignalHandler) { - signal_handler_disconnect(coreSignalHandler, "source_create", SourceCreatedMultiHandler, this); - signal_handler_disconnect(coreSignalHandler, "source_destroy", SourceDestroyedMultiHandler, this); - signal_handler_disconnect(coreSignalHandler, "source_remove", SourceRemovedMultiHandler, this); - signal_handler_disconnect(coreSignalHandler, "source_rename", SourceRenamedMultiHandler, this); - signal_handler_disconnect(coreSignalHandler, "source_update", SourceUpdatedMultiHandler, this); - } else { - blog(LOG_ERROR, "[EventHandler::~EventHandler] Unable to get libobs signal handler!"); - } + coreSignals.clear(); // Revoke callbacks of all inputs and scenes, in case some still have our callbacks attached auto enumInputs = [](void *param, obs_source_t *source) { @@ -378,12 +369,21 @@ void EventHandler::OnFrontendEvent(enum obs_frontend_event event, void *private_ break; case OBS_FRONTEND_EVENT_RECORDING_STARTED: eventHandler->HandleRecordStateChanged(OBS_WEBSOCKET_OUTPUT_STARTED); + { + OBSOutputAutoRelease recordOutput = obs_frontend_get_recording_output(); + if (recordOutput) { + signal_handler_t *sh = obs_output_get_signal_handler(recordOutput); + eventHandler->recordFileChangedSignal.Connect(sh, "file_changed", HandleRecordFileChanged, + private_data); + } + } break; case OBS_FRONTEND_EVENT_RECORDING_STOPPING: eventHandler->HandleRecordStateChanged(OBS_WEBSOCKET_OUTPUT_STOPPING); break; case OBS_FRONTEND_EVENT_RECORDING_STOPPED: eventHandler->HandleRecordStateChanged(OBS_WEBSOCKET_OUTPUT_STOPPED); + eventHandler->recordFileChangedSignal.Disconnect(); break; case OBS_FRONTEND_EVENT_RECORDING_PAUSED: eventHandler->HandleRecordStateChanged(OBS_WEBSOCKET_OUTPUT_PAUSED); diff --git a/src/eventhandler/EventHandler.h b/src/eventhandler/EventHandler.h index e9094428..b52d3879 100644 --- a/src/eventhandler/EventHandler.h +++ b/src/eventhandler/EventHandler.h @@ -51,6 +51,9 @@ private: std::atomic _obsReady = false; + std::vector coreSignals; + OBSSignal recordFileChangedSignal; + std::unique_ptr _inputVolumeMetersHandler; std::atomic _inputVolumeMetersRef = 0; std::atomic _inputActiveStateChangedRef = 0; @@ -155,6 +158,7 @@ private: // Outputs void HandleStreamStateChanged(ObsOutputState state); void HandleRecordStateChanged(ObsOutputState state); + static void HandleRecordFileChanged(void *param, calldata_t *data); // Direct callback void HandleReplayBufferStateChanged(ObsOutputState state); void HandleVirtualcamStateChanged(ObsOutputState state); void HandleReplayBufferSaved(); diff --git a/src/eventhandler/EventHandler_Outputs.cpp b/src/eventhandler/EventHandler_Outputs.cpp index 186ebaf2..91846913 100644 --- a/src/eventhandler/EventHandler_Outputs.cpp +++ b/src/eventhandler/EventHandler_Outputs.cpp @@ -87,6 +87,28 @@ void EventHandler::HandleRecordStateChanged(ObsOutputState state) BroadcastEvent(EventSubscription::Outputs, "RecordStateChanged", eventData); } +/** + * The record output has started writing to a new file. For example, when a file split happens. + * + * @dataField newOutputPath | String | File name that the output has begun writing to + * + * @eventType RecordFileChanged + * @eventSubscription Outputs + * @complexity 2 + * @rpcVersion -1 + * @initialVersion 5.5.0 + * @api events + * @category outputs + */ +void EventHandler::HandleRecordFileChanged(void *param, calldata_t *data) +{ + auto eventHandler = static_cast(param); + + json eventData; + eventData["newOutputPath"] = calldata_string(data, "next_file"); + eventHandler->BroadcastEvent(EventSubscription::Outputs, "RecordFileChanged", eventData); +} + /** * The state of the replay buffer output has changed. *