diff --git a/CMakeLists.txt b/CMakeLists.txt index f4288218..dc1f5707 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -107,6 +107,7 @@ set(obs-websocket_SOURCES src/requesthandler/RequestHandler_Inputs.cpp src/requesthandler/RequestHandler_SceneItems.cpp src/requesthandler/RequestHandler_Stream.cpp + src/requesthandler/RequestHandler_Record.cpp src/requesthandler/rpc/Request.cpp src/requesthandler/rpc/RequestResult.cpp src/forms/SettingsDialog.cpp diff --git a/src/requesthandler/RequestHandler.cpp b/src/requesthandler/RequestHandler.cpp index 32db9e07..168a7a2a 100644 --- a/src/requesthandler/RequestHandler.cpp +++ b/src/requesthandler/RequestHandler.cpp @@ -87,6 +87,16 @@ const std::map RequestHandler::_handlerMap {"ToggleStream", &RequestHandler::ToggleStream}, {"StartStream", &RequestHandler::StartStream}, {"StopStream", &RequestHandler::StopStream}, + + // Record + {"GetRecordStatus", &RequestHandler::GetRecordStatus}, + {"ToggleRecord", &RequestHandler::ToggleRecord}, + {"StartRecord", &RequestHandler::StartRecord}, + {"StopRecord", &RequestHandler::StopRecord}, + {"ToggleRecordPause", &RequestHandler::ToggleRecordPause}, + {"PauseRecord", &RequestHandler::PauseRecord}, + {"ResumeRecord", &RequestHandler::ResumeRecord}, + //{"GetRecordDirectory", &RequestHandler::GetRecordDirectory}, }; RequestHandler::RequestHandler(SessionPtr session) : diff --git a/src/requesthandler/RequestHandler.h b/src/requesthandler/RequestHandler.h index db88f440..f426e3e4 100644 --- a/src/requesthandler/RequestHandler.h +++ b/src/requesthandler/RequestHandler.h @@ -109,6 +109,16 @@ class RequestHandler { RequestResult StartStream(const Request&); RequestResult StopStream(const Request&); + // Record + RequestResult GetRecordStatus(const Request&); + RequestResult ToggleRecord(const Request&); + RequestResult StartRecord(const Request&); + RequestResult StopRecord(const Request&); + RequestResult ToggleRecordPause(const Request&); + RequestResult PauseRecord(const Request&); + RequestResult ResumeRecord(const Request&); + RequestResult GetRecordDirectory(const Request&); + SessionPtr _session; static const std::map _handlerMap; }; diff --git a/src/requesthandler/RequestHandler_Record.cpp b/src/requesthandler/RequestHandler_Record.cpp new file mode 100644 index 00000000..ef6699f1 --- /dev/null +++ b/src/requesthandler/RequestHandler_Record.cpp @@ -0,0 +1,95 @@ +#include "RequestHandler.h" + +RequestResult RequestHandler::GetRecordStatus(const Request& request) +{ + OBSOutputAutoRelease recordOutput = obs_frontend_get_streaming_output(); + + json responseData; + responseData["outputActive"] = obs_output_active(recordOutput); + responseData["outputPaused"] = obs_output_paused(recordOutput); + responseData["outputTimecode"] = Utils::Obs::StringHelper::GetOutputTimecodeString(recordOutput); + responseData["outputDuration"] = Utils::Obs::NumberHelper::GetOutputDuration(recordOutput); + responseData["outputBytes"] = (uint64_t)obs_output_get_total_bytes(recordOutput); + + return RequestResult::Success(responseData); +} + +RequestResult RequestHandler::ToggleRecord(const Request& request) +{ + json responseData; + if (obs_frontend_recording_active()) { + obs_frontend_recording_stop(); + responseData["outputActive"] = false; + } else { + obs_frontend_recording_start(); + responseData["outputActive"] = true; + } + + return RequestResult::Success(responseData); +} + +RequestResult RequestHandler::StartRecord(const Request& request) +{ + if (obs_frontend_recording_active()) + return RequestResult::Error(RequestStatus::OutputRunning); + + // TODO: Call signal directly to perform blocking wait + obs_frontend_recording_start(); + + return RequestResult::Success(); +} + +RequestResult RequestHandler::StopRecord(const Request& request) +{ + if (!obs_frontend_recording_active()) + return RequestResult::Error(RequestStatus::OutputNotRunning); + + // TODO: Call signal directly to perform blocking wait + obs_frontend_recording_stop(); + + return RequestResult::Success(); +} + +RequestResult RequestHandler::ToggleRecordPause(const Request& request) +{ + json responseData; + if (obs_frontend_recording_paused()) { + obs_frontend_recording_pause(false); + responseData["outputPaused"] = false; + } else { + obs_frontend_recording_pause(true); + responseData["outputPaused"] = true; + } + + return RequestResult::Success(responseData); +} + +RequestResult RequestHandler::PauseRecord(const Request& request) +{ + if (obs_frontend_recording_paused()) + return RequestResult::Error(RequestStatus::OutputPaused); + + // TODO: Call signal directly to perform blocking wait + obs_frontend_recording_pause(true); + + return RequestResult::Success(); +} + +RequestResult RequestHandler::ResumeRecord(const Request& request) +{ + if (!obs_frontend_recording_paused()) + return RequestResult::Error(RequestStatus::OutputNotPaused); + + // TODO: Call signal directly to perform blocking wait + obs_frontend_recording_pause(false); + + return RequestResult::Success(); +} + +RequestResult RequestHandler::GetRecordDirectory(const Request& request) +{ + json responseData; + responseData["recordDirectory"] = Utils::Obs::StringHelper::GetCurrentRecordOutputPath(); + + return RequestResult::Success(responseData); +} diff --git a/src/requesthandler/rpc/RequestStatus.h b/src/requesthandler/rpc/RequestStatus.h index 3d1566e8..6c868daa 100644 --- a/src/requesthandler/rpc/RequestStatus.h +++ b/src/requesthandler/rpc/RequestStatus.h @@ -46,6 +46,8 @@ namespace RequestStatus { StudioModeActive = 504, // Studio mode is not active and should be StudioModeNotActive = 505, + // An output is not paused and should be + OutputNotPaused = 506, // The resource was not found ResourceNotFound = 600, diff --git a/src/utils/Obs.cpp b/src/utils/Obs.cpp index a15af7b0..a4f6c7d4 100644 --- a/src/utils/Obs.cpp +++ b/src/utils/Obs.cpp @@ -67,6 +67,16 @@ std::string Utils::Obs::StringHelper::GetCurrentProfilePath() return ret; } +std::string Utils::Obs::StringHelper::GetCurrentRecordOutputPath() +{ + //char *recordOutputPath = obs_frontend_get_current_record_output_path(); + //std::string ret = recordOutputPath; + //bfree(recordOutputPath); + //return ret; + + return ""; +} + std::string Utils::Obs::StringHelper::GetSourceTypeString(obs_source_t *source) { obs_source_type sourceType = obs_source_get_type(source); diff --git a/src/utils/Obs.h b/src/utils/Obs.h index 63b2880a..8819003f 100644 --- a/src/utils/Obs.h +++ b/src/utils/Obs.h @@ -31,6 +31,7 @@ namespace Utils { std::string GetCurrentSceneCollection(); std::string GetCurrentProfile(); std::string GetCurrentProfilePath(); + std::string GetCurrentRecordOutputPath(); std::string GetSourceTypeString(obs_source_t *source); std::string GetInputMonitorTypeString(obs_source_t *input); std::string GetMediaInputStateString(obs_source_t *input);