diff --git a/PROTOCOL.md b/PROTOCOL.md index 1336cd1d..09db1d42 100644 --- a/PROTOCOL.md +++ b/PROTOCOL.md @@ -395,8 +395,9 @@ __Request fields__ : none __Response__ : always OK, with these additional fields : - **"streaming"** (bool) : streaming status (active or not) - **"recording"** (bool) : recording status (active or not) +- **stream-timecode** (string, optional) : time elapsed between now and stream start (only present if OBS Studio is streaming) +- **rec-timecode** (string, optional) : time elapsed between now and recording start (only present if OBS Studio is recording) - **"preview-only"** (bool) : always false. Retrocompat with OBSRemote. - --- #### "GetTransitionList" diff --git a/WSEvents.cpp b/WSEvents.cpp index 7acf6c79..ec20852a 100644 --- a/WSEvents.cpp +++ b/WSEvents.cpp @@ -54,6 +54,8 @@ const char* ns_to_timestamp(uint64_t ns) return ts; } +WSEvents* WSEvents::Instance = nullptr; + WSEvents::WSEvents(WSServer *srv) { _srv = srv; @@ -83,7 +85,8 @@ WSEvents::~WSEvents() obs_frontend_remove_event_callback(WSEvents::FrontendEventHandler, this); } -void WSEvents::deferredInitOperations() { +void WSEvents::deferredInitOperations() +{ obs_source_t* transition = obs_frontend_get_current_transition(); connectTransitionSignals(transition); obs_source_release(transition); @@ -241,6 +244,32 @@ void WSEvents::connectSceneSignals(obs_source_t* scene) signal_handler_connect(scene_handler, "item_visible", OnSceneItemVisibilityChanged, this); } +uint64_t WSEvents::GetStreamingTime() +{ + if (_streaming_active) + return (os_gettime_ns() - _stream_starttime); + else + return 0; +} + +const char* WSEvents::GetStreamingTimecode() +{ + return ns_to_timestamp(GetStreamingTime()); +} + +uint64_t WSEvents::GetRecordingTime() +{ + if (_recording_active) + return (os_gettime_ns() - _rec_starttime); + else + return 0; +} + +const char* WSEvents::GetRecordingTimecode() +{ + return ns_to_timestamp(GetRecordingTime()); +} + void WSEvents::OnSceneChange() { // Implements an existing update type from bilhamil's OBS Remote diff --git a/WSEvents.h b/WSEvents.h index dca57947..2c678364 100644 --- a/WSEvents.h +++ b/WSEvents.h @@ -33,6 +33,12 @@ class WSEvents : public QObject static void FrontendEventHandler(enum obs_frontend_event event, void *private_data); void connectTransitionSignals(obs_source_t* transition); void connectSceneSignals(obs_source_t* scene); + static WSEvents* Instance; + + uint64_t GetStreamingTime(); + const char* GetStreamingTimecode(); + uint64_t GetRecordingTime(); + const char* GetRecordingTimecode(); private Q_SLOTS: void StreamStatus(); diff --git a/WSRequestHandler.cpp b/WSRequestHandler.cpp index 9fc1348e..026a96f5 100644 --- a/WSRequestHandler.cpp +++ b/WSRequestHandler.cpp @@ -18,6 +18,7 @@ with this program. If not, see */ #include "WSRequestHandler.h" +#include "WSEvents.h" #include "obs-websocket.h" #include "Config.h" #include "Utils.h" @@ -298,6 +299,21 @@ void WSRequestHandler::HandleGetStreamingStatus(WSRequestHandler *owner) obs_data_set_bool(data, "recording", obs_frontend_recording_active()); obs_data_set_bool(data, "preview-only", false); + const char* tc = nullptr; + if (obs_frontend_streaming_active()) + { + tc = WSEvents::Instance->GetStreamingTimecode(); + obs_data_set_string(data, "stream-timecode", tc); + bfree((void*)tc); + } + + if (obs_frontend_recording_active()) + { + tc = WSEvents::Instance->GetRecordingTimecode(); + obs_data_set_string(data, "rec-timecode", tc); + bfree((void*)tc); + } + owner->SendOKResponse(data); obs_data_release(data); } diff --git a/WSServer.cpp b/WSServer.cpp index 5e8193db..11bca693 100644 --- a/WSServer.cpp +++ b/WSServer.cpp @@ -27,7 +27,7 @@ with this program. If not, see QT_USE_NAMESPACE -WSServer* WSServer::Instance = new WSServer(); +WSServer* WSServer::Instance = nullptr; WSServer::WSServer(QObject *parent) : QObject(parent), diff --git a/obs-websocket.cpp b/obs-websocket.cpp index fc3e3cea..07f23b60 100644 --- a/obs-websocket.cpp +++ b/obs-websocket.cpp @@ -31,7 +31,6 @@ with this program. If not, see OBS_DECLARE_MODULE() OBS_MODULE_USE_DEFAULT_LOCALE("obs-websocket", "en-US") -WSEvents *eventHandler; SettingsDialog *settings_dialog; bool obs_module_load(void) @@ -42,11 +41,12 @@ bool obs_module_load(void) Config* config = Config::Current(); config->Load(); + WSServer::Instance = new WSServer(); + WSEvents::Instance = new WSEvents(WSServer::Instance); + if (config->ServerEnabled) WSServer::Instance->Start(config->ServerPort); - eventHandler = new WSEvents(WSServer::Instance); - // UI setup QAction *menu_action = (QAction*)obs_frontend_add_tools_menu_qaction(obs_module_text("OBSWebsocket.Menu.SettingsItem"));