diff --git a/src/WebSocketProtocol.cpp b/src/WebSocketProtocol.cpp index baac1326..0b5dbf7a 100644 --- a/src/WebSocketProtocol.cpp +++ b/src/WebSocketProtocol.cpp @@ -101,7 +101,7 @@ WebSocketProtocol::ProcessResult WebSocketProtocol::ProcessMessage(SessionPtr se } RequestHandler requestHandler; - Request request(session->RpcVersion(), session->IgnoreNonFatalRequestChecks(), incomingMessage["requestType"], incomingMessage["requestData"]); + Request request(session, incomingMessage["requestType"], incomingMessage["requestData"]); RequestResult requestResult = requestHandler.ProcessRequest(request); @@ -144,7 +144,7 @@ WebSocketProtocol::ProcessResult WebSocketProtocol::ProcessMessage(SessionPtr se if (!requestJson["requestType"].is_string()) requestJson["requestType"] = ""; - Request request(session->RpcVersion(), session->IgnoreNonFatalRequestChecks(), requestJson["requestType"], requestJson["requestData"]); + Request request(session, requestJson["requestType"], requestJson["requestData"]); RequestResult requestResult = requestHandler.ProcessRequest(request); diff --git a/src/eventhandler/EventHandler.h b/src/eventhandler/EventHandler.h index b5ee6ef9..cedc8f89 100644 --- a/src/eventhandler/EventHandler.h +++ b/src/eventhandler/EventHandler.h @@ -8,24 +8,6 @@ #include "../obs-websocket.h" #include "../WebSocketServer.h" -enum ObsOutputState { - OBS_WEBSOCKET_OUTPUT_STARTING, - OBS_WEBSOCKET_OUTPUT_STARTED, - OBS_WEBSOCKET_OUTPUT_STOPPING, - OBS_WEBSOCKET_OUTPUT_STOPPED, - OBS_WEBSOCKET_OUTPUT_PAUSED, - OBS_WEBSOCKET_OUTPUT_RESUMED -}; - -enum ObsMediaInputAction { - OBS_WEBSOCKET_MEDIA_INPUT_ACTION_PAUSE, - OBS_WEBSOCKET_MEDIA_INPUT_ACTION_PLAY, - OBS_WEBSOCKET_MEDIA_INPUT_ACTION_RESTART, - OBS_WEBSOCKET_MEDIA_INPUT_ACTION_STOP, - OBS_WEBSOCKET_MEDIA_INPUT_ACTION_NEXT, - OBS_WEBSOCKET_MEDIA_INPUT_ACTION_PREVIOUS -}; - template T* GetCalldataPointer(const calldata_t *data, const char* name) { void *ptr = nullptr; calldata_get_ptr(data, name, &ptr); diff --git a/src/obs-websocket.cpp b/src/obs-websocket.cpp index 241b1fab..ba7fec2d 100644 --- a/src/obs-websocket.cpp +++ b/src/obs-websocket.cpp @@ -20,6 +20,7 @@ ConfigPtr _config; WebSocketServerPtr _webSocketServer; EventHandlerPtr _eventHandler; SettingsDialog *_settingsDialog = nullptr; +os_cpu_usage_info_t* _cpuUsageInfo; void ___source_dummy_addref(obs_source_t*) {} void ___sceneitem_dummy_addref(obs_sceneitem_t*) {}; @@ -55,12 +56,14 @@ bool obs_module_load(void) QAction* menuAction = (QAction*)obs_frontend_add_tools_menu_qaction(menuActionText); QObject::connect(menuAction, &QAction::triggered, [] { _settingsDialog->ToggleShowHide(); }); - // Loading finished - blog(LOG_INFO, "[obs_module_load] Module loaded."); + _cpuUsageInfo = os_cpu_usage_info_start(); if (_config->ServerEnabled) _webSocketServer->Start(); + // Loading finished + blog(LOG_INFO, "[obs_module_load] Module loaded."); + return true; } @@ -80,6 +83,8 @@ void obs_module_unload() _config->Save(); _config.reset(); + os_cpu_usage_info_destroy(_cpuUsageInfo); + blog(LOG_INFO, "[obs_module_unload] Finished shutting down."); } @@ -97,3 +102,8 @@ EventHandlerPtr GetEventHandler() { return _eventHandler; } + +os_cpu_usage_info_t* GetCpuUsageInfo() +{ + return _cpuUsageInfo; +} diff --git a/src/obs-websocket.h b/src/obs-websocket.h index ece0d25e..ab253378 100644 --- a/src/obs-websocket.h +++ b/src/obs-websocket.h @@ -2,6 +2,7 @@ #include #include +#include // Autorelease object definitions void ___source_dummy_addref(obs_source_t*); @@ -39,3 +40,5 @@ ConfigPtr GetConfig(); WebSocketServerPtr GetWebSocketServer(); EventHandlerPtr GetEventHandler(); + +os_cpu_usage_info_t* GetCpuUsageInfo(); diff --git a/src/requesthandler/RequestHandler.cpp b/src/requesthandler/RequestHandler.cpp index d29d5f90..240671bb 100644 --- a/src/requesthandler/RequestHandler.cpp +++ b/src/requesthandler/RequestHandler.cpp @@ -6,6 +6,7 @@ const std::map RequestHandler::_handlerMap // General {"GetVersion", &RequestHandler::GetVersion}, {"BroadcastCustomEvent", &RequestHandler::BroadcastCustomEvent}, + {"GetStats", &RequestHandler::GetStats}, {"GetHotkeyList", &RequestHandler::GetHotkeyList}, {"TriggerHotkeyByName", &RequestHandler::TriggerHotkeyByName}, {"TriggerHotkeyByKeySequence", &RequestHandler::TriggerHotkeyByKeySequence}, diff --git a/src/requesthandler/RequestHandler.h b/src/requesthandler/RequestHandler.h index b6868010..05ed49a3 100644 --- a/src/requesthandler/RequestHandler.h +++ b/src/requesthandler/RequestHandler.h @@ -21,6 +21,7 @@ class RequestHandler { // General RequestResult GetVersion(const Request&); RequestResult BroadcastCustomEvent(const Request&); + RequestResult GetStats(const Request&); RequestResult GetHotkeyList(const Request&); RequestResult TriggerHotkeyByName(const Request&); RequestResult TriggerHotkeyByKeySequence(const Request&); diff --git a/src/requesthandler/RequestHandler_General.cpp b/src/requesthandler/RequestHandler_General.cpp index 93e927fd..9ab11c67 100644 --- a/src/requesthandler/RequestHandler_General.cpp +++ b/src/requesthandler/RequestHandler_General.cpp @@ -40,6 +40,16 @@ RequestResult RequestHandler::BroadcastCustomEvent(const Request& request) return RequestResult::Success(); } +RequestResult RequestHandler::GetStats(const Request& request) +{ + json responseData = Utils::Obs::DataHelper::GetStats(); + + responseData["webSocketSessionIncomingMessages"] = request.Session->IncomingMessages(); + responseData["webSocketSessionOutgoingMessages"] = request.Session->OutgoingMessages(); + + return RequestResult::Success(responseData); +} + RequestResult RequestHandler::GetHotkeyList(const Request& request) { json responseData; diff --git a/src/requesthandler/RequestHandler_Stream.cpp b/src/requesthandler/RequestHandler_Stream.cpp index 63f028c6..8a3be52c 100644 --- a/src/requesthandler/RequestHandler_Stream.cpp +++ b/src/requesthandler/RequestHandler_Stream.cpp @@ -3,12 +3,16 @@ RequestResult RequestHandler::GetStreamStatus(const Request& request) { - json responseData; - OBSOutputAutoRelease streamOutput = obs_frontend_get_streaming_output(); + + json responseData; responseData["outputActive"] = obs_output_active(streamOutput); + responseData["outputReconnecting"] = obs_output_reconnecting(streamOutput); responseData["outputTimecode"] = Utils::Obs::StringHelper::GetOutputTimecodeString(streamOutput); responseData["outputDuration"] = Utils::Obs::NumberHelper::GetOutputDuration(streamOutput); + responseData["outputBytes"] = (uint64_t)obs_output_get_total_bytes(streamOutput); + responseData["outputSkippedFrames"] = obs_output_get_frames_dropped(streamOutput); + responseData["outputTotalFrames"] = obs_output_get_total_frames(streamOutput); return RequestResult::Success(responseData); } diff --git a/src/requesthandler/rpc/Request.cpp b/src/requesthandler/rpc/Request.cpp index 0f8819fc..8f670d5f 100644 --- a/src/requesthandler/rpc/Request.cpp +++ b/src/requesthandler/rpc/Request.cpp @@ -10,11 +10,12 @@ json GetDefaultJsonObject(json requestData) return requestData; } -Request::Request(uint8_t rpcVersion, bool ignoreNonFatalRequestChecks, std::string requestType, json requestData) : - RpcVersion(rpcVersion), - IgnoreNonFatalRequestChecks(ignoreNonFatalRequestChecks), - RequestData(GetDefaultJsonObject(requestData)), - RequestType(requestType) +Request::Request(SessionPtr session, std::string requestType, json requestData) : + Session(session), + RpcVersion(session->RpcVersion()), + IgnoreNonFatalRequestChecks(session->IgnoreNonFatalRequestChecks()), + RequestType(requestType), + RequestData(GetDefaultJsonObject(requestData)) { } diff --git a/src/requesthandler/rpc/Request.h b/src/requesthandler/rpc/Request.h index 643da9f0..ae7474fb 100644 --- a/src/requesthandler/rpc/Request.h +++ b/src/requesthandler/rpc/Request.h @@ -1,11 +1,12 @@ #pragma once #include "RequestStatus.h" +#include "../../WebSocketSession.h" #include "../../utils/Utils.h" struct Request { - Request(const uint8_t rpcVersion, const bool ignoreNonFatalRequestChecks, const std::string requestType, const json requestData = nullptr); + Request(SessionPtr session, const std::string requestType, const json requestData = nullptr); const bool HasRequestData() const { @@ -22,6 +23,7 @@ struct Request obs_source_t *ValidateScene(const std::string keyName, RequestStatus::RequestStatus &statusCode, std::string &comment) const; obs_source_t *ValidateInput(const std::string keyName, RequestStatus::RequestStatus &statusCode, std::string &comment) const; + SessionPtr Session; const uint8_t RpcVersion; const bool IgnoreNonFatalRequestChecks; const std::string RequestType; diff --git a/src/utils/Obs.cpp b/src/utils/Obs.cpp index 7e9fe4aa..03320cc2 100644 --- a/src/utils/Obs.cpp +++ b/src/utils/Obs.cpp @@ -1,6 +1,7 @@ #include #include #include +#include #include #include "Obs.h" @@ -332,6 +333,29 @@ std::vector Utils::Obs::ListHelper::GetInputKindList(bool unversion return ret; } +json Utils::Obs::DataHelper::GetStats() +{ + json ret; + + config_t* currentProfile = obs_frontend_get_profile_config(); + const char* outputMode = config_get_string(currentProfile, "Output", "Mode"); + const char* recordPath = strcmp(outputMode, "Advanced") ? config_get_string(currentProfile, "SimpleOutput", "FilePath") : config_get_string(currentProfile, "AdvOut", "RecFilePath"); + + video_t* video = obs_get_video(); + + ret["cpuUsage"] = os_cpu_usage_info_query(GetCpuUsageInfo()); + ret["memoryUsage"] = (double)os_get_proc_resident_size() / (1024.0 * 1024.0); + ret["availableDiskSpace"] = (double)os_get_free_disk_space(recordPath) / (1024.0 * 1024.0); + ret["activeFps"] = obs_get_active_fps(); + ret["averageFrameRenderTime"] = (double)obs_get_average_frame_time_ns() / 1000000.0; + ret["renderSkippedFrames"] = obs_get_lagged_frames(); + ret["renderTotalFrames"] = obs_get_total_frames(); + ret["outputSkippedFrames"] = video_output_get_skipped_frames(video); + ret["outputTotalFrames"] = video_output_get_total_frames(video); + + return ret; +} + obs_hotkey_t *Utils::Obs::SearchHelper::GetHotkeyByName(std::string name) { auto hotkeys = ListHelper::GetHotkeyList(); diff --git a/src/utils/Obs.h b/src/utils/Obs.h index ce216aa8..0bab4033 100644 --- a/src/utils/Obs.h +++ b/src/utils/Obs.h @@ -5,6 +5,25 @@ #include "Json.h" +enum ObsOutputState { + OBS_WEBSOCKET_OUTPUT_STARTING, + OBS_WEBSOCKET_OUTPUT_STARTED, + OBS_WEBSOCKET_OUTPUT_STOPPING, + OBS_WEBSOCKET_OUTPUT_STOPPED, + OBS_WEBSOCKET_OUTPUT_RECONNECTING, + OBS_WEBSOCKET_OUTPUT_PAUSED, + OBS_WEBSOCKET_OUTPUT_RESUMED +}; + +enum ObsMediaInputAction { + OBS_WEBSOCKET_MEDIA_INPUT_ACTION_PAUSE, + OBS_WEBSOCKET_MEDIA_INPUT_ACTION_PLAY, + OBS_WEBSOCKET_MEDIA_INPUT_ACTION_RESTART, + OBS_WEBSOCKET_MEDIA_INPUT_ACTION_STOP, + OBS_WEBSOCKET_MEDIA_INPUT_ACTION_NEXT, + OBS_WEBSOCKET_MEDIA_INPUT_ACTION_PREVIOUS +}; + namespace Utils { namespace Obs { namespace StringHelper { @@ -35,6 +54,10 @@ namespace Utils { std::vector GetInputKindList(bool unversioned = false, bool includeDisabled = false); } + namespace DataHelper { + json GetStats(); + } + namespace SearchHelper { obs_hotkey_t *GetHotkeyByName(std::string name); }