mirror of
https://github.com/Palakis/obs-websocket.git
synced 2024-08-30 18:12:16 +00:00
Merge pull request #390 from Palakis/handler-protocol-refactor
Request handler refactor
This commit is contained in:
commit
e65958f33e
CMakeLists.txt
src
Utils.cppUtils.hWSEvents.cppWSRequestHandler.cppWSRequestHandler.hWSRequestHandler_General.cppWSRequestHandler_Outputs.cppWSRequestHandler_Profiles.cppWSRequestHandler_Recording.cppWSRequestHandler_ReplayBuffer.cppWSRequestHandler_SceneCollections.cppWSRequestHandler_SceneItems.cppWSRequestHandler_Scenes.cppWSRequestHandler_Sources.cppWSRequestHandler_Streaming.cppWSRequestHandler_StudioMode.cppWSRequestHandler_Transitions.cppWSServer.cppWSServer.h
protocol
rpc
@ -46,6 +46,10 @@ set(obs-websocket_SOURCES
|
||||
src/WSEvents.cpp
|
||||
src/Config.cpp
|
||||
src/Utils.cpp
|
||||
src/rpc/RpcRequest.cpp
|
||||
src/rpc/RpcResponse.cpp
|
||||
src/rpc/RpcEvent.cpp
|
||||
src/protocol/OBSRemoteProtocol.cpp
|
||||
src/forms/settings-dialog.cpp)
|
||||
|
||||
set(obs-websocket_HEADERS
|
||||
@ -56,6 +60,10 @@ set(obs-websocket_HEADERS
|
||||
src/WSEvents.h
|
||||
src/Config.h
|
||||
src/Utils.h
|
||||
src/rpc/RpcRequest.h
|
||||
src/rpc/RpcResponse.h
|
||||
src/rpc/RpcEvent.h
|
||||
src/protocol/OBSRemoteProtocol.h
|
||||
src/forms/settings-dialog.h)
|
||||
|
||||
# --- Platform-independent build settings ---
|
||||
@ -174,8 +182,8 @@ if(UNIX AND NOT APPLE)
|
||||
install(TARGETS obs-websocket
|
||||
LIBRARY DESTINATION "${CMAKE_INSTALL_PREFIX}/lib/obs-plugins")
|
||||
# Dirty fix for Ubuntu
|
||||
install(TARGETS obs-websocket
|
||||
LIBRARY DESTINATION "${CMAKE_INSTALL_PREFIX}/lib/${UNAME_MACHINE}-linux-gnu/obs-plugins")
|
||||
install(TARGETS obs-websocket
|
||||
LIBRARY DESTINATION "${CMAKE_INSTALL_PREFIX}/lib/${UNAME_MACHINE}-linux-gnu/obs-plugins")
|
||||
|
||||
install(FILES ${locale_files}
|
||||
DESTINATION "${CMAKE_INSTALL_PREFIX}/share/obs/obs-plugins/obs-websocket/locale")
|
||||
|
@ -16,6 +16,7 @@ You should have received a copy of the GNU General Public License along
|
||||
with this program. If not, see <https://www.gnu.org/licenses/>
|
||||
*/
|
||||
|
||||
#include <inttypes.h>
|
||||
#include <QtWidgets/QMainWindow>
|
||||
#include <QtCore/QDir>
|
||||
#include <QtCore/QUrl>
|
||||
@ -822,3 +823,17 @@ void Utils::PauseRecording(bool pause)
|
||||
|
||||
pauseRecording(pause);
|
||||
}
|
||||
|
||||
QString Utils::nsToTimestamp(uint64_t ns)
|
||||
{
|
||||
uint64_t ms = ns / 1000000ULL;
|
||||
uint64_t secs = ms / 1000ULL;
|
||||
uint64_t minutes = secs / 60ULL;
|
||||
|
||||
uint64_t hoursPart = minutes / 60ULL;
|
||||
uint64_t minutesPart = minutes % 60ULL;
|
||||
uint64_t secsPart = secs % 60ULL;
|
||||
uint64_t msPart = ms % 1000ULL;
|
||||
|
||||
return QString::asprintf("%02" PRIu64 ":%02" PRIu64 ":%02" PRIu64 ".%03" PRIu64, hoursPart, minutesPart, secsPart, msPart);
|
||||
}
|
||||
|
@ -86,4 +86,6 @@ class Utils {
|
||||
static bool RecordingPauseSupported();
|
||||
static bool RecordingPaused();
|
||||
static void PauseRecording(bool pause);
|
||||
|
||||
static QString nsToTimestamp(uint64_t ns);
|
||||
};
|
||||
|
@ -23,27 +23,15 @@
|
||||
|
||||
#include <QtWidgets/QPushButton>
|
||||
|
||||
#include "Config.h"
|
||||
#include "Utils.h"
|
||||
#include "WSEvents.h"
|
||||
|
||||
#include "obs-websocket.h"
|
||||
#include "Config.h"
|
||||
#include "Utils.h"
|
||||
#include "rpc/RpcEvent.h"
|
||||
|
||||
#define STATUS_INTERVAL 2000
|
||||
|
||||
QString nsToTimestamp(uint64_t ns) {
|
||||
uint64_t ms = ns / 1000000ULL;
|
||||
uint64_t secs = ms / 1000ULL;
|
||||
uint64_t minutes = secs / 60ULL;
|
||||
|
||||
uint64_t hoursPart = minutes / 60ULL;
|
||||
uint64_t minutesPart = minutes % 60ULL;
|
||||
uint64_t secsPart = secs % 60ULL;
|
||||
uint64_t msPart = ms % 1000ULL;
|
||||
|
||||
return QString::asprintf("%02" PRIu64 ":%02" PRIu64 ":%02" PRIu64 ".%03" PRIu64, hoursPart, minutesPart, secsPart, msPart);
|
||||
}
|
||||
|
||||
const char* sourceTypeToString(obs_source_type type) {
|
||||
switch (type) {
|
||||
case OBS_SOURCE_TYPE_INPUT:
|
||||
@ -252,28 +240,11 @@ void WSEvents::FrontendEventHandler(enum obs_frontend_event event, void* private
|
||||
void WSEvents::broadcastUpdate(const char* updateType,
|
||||
obs_data_t* additionalFields = nullptr)
|
||||
{
|
||||
OBSDataAutoRelease update = obs_data_create();
|
||||
obs_data_set_string(update, "update-type", updateType);
|
||||
uint64_t streamTime = getStreamingTime();
|
||||
uint64_t recordingTime = getStreamingTime();
|
||||
RpcEvent event(QString(updateType), streamTime, recordingTime, additionalFields);
|
||||
|
||||
if (obs_frontend_streaming_active()) {
|
||||
QString streamingTimecode = getStreamingTimecode();
|
||||
obs_data_set_string(update, "stream-timecode", streamingTimecode.toUtf8().constData());
|
||||
}
|
||||
|
||||
if (obs_frontend_recording_active()) {
|
||||
QString recordingTimecode = getRecordingTimecode();
|
||||
obs_data_set_string(update, "rec-timecode", recordingTimecode.toUtf8().constData());
|
||||
}
|
||||
|
||||
if (additionalFields)
|
||||
obs_data_apply(update, additionalFields);
|
||||
|
||||
QString json = obs_data_get_json(update);
|
||||
_srv->broadcast(json.toStdString());
|
||||
|
||||
if (GetConfig()->DebugEnabled) {
|
||||
blog(LOG_INFO, "Update << '%s'", json.toUtf8().constData());
|
||||
}
|
||||
_srv->broadcast(event);
|
||||
}
|
||||
|
||||
void WSEvents::connectSourceSignals(obs_source_t* source) {
|
||||
@ -410,11 +381,11 @@ uint64_t WSEvents::getRecordingTime() {
|
||||
}
|
||||
|
||||
QString WSEvents::getStreamingTimecode() {
|
||||
return nsToTimestamp(getStreamingTime());
|
||||
return Utils::nsToTimestamp(getStreamingTime());
|
||||
}
|
||||
|
||||
QString WSEvents::getRecordingTimecode() {
|
||||
return nsToTimestamp(getRecordingTime());
|
||||
return Utils::nsToTimestamp(getRecordingTime());
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -17,6 +17,8 @@
|
||||
* with this program. If not, see <https://www.gnu.org/licenses/>
|
||||
*/
|
||||
|
||||
#include <functional>
|
||||
|
||||
#include <obs-data.h>
|
||||
|
||||
#include "Config.h"
|
||||
@ -24,265 +26,148 @@
|
||||
|
||||
#include "WSRequestHandler.h"
|
||||
|
||||
QHash<QString, HandlerResponse(*)(WSRequestHandler*)> WSRequestHandler::messageMap{
|
||||
{ "GetVersion", WSRequestHandler::HandleGetVersion },
|
||||
{ "GetAuthRequired", WSRequestHandler::HandleGetAuthRequired },
|
||||
{ "Authenticate", WSRequestHandler::HandleAuthenticate },
|
||||
using namespace std::placeholders;
|
||||
|
||||
{ "GetStats", WSRequestHandler::HandleGetStats },
|
||||
{ "SetHeartbeat", WSRequestHandler::HandleSetHeartbeat },
|
||||
{ "GetVideoInfo", WSRequestHandler::HandleGetVideoInfo },
|
||||
const QHash<QString, RpcMethodHandler> WSRequestHandler::messageMap {
|
||||
{ "GetVersion", &WSRequestHandler::GetVersion },
|
||||
{ "GetAuthRequired", &WSRequestHandler::GetAuthRequired },
|
||||
{ "Authenticate", &WSRequestHandler::Authenticate },
|
||||
|
||||
{ "SetFilenameFormatting", WSRequestHandler::HandleSetFilenameFormatting },
|
||||
{ "GetFilenameFormatting", WSRequestHandler::HandleGetFilenameFormatting },
|
||||
{ "GetStats", &WSRequestHandler::GetStats },
|
||||
{ "SetHeartbeat", &WSRequestHandler::SetHeartbeat },
|
||||
{ "GetVideoInfo", &WSRequestHandler::GetVideoInfo },
|
||||
|
||||
{ "BroadcastCustomMessage", WSRequestHandler::HandleBroadcastCustomMessage },
|
||||
{ "SetFilenameFormatting", &WSRequestHandler::SetFilenameFormatting },
|
||||
{ "GetFilenameFormatting", &WSRequestHandler::GetFilenameFormatting },
|
||||
|
||||
{ "SetCurrentScene", WSRequestHandler::HandleSetCurrentScene },
|
||||
{ "GetCurrentScene", WSRequestHandler::HandleGetCurrentScene },
|
||||
{ "GetSceneList", WSRequestHandler::HandleGetSceneList },
|
||||
{ "BroadcastCustomMessage", &WSRequestHandler::BroadcastCustomMessage },
|
||||
|
||||
{ "SetSourceRender", WSRequestHandler::HandleSetSceneItemRender }, // Retrocompat
|
||||
{ "SetSceneItemRender", WSRequestHandler::HandleSetSceneItemRender },
|
||||
{ "SetSceneItemPosition", WSRequestHandler::HandleSetSceneItemPosition },
|
||||
{ "SetSceneItemTransform", WSRequestHandler::HandleSetSceneItemTransform },
|
||||
{ "SetSceneItemCrop", WSRequestHandler::HandleSetSceneItemCrop },
|
||||
{ "GetSceneItemProperties", WSRequestHandler::HandleGetSceneItemProperties },
|
||||
{ "SetSceneItemProperties", WSRequestHandler::HandleSetSceneItemProperties },
|
||||
{ "ResetSceneItem", WSRequestHandler::HandleResetSceneItem },
|
||||
{ "DeleteSceneItem", WSRequestHandler::HandleDeleteSceneItem },
|
||||
{ "DuplicateSceneItem", WSRequestHandler::HandleDuplicateSceneItem },
|
||||
{ "ReorderSceneItems", WSRequestHandler::HandleReorderSceneItems },
|
||||
{ "SetCurrentScene", &WSRequestHandler::SetCurrentScene },
|
||||
{ "GetCurrentScene", &WSRequestHandler::GetCurrentScene },
|
||||
{ "GetSceneList", &WSRequestHandler::GetSceneList },
|
||||
|
||||
{ "GetStreamingStatus", WSRequestHandler::HandleGetStreamingStatus },
|
||||
{ "StartStopStreaming", WSRequestHandler::HandleStartStopStreaming },
|
||||
{ "StartStopRecording", WSRequestHandler::HandleStartStopRecording },
|
||||
{ "SetSourceRender", &WSRequestHandler::SetSceneItemRender }, // Retrocompat
|
||||
{ "SetSceneItemRender", &WSRequestHandler::SetSceneItemRender },
|
||||
{ "SetSceneItemPosition", &WSRequestHandler::SetSceneItemPosition },
|
||||
{ "SetSceneItemTransform", &WSRequestHandler::SetSceneItemTransform },
|
||||
{ "SetSceneItemCrop", &WSRequestHandler::SetSceneItemCrop },
|
||||
{ "GetSceneItemProperties", &WSRequestHandler::GetSceneItemProperties },
|
||||
{ "SetSceneItemProperties", &WSRequestHandler::SetSceneItemProperties },
|
||||
{ "ResetSceneItem", &WSRequestHandler::ResetSceneItem },
|
||||
{ "DeleteSceneItem", &WSRequestHandler::DeleteSceneItem },
|
||||
{ "DuplicateSceneItem", &WSRequestHandler::DuplicateSceneItem },
|
||||
{ "ReorderSceneItems", &WSRequestHandler::ReorderSceneItems },
|
||||
|
||||
{ "StartStreaming", WSRequestHandler::HandleStartStreaming },
|
||||
{ "StopStreaming", WSRequestHandler::HandleStopStreaming },
|
||||
{ "GetStreamingStatus", &WSRequestHandler::GetStreamingStatus },
|
||||
{ "StartStopStreaming", &WSRequestHandler::StartStopStreaming },
|
||||
{ "StartStopRecording", &WSRequestHandler::StartStopRecording },
|
||||
|
||||
{ "StartRecording", WSRequestHandler::HandleStartRecording },
|
||||
{ "StopRecording", WSRequestHandler::HandleStopRecording },
|
||||
{ "PauseRecording", WSRequestHandler::HandlePauseRecording },
|
||||
{ "ResumeRecording", WSRequestHandler::HandleResumeRecording },
|
||||
{ "StartStreaming", &WSRequestHandler::StartStreaming },
|
||||
{ "StopStreaming", &WSRequestHandler::StopStreaming },
|
||||
|
||||
{ "StartStopReplayBuffer", WSRequestHandler::HandleStartStopReplayBuffer },
|
||||
{ "StartReplayBuffer", WSRequestHandler::HandleStartReplayBuffer },
|
||||
{ "StopReplayBuffer", WSRequestHandler::HandleStopReplayBuffer },
|
||||
{ "SaveReplayBuffer", WSRequestHandler::HandleSaveReplayBuffer },
|
||||
{ "StartRecording", &WSRequestHandler::StartRecording },
|
||||
{ "StopRecording", &WSRequestHandler::StopRecording },
|
||||
{ "PauseRecording", &WSRequestHandler::PauseRecording },
|
||||
{ "ResumeRecording", &WSRequestHandler::ResumeRecording },
|
||||
|
||||
{ "SetRecordingFolder", WSRequestHandler::HandleSetRecordingFolder },
|
||||
{ "GetRecordingFolder", WSRequestHandler::HandleGetRecordingFolder },
|
||||
{ "StartStopReplayBuffer", &WSRequestHandler::StartStopReplayBuffer },
|
||||
{ "StartReplayBuffer", &WSRequestHandler::StartReplayBuffer },
|
||||
{ "StopReplayBuffer", &WSRequestHandler::StopReplayBuffer },
|
||||
{ "SaveReplayBuffer", &WSRequestHandler::SaveReplayBuffer },
|
||||
|
||||
{ "GetTransitionList", WSRequestHandler::HandleGetTransitionList },
|
||||
{ "GetCurrentTransition", WSRequestHandler::HandleGetCurrentTransition },
|
||||
{ "SetCurrentTransition", WSRequestHandler::HandleSetCurrentTransition },
|
||||
{ "SetTransitionDuration", WSRequestHandler::HandleSetTransitionDuration },
|
||||
{ "GetTransitionDuration", WSRequestHandler::HandleGetTransitionDuration },
|
||||
{ "SetRecordingFolder", &WSRequestHandler::SetRecordingFolder },
|
||||
{ "GetRecordingFolder", &WSRequestHandler::GetRecordingFolder },
|
||||
|
||||
{ "SetVolume", WSRequestHandler::HandleSetVolume },
|
||||
{ "GetVolume", WSRequestHandler::HandleGetVolume },
|
||||
{ "ToggleMute", WSRequestHandler::HandleToggleMute },
|
||||
{ "SetMute", WSRequestHandler::HandleSetMute },
|
||||
{ "GetMute", WSRequestHandler::HandleGetMute },
|
||||
{ "SetSyncOffset", WSRequestHandler::HandleSetSyncOffset },
|
||||
{ "GetSyncOffset", WSRequestHandler::HandleGetSyncOffset },
|
||||
{ "GetSpecialSources", WSRequestHandler::HandleGetSpecialSources },
|
||||
{ "GetSourcesList", WSRequestHandler::HandleGetSourcesList },
|
||||
{ "GetSourceTypesList", WSRequestHandler::HandleGetSourceTypesList },
|
||||
{ "GetSourceSettings", WSRequestHandler::HandleGetSourceSettings },
|
||||
{ "SetSourceSettings", WSRequestHandler::HandleSetSourceSettings },
|
||||
{ "TakeSourceScreenshot", WSRequestHandler::HandleTakeSourceScreenshot },
|
||||
{ "GetTransitionList", &WSRequestHandler::GetTransitionList },
|
||||
{ "GetCurrentTransition", &WSRequestHandler::GetCurrentTransition },
|
||||
{ "SetCurrentTransition", &WSRequestHandler::SetCurrentTransition },
|
||||
{ "SetTransitionDuration", &WSRequestHandler::SetTransitionDuration },
|
||||
{ "GetTransitionDuration", &WSRequestHandler::GetTransitionDuration },
|
||||
|
||||
{ "GetSourceFilters", WSRequestHandler::HandleGetSourceFilters },
|
||||
{ "GetSourceFilterInfo", WSRequestHandler::HandleGetSourceFilterInfo },
|
||||
{ "AddFilterToSource", WSRequestHandler::HandleAddFilterToSource },
|
||||
{ "RemoveFilterFromSource", WSRequestHandler::HandleRemoveFilterFromSource },
|
||||
{ "ReorderSourceFilter", WSRequestHandler::HandleReorderSourceFilter },
|
||||
{ "MoveSourceFilter", WSRequestHandler::HandleMoveSourceFilter },
|
||||
{ "SetSourceFilterSettings", WSRequestHandler::HandleSetSourceFilterSettings },
|
||||
{ "SetSourceFilterVisibility", WSRequestHandler::HandleSetSourceFilterVisibility },
|
||||
{ "SetVolume", &WSRequestHandler::SetVolume },
|
||||
{ "GetVolume", &WSRequestHandler::GetVolume },
|
||||
{ "ToggleMute", &WSRequestHandler::ToggleMute },
|
||||
{ "SetMute", &WSRequestHandler::SetMute },
|
||||
{ "GetMute", &WSRequestHandler::GetMute },
|
||||
{ "SetSyncOffset", &WSRequestHandler::SetSyncOffset },
|
||||
{ "GetSyncOffset", &WSRequestHandler::GetSyncOffset },
|
||||
{ "GetSpecialSources", &WSRequestHandler::GetSpecialSources },
|
||||
{ "GetSourcesList", &WSRequestHandler::GetSourcesList },
|
||||
{ "GetSourceTypesList", &WSRequestHandler::GetSourceTypesList },
|
||||
{ "GetSourceSettings", &WSRequestHandler::GetSourceSettings },
|
||||
{ "SetSourceSettings", &WSRequestHandler::SetSourceSettings },
|
||||
{ "TakeSourceScreenshot", &WSRequestHandler::TakeSourceScreenshot },
|
||||
|
||||
{ "SetCurrentSceneCollection", WSRequestHandler::HandleSetCurrentSceneCollection },
|
||||
{ "GetCurrentSceneCollection", WSRequestHandler::HandleGetCurrentSceneCollection },
|
||||
{ "ListSceneCollections", WSRequestHandler::HandleListSceneCollections },
|
||||
{ "GetSourceFilters", &WSRequestHandler::GetSourceFilters },
|
||||
{ "GetSourceFilterInfo", &WSRequestHandler::GetSourceFilterInfo },
|
||||
{ "AddFilterToSource", &WSRequestHandler::AddFilterToSource },
|
||||
{ "RemoveFilterFromSource", &WSRequestHandler::RemoveFilterFromSource },
|
||||
{ "ReorderSourceFilter", &WSRequestHandler::ReorderSourceFilter },
|
||||
{ "MoveSourceFilter", &WSRequestHandler::MoveSourceFilter },
|
||||
{ "SetSourceFilterSettings", &WSRequestHandler::SetSourceFilterSettings },
|
||||
{ "SetSourceFilterVisibility", &WSRequestHandler::SetSourceFilterVisibility },
|
||||
|
||||
{ "SetCurrentProfile", WSRequestHandler::HandleSetCurrentProfile },
|
||||
{ "GetCurrentProfile", WSRequestHandler::HandleGetCurrentProfile },
|
||||
{ "ListProfiles", WSRequestHandler::HandleListProfiles },
|
||||
{ "SetCurrentSceneCollection", &WSRequestHandler::SetCurrentSceneCollection },
|
||||
{ "GetCurrentSceneCollection", &WSRequestHandler::GetCurrentSceneCollection },
|
||||
{ "ListSceneCollections", &WSRequestHandler::ListSceneCollections },
|
||||
|
||||
{ "SetStreamSettings", WSRequestHandler::HandleSetStreamSettings },
|
||||
{ "GetStreamSettings", WSRequestHandler::HandleGetStreamSettings },
|
||||
{ "SaveStreamSettings", WSRequestHandler::HandleSaveStreamSettings },
|
||||
{ "SetCurrentProfile", &WSRequestHandler::SetCurrentProfile },
|
||||
{ "GetCurrentProfile", &WSRequestHandler::GetCurrentProfile },
|
||||
{ "ListProfiles", &WSRequestHandler::ListProfiles },
|
||||
|
||||
{ "SetStreamSettings", &WSRequestHandler::SetStreamSettings },
|
||||
{ "GetStreamSettings", &WSRequestHandler::GetStreamSettings },
|
||||
{ "SaveStreamSettings", &WSRequestHandler::SaveStreamSettings },
|
||||
#if BUILD_CAPTIONS
|
||||
{ "SendCaptions", WSRequestHandler::HandleSendCaptions },
|
||||
{ "SendCaptions", &WSRequestHandler::SendCaptions },
|
||||
#endif
|
||||
|
||||
{ "GetStudioModeStatus", WSRequestHandler::HandleGetStudioModeStatus },
|
||||
{ "GetPreviewScene", WSRequestHandler::HandleGetPreviewScene },
|
||||
{ "SetPreviewScene", WSRequestHandler::HandleSetPreviewScene },
|
||||
{ "TransitionToProgram", WSRequestHandler::HandleTransitionToProgram },
|
||||
{ "EnableStudioMode", WSRequestHandler::HandleEnableStudioMode },
|
||||
{ "DisableStudioMode", WSRequestHandler::HandleDisableStudioMode },
|
||||
{ "ToggleStudioMode", WSRequestHandler::HandleToggleStudioMode },
|
||||
{ "GetStudioModeStatus", &WSRequestHandler::GetStudioModeStatus },
|
||||
{ "GetPreviewScene", &WSRequestHandler::GetPreviewScene },
|
||||
{ "SetPreviewScene", &WSRequestHandler::SetPreviewScene },
|
||||
{ "TransitionToProgram", &WSRequestHandler::TransitionToProgram },
|
||||
{ "EnableStudioMode", &WSRequestHandler::EnableStudioMode },
|
||||
{ "DisableStudioMode", &WSRequestHandler::DisableStudioMode },
|
||||
{ "ToggleStudioMode", &WSRequestHandler::ToggleStudioMode },
|
||||
|
||||
{ "SetTextGDIPlusProperties", WSRequestHandler::HandleSetTextGDIPlusProperties },
|
||||
{ "GetTextGDIPlusProperties", WSRequestHandler::HandleGetTextGDIPlusProperties },
|
||||
{ "SetTextGDIPlusProperties", &WSRequestHandler::SetTextGDIPlusProperties },
|
||||
{ "GetTextGDIPlusProperties", &WSRequestHandler::GetTextGDIPlusProperties },
|
||||
|
||||
{ "SetTextFreetype2Properties", WSRequestHandler::HandleSetTextFreetype2Properties },
|
||||
{ "GetTextFreetype2Properties", WSRequestHandler::HandleGetTextFreetype2Properties },
|
||||
{ "SetTextFreetype2Properties", &WSRequestHandler::SetTextFreetype2Properties },
|
||||
{ "GetTextFreetype2Properties", &WSRequestHandler::GetTextFreetype2Properties },
|
||||
|
||||
{ "GetBrowserSourceProperties", WSRequestHandler::HandleGetBrowserSourceProperties },
|
||||
{ "SetBrowserSourceProperties", WSRequestHandler::HandleSetBrowserSourceProperties },
|
||||
{ "GetBrowserSourceProperties", &WSRequestHandler::GetBrowserSourceProperties },
|
||||
{ "SetBrowserSourceProperties", &WSRequestHandler::SetBrowserSourceProperties },
|
||||
|
||||
{ "ListOutputs", WSRequestHandler::HandleListOutputs },
|
||||
{ "GetOutputInfo", WSRequestHandler::HandleGetOutputInfo },
|
||||
{ "StartOutput", WSRequestHandler::HandleStartOutput },
|
||||
{ "StopOutput", WSRequestHandler::HandleStopOutput }
|
||||
{ "ListOutputs", &WSRequestHandler::ListOutputs },
|
||||
{ "GetOutputInfo", &WSRequestHandler::GetOutputInfo },
|
||||
{ "StartOutput", &WSRequestHandler::StartOutput },
|
||||
{ "StopOutput", &WSRequestHandler::StopOutput }
|
||||
};
|
||||
|
||||
QSet<QString> WSRequestHandler::authNotRequired {
|
||||
const QSet<QString> WSRequestHandler::authNotRequired {
|
||||
"GetVersion",
|
||||
"GetAuthRequired",
|
||||
"Authenticate"
|
||||
};
|
||||
|
||||
WSRequestHandler::WSRequestHandler(ConnectionProperties& connProperties) :
|
||||
_messageId(0),
|
||||
_requestType(""),
|
||||
data(nullptr),
|
||||
_connProperties(connProperties)
|
||||
{
|
||||
}
|
||||
|
||||
std::string WSRequestHandler::processIncomingMessage(std::string& textMessage) {
|
||||
if (GetConfig()->DebugEnabled) {
|
||||
blog(LOG_INFO, "Request >> '%s'", textMessage.c_str());
|
||||
}
|
||||
|
||||
OBSDataAutoRelease responseData = processRequest(textMessage);
|
||||
std::string response = obs_data_get_json(responseData);
|
||||
|
||||
if (GetConfig()->DebugEnabled) {
|
||||
blog(LOG_INFO, "Response << '%s'", response.c_str());
|
||||
}
|
||||
|
||||
return response;
|
||||
}
|
||||
|
||||
HandlerResponse WSRequestHandler::processRequest(std::string& textMessage){
|
||||
std::string msgContainer(textMessage);
|
||||
const char* msg = msgContainer.c_str();
|
||||
|
||||
data = obs_data_create_from_json(msg);
|
||||
if (!data) {
|
||||
blog(LOG_ERROR, "invalid JSON payload received for '%s'", msg);
|
||||
return SendErrorResponse("invalid JSON payload");
|
||||
}
|
||||
|
||||
if (!hasField("request-type") || !hasField("message-id")) {
|
||||
return SendErrorResponse("missing request parameters");
|
||||
}
|
||||
|
||||
_requestType = obs_data_get_string(data, "request-type");
|
||||
_messageId = obs_data_get_string(data, "message-id");
|
||||
|
||||
RpcResponse WSRequestHandler::processRequest(const RpcRequest& request){
|
||||
if (GetConfig()->AuthRequired
|
||||
&& (!authNotRequired.contains(_requestType))
|
||||
&& (!authNotRequired.contains(request.methodName()))
|
||||
&& (!_connProperties.isAuthenticated()))
|
||||
{
|
||||
return SendErrorResponse("Not Authenticated");
|
||||
return RpcResponse::fail(request, "Not Authenticated");
|
||||
}
|
||||
|
||||
HandlerResponse (*handlerFunc)(WSRequestHandler*) = (messageMap[_requestType]);
|
||||
RpcMethodHandler handlerFunc = messageMap[request.methodName()];
|
||||
if (!handlerFunc) {
|
||||
return SendErrorResponse("invalid request type");
|
||||
return RpcResponse::fail(request, "invalid request type");
|
||||
}
|
||||
|
||||
return handlerFunc(this);
|
||||
}
|
||||
|
||||
WSRequestHandler::~WSRequestHandler() {
|
||||
}
|
||||
|
||||
HandlerResponse WSRequestHandler::SendOKResponse(obs_data_t* additionalFields) {
|
||||
return SendResponse("ok", additionalFields);
|
||||
}
|
||||
|
||||
HandlerResponse WSRequestHandler::SendErrorResponse(QString errorMessage) {
|
||||
OBSDataAutoRelease fields = obs_data_create();
|
||||
obs_data_set_string(fields, "error", errorMessage.toUtf8().constData());
|
||||
|
||||
return SendResponse("error", fields);
|
||||
}
|
||||
|
||||
HandlerResponse WSRequestHandler::SendErrorResponse(obs_data_t* additionalFields) {
|
||||
return SendResponse("error", additionalFields);
|
||||
}
|
||||
|
||||
HandlerResponse WSRequestHandler::SendResponse(const char* status, obs_data_t* fields) {
|
||||
obs_data_t* response = obs_data_create();
|
||||
obs_data_set_string(response, "message-id", _messageId);
|
||||
obs_data_set_string(response, "status", status);
|
||||
|
||||
if (fields) {
|
||||
obs_data_apply(response, fields);
|
||||
}
|
||||
|
||||
return response;
|
||||
}
|
||||
|
||||
bool WSRequestHandler::hasField(QString name, obs_data_type expectedFieldType, obs_data_number_type expectedNumberType) {
|
||||
if (!data || name.isEmpty() || name.isNull()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
OBSDataItemAutoRelease dataItem = obs_data_item_byname(data, name.toUtf8());
|
||||
if (!dataItem) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (expectedFieldType != OBS_DATA_NULL) {
|
||||
obs_data_type fieldType = obs_data_item_gettype(dataItem);
|
||||
if (fieldType != expectedFieldType) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (fieldType == OBS_DATA_NUMBER && expectedNumberType != OBS_DATA_NUM_INVALID) {
|
||||
obs_data_number_type numberType = obs_data_item_numtype(dataItem);
|
||||
if (numberType != expectedNumberType) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool WSRequestHandler::hasBool(QString fieldName) {
|
||||
return this->hasField(fieldName, OBS_DATA_BOOLEAN);
|
||||
}
|
||||
|
||||
bool WSRequestHandler::hasString(QString fieldName) {
|
||||
return this->hasField(fieldName, OBS_DATA_STRING);
|
||||
}
|
||||
|
||||
bool WSRequestHandler::hasNumber(QString fieldName, obs_data_number_type expectedNumberType) {
|
||||
return this->hasField(fieldName, OBS_DATA_NUMBER, expectedNumberType);
|
||||
}
|
||||
|
||||
bool WSRequestHandler::hasInteger(QString fieldName) {
|
||||
return this->hasNumber(fieldName, OBS_DATA_NUM_INT);
|
||||
}
|
||||
|
||||
bool WSRequestHandler::hasDouble(QString fieldName) {
|
||||
return this->hasNumber(fieldName, OBS_DATA_NUM_DOUBLE);
|
||||
}
|
||||
|
||||
bool WSRequestHandler::hasArray(QString fieldName) {
|
||||
return this->hasField(fieldName, OBS_DATA_ARRAY);
|
||||
}
|
||||
|
||||
bool WSRequestHandler::hasObject(QString fieldName) {
|
||||
return this->hasField(fieldName, OBS_DATA_OBJECT);
|
||||
return std::bind(handlerFunc, this, _1)(request);
|
||||
}
|
||||
|
@ -19,171 +19,146 @@ with this program. If not, see <https://www.gnu.org/licenses/>
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <QtCore/QString>
|
||||
#include <QtCore/QHash>
|
||||
#include <QtCore/QSet>
|
||||
#include <QtCore/QVariantHash>
|
||||
#include <QtCore/QString>
|
||||
#include <QtCore/QSharedPointer>
|
||||
|
||||
#include <obs.hpp>
|
||||
#include <obs-frontend-api.h>
|
||||
|
||||
#include "ConnectionProperties.h"
|
||||
|
||||
#include "rpc/RpcRequest.h"
|
||||
#include "rpc/RpcResponse.h"
|
||||
|
||||
#include "obs-websocket.h"
|
||||
|
||||
typedef obs_data_t* HandlerResponse;
|
||||
|
||||
class WSRequestHandler : public QObject {
|
||||
Q_OBJECT
|
||||
class WSRequestHandler;
|
||||
typedef RpcResponse(WSRequestHandler::*RpcMethodHandler)(const RpcRequest&);
|
||||
|
||||
class WSRequestHandler {
|
||||
public:
|
||||
explicit WSRequestHandler(ConnectionProperties& connProperties);
|
||||
~WSRequestHandler();
|
||||
std::string processIncomingMessage(std::string& textMessage);
|
||||
|
||||
bool hasField(QString fieldName, obs_data_type expectedFieldType = OBS_DATA_NULL,
|
||||
obs_data_number_type expectedNumberType = OBS_DATA_NUM_INVALID);
|
||||
bool hasBool(QString fieldName);
|
||||
bool hasString(QString fieldName);
|
||||
bool hasNumber(QString fieldName, obs_data_number_type expectedNumberType = OBS_DATA_NUM_INVALID);
|
||||
bool hasInteger(QString fieldName);
|
||||
bool hasDouble(QString fieldName);
|
||||
bool hasArray(QString fieldName);
|
||||
bool hasObject(QString fieldName);
|
||||
|
||||
HandlerResponse SendOKResponse(obs_data_t* additionalFields = nullptr);
|
||||
HandlerResponse SendErrorResponse(QString errorMessage);
|
||||
HandlerResponse SendErrorResponse(obs_data_t* additionalFields = nullptr);
|
||||
HandlerResponse SendResponse(const char* status, obs_data_t* additionalFields = nullptr);
|
||||
|
||||
obs_data_t* parameters() {
|
||||
return this->data;
|
||||
}
|
||||
RpcResponse processRequest(const RpcRequest& textMessage);
|
||||
|
||||
private:
|
||||
const char* _messageId;
|
||||
const char* _requestType;
|
||||
ConnectionProperties& _connProperties;
|
||||
OBSDataAutoRelease data;
|
||||
|
||||
HandlerResponse processRequest(std::string& textMessage);
|
||||
static const QHash<QString, RpcMethodHandler> messageMap;
|
||||
static const QSet<QString> authNotRequired;
|
||||
|
||||
static QHash<QString, HandlerResponse(*)(WSRequestHandler*)> messageMap;
|
||||
static QSet<QString> authNotRequired;
|
||||
RpcResponse GetVersion(const RpcRequest&);
|
||||
RpcResponse GetAuthRequired(const RpcRequest&);
|
||||
RpcResponse Authenticate(const RpcRequest&);
|
||||
|
||||
static HandlerResponse HandleGetVersion(WSRequestHandler* req);
|
||||
static HandlerResponse HandleGetAuthRequired(WSRequestHandler* req);
|
||||
static HandlerResponse HandleAuthenticate(WSRequestHandler* req);
|
||||
RpcResponse GetStats(const RpcRequest&);
|
||||
RpcResponse SetHeartbeat(const RpcRequest&);
|
||||
RpcResponse GetVideoInfo(const RpcRequest&);
|
||||
|
||||
static HandlerResponse HandleGetStats(WSRequestHandler* req);
|
||||
static HandlerResponse HandleSetHeartbeat(WSRequestHandler* req);
|
||||
static HandlerResponse HandleGetVideoInfo(WSRequestHandler* req);
|
||||
RpcResponse SetFilenameFormatting(const RpcRequest&);
|
||||
RpcResponse GetFilenameFormatting(const RpcRequest&);
|
||||
|
||||
static HandlerResponse HandleSetFilenameFormatting(WSRequestHandler* req);
|
||||
static HandlerResponse HandleGetFilenameFormatting(WSRequestHandler* req);
|
||||
RpcResponse BroadcastCustomMessage(const RpcRequest&);
|
||||
|
||||
static HandlerResponse HandleBroadcastCustomMessage(WSRequestHandler* req);
|
||||
RpcResponse SetCurrentScene(const RpcRequest&);
|
||||
RpcResponse GetCurrentScene(const RpcRequest&);
|
||||
RpcResponse GetSceneList(const RpcRequest&);
|
||||
|
||||
static HandlerResponse HandleSetCurrentScene(WSRequestHandler* req);
|
||||
static HandlerResponse HandleGetCurrentScene(WSRequestHandler* req);
|
||||
static HandlerResponse HandleGetSceneList(WSRequestHandler* req);
|
||||
RpcResponse SetSceneItemRender(const RpcRequest&);
|
||||
RpcResponse SetSceneItemPosition(const RpcRequest&);
|
||||
RpcResponse SetSceneItemTransform(const RpcRequest&);
|
||||
RpcResponse SetSceneItemCrop(const RpcRequest&);
|
||||
RpcResponse GetSceneItemProperties(const RpcRequest&);
|
||||
RpcResponse SetSceneItemProperties(const RpcRequest&);
|
||||
RpcResponse ResetSceneItem(const RpcRequest&);
|
||||
RpcResponse DuplicateSceneItem(const RpcRequest&);
|
||||
RpcResponse DeleteSceneItem(const RpcRequest&);
|
||||
RpcResponse ReorderSceneItems(const RpcRequest&);
|
||||
|
||||
static HandlerResponse HandleSetSceneItemRender(WSRequestHandler* req);
|
||||
static HandlerResponse HandleSetSceneItemPosition(WSRequestHandler* req);
|
||||
static HandlerResponse HandleSetSceneItemTransform(WSRequestHandler* req);
|
||||
static HandlerResponse HandleSetSceneItemCrop(WSRequestHandler* req);
|
||||
static HandlerResponse HandleGetSceneItemProperties(WSRequestHandler* req);
|
||||
static HandlerResponse HandleSetSceneItemProperties(WSRequestHandler* req);
|
||||
static HandlerResponse HandleResetSceneItem(WSRequestHandler* req);
|
||||
static HandlerResponse HandleDuplicateSceneItem(WSRequestHandler* req);
|
||||
static HandlerResponse HandleDeleteSceneItem(WSRequestHandler* req);
|
||||
static HandlerResponse HandleReorderSceneItems(WSRequestHandler* req);
|
||||
RpcResponse GetStreamingStatus(const RpcRequest&);
|
||||
RpcResponse StartStopStreaming(const RpcRequest&);
|
||||
RpcResponse StartStopRecording(const RpcRequest&);
|
||||
|
||||
static HandlerResponse HandleGetStreamingStatus(WSRequestHandler* req);
|
||||
static HandlerResponse HandleStartStopStreaming(WSRequestHandler* req);
|
||||
static HandlerResponse HandleStartStopRecording(WSRequestHandler* req);
|
||||
RpcResponse StartStreaming(const RpcRequest&);
|
||||
RpcResponse StopStreaming(const RpcRequest&);
|
||||
|
||||
static HandlerResponse HandleStartStreaming(WSRequestHandler* req);
|
||||
static HandlerResponse HandleStopStreaming(WSRequestHandler* req);
|
||||
RpcResponse StartRecording(const RpcRequest&);
|
||||
RpcResponse StopRecording(const RpcRequest&);
|
||||
RpcResponse PauseRecording(const RpcRequest&);
|
||||
RpcResponse ResumeRecording(const RpcRequest&);
|
||||
|
||||
static HandlerResponse HandleStartRecording(WSRequestHandler* req);
|
||||
static HandlerResponse HandleStopRecording(WSRequestHandler* req);
|
||||
static HandlerResponse HandlePauseRecording(WSRequestHandler* req);
|
||||
static HandlerResponse HandleResumeRecording(WSRequestHandler* req);
|
||||
RpcResponse StartStopReplayBuffer(const RpcRequest&);
|
||||
RpcResponse StartReplayBuffer(const RpcRequest&);
|
||||
RpcResponse StopReplayBuffer(const RpcRequest&);
|
||||
RpcResponse SaveReplayBuffer(const RpcRequest&);
|
||||
|
||||
static HandlerResponse HandleStartStopReplayBuffer(WSRequestHandler* req);
|
||||
static HandlerResponse HandleStartReplayBuffer(WSRequestHandler* req);
|
||||
static HandlerResponse HandleStopReplayBuffer(WSRequestHandler* req);
|
||||
static HandlerResponse HandleSaveReplayBuffer(WSRequestHandler* req);
|
||||
RpcResponse SetRecordingFolder(const RpcRequest&);
|
||||
RpcResponse GetRecordingFolder(const RpcRequest&);
|
||||
|
||||
static HandlerResponse HandleSetRecordingFolder(WSRequestHandler* req);
|
||||
static HandlerResponse HandleGetRecordingFolder(WSRequestHandler* req);
|
||||
RpcResponse GetTransitionList(const RpcRequest&);
|
||||
RpcResponse GetCurrentTransition(const RpcRequest&);
|
||||
RpcResponse SetCurrentTransition(const RpcRequest&);
|
||||
|
||||
static HandlerResponse HandleGetTransitionList(WSRequestHandler* req);
|
||||
static HandlerResponse HandleGetCurrentTransition(WSRequestHandler* req);
|
||||
static HandlerResponse HandleSetCurrentTransition(WSRequestHandler* req);
|
||||
RpcResponse SetVolume(const RpcRequest&);
|
||||
RpcResponse GetVolume(const RpcRequest&);
|
||||
RpcResponse ToggleMute(const RpcRequest&);
|
||||
RpcResponse SetMute(const RpcRequest&);
|
||||
RpcResponse GetMute(const RpcRequest&);
|
||||
RpcResponse SetSyncOffset(const RpcRequest&);
|
||||
RpcResponse GetSyncOffset(const RpcRequest&);
|
||||
RpcResponse GetSpecialSources(const RpcRequest&);
|
||||
RpcResponse GetSourcesList(const RpcRequest&);
|
||||
RpcResponse GetSourceTypesList(const RpcRequest&);
|
||||
RpcResponse GetSourceSettings(const RpcRequest&);
|
||||
RpcResponse SetSourceSettings(const RpcRequest&);
|
||||
RpcResponse TakeSourceScreenshot(const RpcRequest&);
|
||||
|
||||
static HandlerResponse HandleSetVolume(WSRequestHandler* req);
|
||||
static HandlerResponse HandleGetVolume(WSRequestHandler* req);
|
||||
static HandlerResponse HandleToggleMute(WSRequestHandler* req);
|
||||
static HandlerResponse HandleSetMute(WSRequestHandler* req);
|
||||
static HandlerResponse HandleGetMute(WSRequestHandler* req);
|
||||
static HandlerResponse HandleSetSyncOffset(WSRequestHandler* req);
|
||||
static HandlerResponse HandleGetSyncOffset(WSRequestHandler* req);
|
||||
static HandlerResponse HandleGetSpecialSources(WSRequestHandler* req);
|
||||
static HandlerResponse HandleGetSourcesList(WSRequestHandler* req);
|
||||
static HandlerResponse HandleGetSourceTypesList(WSRequestHandler* req);
|
||||
static HandlerResponse HandleGetSourceSettings(WSRequestHandler* req);
|
||||
static HandlerResponse HandleSetSourceSettings(WSRequestHandler* req);
|
||||
static HandlerResponse HandleTakeSourceScreenshot(WSRequestHandler* req);
|
||||
RpcResponse GetSourceFilters(const RpcRequest&);
|
||||
RpcResponse GetSourceFilterInfo(const RpcRequest&);
|
||||
RpcResponse AddFilterToSource(const RpcRequest&);
|
||||
RpcResponse RemoveFilterFromSource(const RpcRequest&);
|
||||
RpcResponse ReorderSourceFilter(const RpcRequest&);
|
||||
RpcResponse MoveSourceFilter(const RpcRequest&);
|
||||
RpcResponse SetSourceFilterSettings(const RpcRequest&);
|
||||
RpcResponse SetSourceFilterVisibility(const RpcRequest&);
|
||||
|
||||
static HandlerResponse HandleGetSourceFilters(WSRequestHandler* req);
|
||||
static HandlerResponse HandleGetSourceFilterInfo(WSRequestHandler* req);
|
||||
static HandlerResponse HandleAddFilterToSource(WSRequestHandler* req);
|
||||
static HandlerResponse HandleRemoveFilterFromSource(WSRequestHandler* req);
|
||||
static HandlerResponse HandleReorderSourceFilter(WSRequestHandler* req);
|
||||
static HandlerResponse HandleMoveSourceFilter(WSRequestHandler* req);
|
||||
static HandlerResponse HandleSetSourceFilterSettings(WSRequestHandler* req);
|
||||
static HandlerResponse HandleSetSourceFilterVisibility(WSRequestHandler* req);
|
||||
RpcResponse SetCurrentSceneCollection(const RpcRequest&);
|
||||
RpcResponse GetCurrentSceneCollection(const RpcRequest&);
|
||||
RpcResponse ListSceneCollections(const RpcRequest&);
|
||||
|
||||
static HandlerResponse HandleSetCurrentSceneCollection(WSRequestHandler* req);
|
||||
static HandlerResponse HandleGetCurrentSceneCollection(WSRequestHandler* req);
|
||||
static HandlerResponse HandleListSceneCollections(WSRequestHandler* req);
|
||||
RpcResponse SetCurrentProfile(const RpcRequest&);
|
||||
RpcResponse GetCurrentProfile(const RpcRequest&);
|
||||
RpcResponse ListProfiles(const RpcRequest&);
|
||||
|
||||
static HandlerResponse HandleSetCurrentProfile(WSRequestHandler* req);
|
||||
static HandlerResponse HandleGetCurrentProfile(WSRequestHandler* req);
|
||||
static HandlerResponse HandleListProfiles(WSRequestHandler* req);
|
||||
|
||||
static HandlerResponse HandleSetStreamSettings(WSRequestHandler* req);
|
||||
static HandlerResponse HandleGetStreamSettings(WSRequestHandler* req);
|
||||
static HandlerResponse HandleSaveStreamSettings(WSRequestHandler* req);
|
||||
RpcResponse SetStreamSettings(const RpcRequest&);
|
||||
RpcResponse GetStreamSettings(const RpcRequest&);
|
||||
RpcResponse SaveStreamSettings(const RpcRequest&);
|
||||
#if BUILD_CAPTIONS
|
||||
static HandlerResponse HandleSendCaptions(WSRequestHandler * req);
|
||||
RpcResponse SendCaptions(const RpcRequest&);
|
||||
#endif
|
||||
|
||||
static HandlerResponse HandleSetTransitionDuration(WSRequestHandler* req);
|
||||
static HandlerResponse HandleGetTransitionDuration(WSRequestHandler* req);
|
||||
RpcResponse SetTransitionDuration(const RpcRequest&);
|
||||
RpcResponse GetTransitionDuration(const RpcRequest&);
|
||||
|
||||
static HandlerResponse HandleGetStudioModeStatus(WSRequestHandler* req);
|
||||
static HandlerResponse HandleGetPreviewScene(WSRequestHandler* req);
|
||||
static HandlerResponse HandleSetPreviewScene(WSRequestHandler* req);
|
||||
static HandlerResponse HandleTransitionToProgram(WSRequestHandler* req);
|
||||
static HandlerResponse HandleEnableStudioMode(WSRequestHandler* req);
|
||||
static HandlerResponse HandleDisableStudioMode(WSRequestHandler* req);
|
||||
static HandlerResponse HandleToggleStudioMode(WSRequestHandler* req);
|
||||
RpcResponse GetStudioModeStatus(const RpcRequest&);
|
||||
RpcResponse GetPreviewScene(const RpcRequest&);
|
||||
RpcResponse SetPreviewScene(const RpcRequest&);
|
||||
RpcResponse TransitionToProgram(const RpcRequest&);
|
||||
RpcResponse EnableStudioMode(const RpcRequest&);
|
||||
RpcResponse DisableStudioMode(const RpcRequest&);
|
||||
RpcResponse ToggleStudioMode(const RpcRequest&);
|
||||
|
||||
static HandlerResponse HandleSetTextGDIPlusProperties(WSRequestHandler* req);
|
||||
static HandlerResponse HandleGetTextGDIPlusProperties(WSRequestHandler* req);
|
||||
RpcResponse SetTextGDIPlusProperties(const RpcRequest&);
|
||||
RpcResponse GetTextGDIPlusProperties(const RpcRequest&);
|
||||
|
||||
static HandlerResponse HandleSetTextFreetype2Properties(WSRequestHandler* req);
|
||||
static HandlerResponse HandleGetTextFreetype2Properties(WSRequestHandler* req);
|
||||
RpcResponse SetTextFreetype2Properties(const RpcRequest&);
|
||||
RpcResponse GetTextFreetype2Properties(const RpcRequest&);
|
||||
|
||||
static HandlerResponse HandleSetBrowserSourceProperties(WSRequestHandler* req);
|
||||
static HandlerResponse HandleGetBrowserSourceProperties(WSRequestHandler* req);
|
||||
RpcResponse SetBrowserSourceProperties(const RpcRequest&);
|
||||
RpcResponse GetBrowserSourceProperties(const RpcRequest&);
|
||||
|
||||
static HandlerResponse HandleListOutputs(WSRequestHandler* req);
|
||||
static HandlerResponse HandleGetOutputInfo(WSRequestHandler* req);
|
||||
static HandlerResponse HandleStartOutput(WSRequestHandler* req);
|
||||
static HandlerResponse HandleStopOutput(WSRequestHandler* req);
|
||||
RpcResponse ListOutputs(const RpcRequest&);
|
||||
RpcResponse GetOutputInfo(const RpcRequest&);
|
||||
RpcResponse StartOutput(const RpcRequest&);
|
||||
RpcResponse StopOutput(const RpcRequest&);
|
||||
};
|
||||
|
@ -66,10 +66,10 @@ const char *describe_scale_type(int scale) {
|
||||
* @category general
|
||||
* @since 0.3
|
||||
*/
|
||||
HandlerResponse WSRequestHandler::HandleGetVersion(WSRequestHandler* req) {
|
||||
RpcResponse WSRequestHandler::GetVersion(const RpcRequest& request) {
|
||||
QString obsVersion = Utils::OBSVersionString();
|
||||
|
||||
QList<QString> names = req->messageMap.keys();
|
||||
QList<QString> names = messageMap.keys();
|
||||
names.sort(Qt::CaseInsensitive);
|
||||
|
||||
// (Palakis) OBS' data arrays only support object arrays, so I improvised.
|
||||
@ -85,7 +85,7 @@ HandlerResponse WSRequestHandler::HandleGetVersion(WSRequestHandler* req) {
|
||||
obs_data_set_string(data, "obs-studio-version", obsVersion.toUtf8());
|
||||
obs_data_set_string(data, "available-requests", requests.toUtf8());
|
||||
|
||||
return req->SendOKResponse(data);
|
||||
return request.success(data);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -101,7 +101,7 @@ HandlerResponse WSRequestHandler::HandleGetVersion(WSRequestHandler* req) {
|
||||
* @category general
|
||||
* @since 0.3
|
||||
*/
|
||||
HandlerResponse WSRequestHandler::HandleGetAuthRequired(WSRequestHandler* req) {
|
||||
RpcResponse WSRequestHandler::GetAuthRequired(const RpcRequest& request) {
|
||||
bool authRequired = GetConfig()->AuthRequired;
|
||||
|
||||
OBSDataAutoRelease data = obs_data_create();
|
||||
@ -115,7 +115,7 @@ HandlerResponse WSRequestHandler::HandleGetAuthRequired(WSRequestHandler* req) {
|
||||
config->Salt.toUtf8());
|
||||
}
|
||||
|
||||
return req->SendOKResponse(data);
|
||||
return request.success(data);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -128,26 +128,26 @@ HandlerResponse WSRequestHandler::HandleGetAuthRequired(WSRequestHandler* req) {
|
||||
* @category general
|
||||
* @since 0.3
|
||||
*/
|
||||
HandlerResponse WSRequestHandler::HandleAuthenticate(WSRequestHandler* req) {
|
||||
if (!req->hasField("auth")) {
|
||||
return req->SendErrorResponse("missing request parameters");
|
||||
RpcResponse WSRequestHandler::Authenticate(const RpcRequest& request) {
|
||||
if (!request.hasField("auth")) {
|
||||
return request.failed("missing request parameters");
|
||||
}
|
||||
|
||||
if (req->_connProperties.isAuthenticated()) {
|
||||
return req->SendErrorResponse("already authenticated");
|
||||
if (_connProperties.isAuthenticated()) {
|
||||
return request.failed("already authenticated");
|
||||
}
|
||||
|
||||
QString auth = obs_data_get_string(req->data, "auth");
|
||||
QString auth = obs_data_get_string(request.parameters(), "auth");
|
||||
if (auth.isEmpty()) {
|
||||
return req->SendErrorResponse("auth not specified!");
|
||||
return request.failed("auth not specified!");
|
||||
}
|
||||
|
||||
if (GetConfig()->CheckAuth(auth) == false) {
|
||||
return req->SendErrorResponse("Authentication Failed.");
|
||||
return request.failed("Authentication Failed.");
|
||||
}
|
||||
|
||||
req->_connProperties.setAuthenticated(true);
|
||||
return req->SendOKResponse();
|
||||
_connProperties.setAuthenticated(true);
|
||||
return request.success();
|
||||
}
|
||||
|
||||
/**
|
||||
@ -160,17 +160,18 @@ HandlerResponse WSRequestHandler::HandleAuthenticate(WSRequestHandler* req) {
|
||||
* @category general
|
||||
* @since 4.3.0
|
||||
*/
|
||||
HandlerResponse WSRequestHandler::HandleSetHeartbeat(WSRequestHandler* req) {
|
||||
if (!req->hasField("enable")) {
|
||||
return req->SendErrorResponse("Heartbeat <enable> parameter missing");
|
||||
RpcResponse WSRequestHandler::SetHeartbeat(const RpcRequest& request) {
|
||||
if (!request.hasField("enable")) {
|
||||
return request.failed("Heartbeat <enable> parameter missing");
|
||||
}
|
||||
|
||||
auto events = GetEventsSystem();
|
||||
events->HeartbeatIsActive = obs_data_get_bool(req->data, "enable");
|
||||
events->HeartbeatIsActive = obs_data_get_bool(request.parameters(), "enable");
|
||||
|
||||
OBSDataAutoRelease response = obs_data_create();
|
||||
obs_data_set_bool(response, "enable", events->HeartbeatIsActive);
|
||||
return req->SendOKResponse(response);
|
||||
|
||||
return request.success(response);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -183,18 +184,19 @@ HandlerResponse WSRequestHandler::HandleSetHeartbeat(WSRequestHandler* req) {
|
||||
* @category general
|
||||
* @since 4.3.0
|
||||
*/
|
||||
HandlerResponse WSRequestHandler::HandleSetFilenameFormatting(WSRequestHandler* req) {
|
||||
if (!req->hasField("filename-formatting")) {
|
||||
return req->SendErrorResponse("<filename-formatting> parameter missing");
|
||||
RpcResponse WSRequestHandler::SetFilenameFormatting(const RpcRequest& request) {
|
||||
if (!request.hasField("filename-formatting")) {
|
||||
return request.failed("<filename-formatting> parameter missing");
|
||||
}
|
||||
|
||||
QString filenameFormatting = obs_data_get_string(req->data, "filename-formatting");
|
||||
QString filenameFormatting = obs_data_get_string(request.parameters(), "filename-formatting");
|
||||
if (filenameFormatting.isEmpty()) {
|
||||
return req->SendErrorResponse("invalid request parameters");
|
||||
return request.failed("invalid request parameters");
|
||||
}
|
||||
|
||||
Utils::SetFilenameFormatting(filenameFormatting.toUtf8());
|
||||
return req->SendOKResponse();
|
||||
|
||||
return request.success();
|
||||
}
|
||||
|
||||
/**
|
||||
@ -207,10 +209,11 @@ HandlerResponse WSRequestHandler::HandleSetFilenameFormatting(WSRequestHandler*
|
||||
* @category general
|
||||
* @since 4.3.0
|
||||
*/
|
||||
HandlerResponse WSRequestHandler::HandleGetFilenameFormatting(WSRequestHandler* req) {
|
||||
RpcResponse WSRequestHandler::GetFilenameFormatting(const RpcRequest& request) {
|
||||
OBSDataAutoRelease response = obs_data_create();
|
||||
obs_data_set_string(response, "filename-formatting", Utils::GetFilenameFormatting());
|
||||
return req->SendOKResponse(response);
|
||||
|
||||
return request.success(response);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -223,12 +226,13 @@ HandlerResponse WSRequestHandler::HandleGetFilenameFormatting(WSRequestHandler*
|
||||
* @category general
|
||||
* @since 4.6.0
|
||||
*/
|
||||
HandlerResponse WSRequestHandler::HandleGetStats(WSRequestHandler* req) {
|
||||
RpcResponse WSRequestHandler::GetStats(const RpcRequest& request) {
|
||||
OBSDataAutoRelease stats = GetEventsSystem()->GetStats();
|
||||
|
||||
OBSDataAutoRelease response = obs_data_create();
|
||||
obs_data_set_obj(response, "stats", stats);
|
||||
return req->SendOKResponse(response);
|
||||
|
||||
return request.success(response);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -242,26 +246,26 @@ HandlerResponse WSRequestHandler::HandleGetStats(WSRequestHandler* req) {
|
||||
* @category general
|
||||
* @since 4.7.0
|
||||
*/
|
||||
HandlerResponse WSRequestHandler::HandleBroadcastCustomMessage(WSRequestHandler* req) {
|
||||
if (!req->hasField("realm") || !req->hasField("data")) {
|
||||
return req->SendErrorResponse("missing request parameters");
|
||||
RpcResponse WSRequestHandler::BroadcastCustomMessage(const RpcRequest& request) {
|
||||
if (!request.hasField("realm") || !request.hasField("data")) {
|
||||
return request.failed("missing request parameters");
|
||||
}
|
||||
|
||||
QString realm = obs_data_get_string(req->data, "realm");
|
||||
OBSDataAutoRelease data = obs_data_get_obj(req->data, "data");
|
||||
QString realm = obs_data_get_string(request.parameters(), "realm");
|
||||
OBSDataAutoRelease data = obs_data_get_obj(request.parameters(), "data");
|
||||
|
||||
if (realm.isEmpty()) {
|
||||
return req->SendErrorResponse("realm not specified!");
|
||||
return request.failed("realm not specified!");
|
||||
}
|
||||
|
||||
if (!data) {
|
||||
return req->SendErrorResponse("data not specified!");
|
||||
return request.failed("data not specified!");
|
||||
}
|
||||
|
||||
auto events = GetEventsSystem();
|
||||
events->OnBroadcastCustomMessage(realm, data);
|
||||
|
||||
return req->SendOKResponse();
|
||||
return request.success();
|
||||
}
|
||||
|
||||
|
||||
@ -283,9 +287,10 @@ HandlerResponse WSRequestHandler::HandleBroadcastCustomMessage(WSRequestHandler*
|
||||
* @category general
|
||||
* @since 4.6.0
|
||||
*/
|
||||
HandlerResponse WSRequestHandler::HandleGetVideoInfo(WSRequestHandler* req) {
|
||||
RpcResponse WSRequestHandler::GetVideoInfo(const RpcRequest& request) {
|
||||
obs_video_info ovi;
|
||||
obs_get_video_info(&ovi);
|
||||
|
||||
OBSDataAutoRelease response = obs_data_create();
|
||||
obs_data_set_int(response, "baseWidth", ovi.base_width);
|
||||
obs_data_set_int(response, "baseHeight", ovi.base_height);
|
||||
@ -296,5 +301,6 @@ HandlerResponse WSRequestHandler::HandleGetVideoInfo(WSRequestHandler* req) {
|
||||
obs_data_set_string(response, "colorSpace", describe_color_space(ovi.colorspace));
|
||||
obs_data_set_string(response, "colorRange", describe_color_range(ovi.range));
|
||||
obs_data_set_string(response, "scaleType", describe_scale_type(ovi.scale_type));
|
||||
return req->SendOKResponse(response);
|
||||
|
||||
return request.success(response);
|
||||
}
|
||||
|
@ -1,3 +1,5 @@
|
||||
#include <functional>
|
||||
|
||||
#include "WSRequestHandler.h"
|
||||
|
||||
/**
|
||||
@ -57,16 +59,16 @@ obs_data_t* getOutputInfo(obs_output_t* output)
|
||||
return data;
|
||||
}
|
||||
|
||||
HandlerResponse findOutputOrFail(WSRequestHandler* req, std::function<HandlerResponse (obs_output_t*)> callback)
|
||||
RpcResponse findOutputOrFail(const RpcRequest& request, std::function<RpcResponse (obs_output_t*)> callback)
|
||||
{
|
||||
if (!req->hasField("outputName")) {
|
||||
return req->SendErrorResponse("missing request parameters");
|
||||
if (!request.hasField("outputName")) {
|
||||
return request.failed("missing request parameters");
|
||||
}
|
||||
|
||||
const char* outputName = obs_data_get_string(req->parameters(), "outputName");
|
||||
const char* outputName = obs_data_get_string(request.parameters(), "outputName");
|
||||
OBSOutputAutoRelease output = obs_get_output_by_name(outputName);
|
||||
if (!output) {
|
||||
return req->SendErrorResponse("specified output doesn't exist");
|
||||
return request.failed("specified output doesn't exist");
|
||||
}
|
||||
|
||||
return callback(output);
|
||||
@ -82,7 +84,7 @@ HandlerResponse findOutputOrFail(WSRequestHandler* req, std::function<HandlerRes
|
||||
* @category outputs
|
||||
* @since 4.7.0
|
||||
*/
|
||||
HandlerResponse WSRequestHandler::HandleListOutputs(WSRequestHandler* req)
|
||||
RpcResponse WSRequestHandler::ListOutputs(const RpcRequest& request)
|
||||
{
|
||||
OBSDataArrayAutoRelease outputs = obs_data_array_create();
|
||||
|
||||
@ -97,7 +99,8 @@ HandlerResponse WSRequestHandler::HandleListOutputs(WSRequestHandler* req)
|
||||
|
||||
OBSDataAutoRelease fields = obs_data_create();
|
||||
obs_data_set_array(fields, "outputs", outputs);
|
||||
return req->SendOKResponse(fields);
|
||||
|
||||
return request.success(fields);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -112,14 +115,14 @@ HandlerResponse WSRequestHandler::HandleListOutputs(WSRequestHandler* req)
|
||||
* @category outputs
|
||||
* @since 4.7.0
|
||||
*/
|
||||
HandlerResponse WSRequestHandler::HandleGetOutputInfo(WSRequestHandler* req)
|
||||
RpcResponse WSRequestHandler::GetOutputInfo(const RpcRequest& request)
|
||||
{
|
||||
return findOutputOrFail(req, [req](obs_output_t* output) {
|
||||
return findOutputOrFail(request, [request](obs_output_t* output) {
|
||||
OBSDataAutoRelease outputInfo = getOutputInfo(output);
|
||||
|
||||
OBSDataAutoRelease fields = obs_data_create();
|
||||
obs_data_set_obj(fields, "outputInfo", outputInfo);
|
||||
return req->SendOKResponse(fields);
|
||||
return request.success(fields);
|
||||
});
|
||||
}
|
||||
|
||||
@ -133,21 +136,21 @@ HandlerResponse WSRequestHandler::HandleGetOutputInfo(WSRequestHandler* req)
|
||||
* @category outputs
|
||||
* @since 4.7.0
|
||||
*/
|
||||
HandlerResponse WSRequestHandler::HandleStartOutput(WSRequestHandler* req)
|
||||
RpcResponse WSRequestHandler::StartOutput(const RpcRequest& request)
|
||||
{
|
||||
return findOutputOrFail(req, [req](obs_output_t* output) {
|
||||
return findOutputOrFail(request, [request](obs_output_t* output) {
|
||||
if (obs_output_active(output)) {
|
||||
return req->SendErrorResponse("output already active");
|
||||
return request.failed("output already active");
|
||||
}
|
||||
|
||||
bool success = obs_output_start(output);
|
||||
if (!success) {
|
||||
QString lastError = obs_output_get_last_error(output);
|
||||
QString errorMessage = QString("output start failed: %1").arg(lastError);
|
||||
return req->SendErrorResponse(errorMessage);
|
||||
return request.failed(errorMessage);
|
||||
}
|
||||
|
||||
return req->SendOKResponse();
|
||||
return request.success();
|
||||
});
|
||||
}
|
||||
|
||||
@ -162,20 +165,20 @@ HandlerResponse WSRequestHandler::HandleStartOutput(WSRequestHandler* req)
|
||||
* @category outputs
|
||||
* @since 4.7.0
|
||||
*/
|
||||
HandlerResponse WSRequestHandler::HandleStopOutput(WSRequestHandler* req)
|
||||
RpcResponse WSRequestHandler::StopOutput(const RpcRequest& request)
|
||||
{
|
||||
return findOutputOrFail(req, [req](obs_output_t* output) {
|
||||
return findOutputOrFail(request, [request](obs_output_t* output) {
|
||||
if (!obs_output_active(output)) {
|
||||
return req->SendErrorResponse("output not active");
|
||||
return request.failed("output not active");
|
||||
}
|
||||
|
||||
bool forceStop = obs_data_get_bool(req->data, "force");
|
||||
bool forceStop = obs_data_get_bool(request.parameters(), "force");
|
||||
if (forceStop) {
|
||||
obs_output_force_stop(output);
|
||||
} else {
|
||||
obs_output_stop(output);
|
||||
}
|
||||
|
||||
return req->SendOKResponse();
|
||||
return request.success();
|
||||
});
|
||||
}
|
||||
|
@ -12,19 +12,19 @@
|
||||
* @category profiles
|
||||
* @since 4.0.0
|
||||
*/
|
||||
HandlerResponse WSRequestHandler::HandleSetCurrentProfile(WSRequestHandler* req) {
|
||||
if (!req->hasField("profile-name")) {
|
||||
return req->SendErrorResponse("missing request parameters");
|
||||
RpcResponse WSRequestHandler::SetCurrentProfile(const RpcRequest& request) {
|
||||
if (!request.hasField("profile-name")) {
|
||||
return request.failed("missing request parameters");
|
||||
}
|
||||
|
||||
QString profileName = obs_data_get_string(req->data, "profile-name");
|
||||
QString profileName = obs_data_get_string(request.parameters(), "profile-name");
|
||||
if (profileName.isEmpty()) {
|
||||
return req->SendErrorResponse("invalid request parameters");
|
||||
return request.failed("invalid request parameters");
|
||||
}
|
||||
|
||||
// TODO : check if profile exists
|
||||
obs_frontend_set_current_profile(profileName.toUtf8());
|
||||
return req->SendOKResponse();
|
||||
return request.success();
|
||||
}
|
||||
|
||||
/**
|
||||
@ -37,12 +37,12 @@ HandlerResponse WSRequestHandler::HandleSetCurrentProfile(WSRequestHandler* req)
|
||||
* @category profiles
|
||||
* @since 4.0.0
|
||||
*/
|
||||
HandlerResponse WSRequestHandler::HandleGetCurrentProfile(WSRequestHandler* req) {
|
||||
RpcResponse WSRequestHandler::GetCurrentProfile(const RpcRequest& request) {
|
||||
OBSDataAutoRelease response = obs_data_create();
|
||||
char* currentProfile = obs_frontend_get_current_profile();
|
||||
obs_data_set_string(response, "profile-name", currentProfile);
|
||||
bfree(currentProfile);
|
||||
return req->SendOKResponse(response);
|
||||
return request.success(response);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -55,7 +55,7 @@ HandlerResponse WSRequestHandler::HandleGetCurrentProfile(WSRequestHandler* req)
|
||||
* @category profiles
|
||||
* @since 4.0.0
|
||||
*/
|
||||
HandlerResponse WSRequestHandler::HandleListProfiles(WSRequestHandler* req) {
|
||||
RpcResponse WSRequestHandler::ListProfiles(const RpcRequest& request) {
|
||||
char** profiles = obs_frontend_get_profiles();
|
||||
OBSDataArrayAutoRelease list = Utils::StringListToArray(profiles, "profile-name");
|
||||
bfree(profiles);
|
||||
@ -63,5 +63,5 @@ HandlerResponse WSRequestHandler::HandleListProfiles(WSRequestHandler* req) {
|
||||
OBSDataAutoRelease response = obs_data_create();
|
||||
obs_data_set_array(response, "profiles", list);
|
||||
|
||||
return req->SendOKResponse(response);
|
||||
return request.success(response);
|
||||
}
|
||||
|
@ -1,16 +1,17 @@
|
||||
#include "WSRequestHandler.h"
|
||||
|
||||
#include <functional>
|
||||
#include <util/platform.h>
|
||||
#include "Utils.h"
|
||||
|
||||
HandlerResponse ifCanPause(WSRequestHandler* req, std::function<HandlerResponse()> callback)
|
||||
RpcResponse ifCanPause(const RpcRequest& request, std::function<RpcResponse()> callback)
|
||||
{
|
||||
if (!obs_frontend_recording_active()) {
|
||||
return req->SendErrorResponse("recording is not active");
|
||||
return request.failed("recording is not active");
|
||||
}
|
||||
|
||||
if (!Utils::RecordingPauseSupported()) {
|
||||
return req->SendErrorResponse("recording pauses are not available in this version of OBS Studio");
|
||||
return request.failed("recording pauses are not available in this version of OBS Studio");
|
||||
}
|
||||
|
||||
return callback();
|
||||
@ -24,9 +25,9 @@ HandlerResponse ifCanPause(WSRequestHandler* req, std::function<HandlerResponse(
|
||||
* @category recording
|
||||
* @since 0.3
|
||||
*/
|
||||
HandlerResponse WSRequestHandler::HandleStartStopRecording(WSRequestHandler* req) {
|
||||
RpcResponse WSRequestHandler::StartStopRecording(const RpcRequest& request) {
|
||||
(obs_frontend_recording_active() ? obs_frontend_recording_stop() : obs_frontend_recording_start());
|
||||
return req->SendOKResponse();
|
||||
return request.success();
|
||||
}
|
||||
|
||||
/**
|
||||
@ -38,13 +39,13 @@ HandlerResponse WSRequestHandler::HandleStartStopRecording(WSRequestHandler* req
|
||||
* @category recording
|
||||
* @since 4.1.0
|
||||
*/
|
||||
HandlerResponse WSRequestHandler::HandleStartRecording(WSRequestHandler* req) {
|
||||
RpcResponse WSRequestHandler::StartRecording(const RpcRequest& request) {
|
||||
if (obs_frontend_recording_active()) {
|
||||
return req->SendErrorResponse("recording already active");
|
||||
return request.failed("recording already active");
|
||||
}
|
||||
|
||||
obs_frontend_recording_start();
|
||||
return req->SendOKResponse();
|
||||
return request.success();
|
||||
}
|
||||
|
||||
/**
|
||||
@ -56,13 +57,13 @@ HandlerResponse WSRequestHandler::HandleStartRecording(WSRequestHandler* req) {
|
||||
* @category recording
|
||||
* @since 4.1.0
|
||||
*/
|
||||
HandlerResponse WSRequestHandler::HandleStopRecording(WSRequestHandler* req) {
|
||||
RpcResponse WSRequestHandler::StopRecording(const RpcRequest& request) {
|
||||
if (!obs_frontend_recording_active()) {
|
||||
return req->SendErrorResponse("recording not active");
|
||||
return request.failed("recording not active");
|
||||
}
|
||||
|
||||
obs_frontend_recording_stop();
|
||||
return req->SendOKResponse();
|
||||
return request.success();
|
||||
}
|
||||
|
||||
/**
|
||||
@ -74,14 +75,14 @@ HandlerResponse WSRequestHandler::HandleStartRecording(WSRequestHandler* req) {
|
||||
* @category recording
|
||||
* @since 4.7.0
|
||||
*/
|
||||
HandlerResponse WSRequestHandler::HandlePauseRecording(WSRequestHandler* req) {
|
||||
return ifCanPause(req, [req]() {
|
||||
RpcResponse WSRequestHandler::PauseRecording(const RpcRequest& request) {
|
||||
return ifCanPause(request, [request]() {
|
||||
if (Utils::RecordingPaused()) {
|
||||
return req->SendErrorResponse("recording already paused");
|
||||
return request.failed("recording already paused");
|
||||
}
|
||||
|
||||
Utils::PauseRecording(true);
|
||||
return req->SendOKResponse();
|
||||
return request.success();
|
||||
});
|
||||
}
|
||||
|
||||
@ -94,14 +95,14 @@ HandlerResponse WSRequestHandler::HandlePauseRecording(WSRequestHandler* req) {
|
||||
* @category recording
|
||||
* @since 4.7.0
|
||||
*/
|
||||
HandlerResponse WSRequestHandler::HandleResumeRecording(WSRequestHandler* req) {
|
||||
return ifCanPause(req, [req]() {
|
||||
RpcResponse WSRequestHandler::ResumeRecording(const RpcRequest& request) {
|
||||
return ifCanPause(request, [request]() {
|
||||
if (!Utils::RecordingPaused()) {
|
||||
return req->SendErrorResponse("recording is not paused");
|
||||
return request.failed("recording is not paused");
|
||||
}
|
||||
|
||||
Utils::PauseRecording(false);
|
||||
return req->SendOKResponse();
|
||||
return request.success();
|
||||
});
|
||||
}
|
||||
|
||||
@ -120,18 +121,18 @@ HandlerResponse WSRequestHandler::HandleResumeRecording(WSRequestHandler* req) {
|
||||
* @category recording
|
||||
* @since 4.1.0
|
||||
*/
|
||||
HandlerResponse WSRequestHandler::HandleSetRecordingFolder(WSRequestHandler* req) {
|
||||
if (!req->hasField("rec-folder")) {
|
||||
return req->SendErrorResponse("missing request parameters");
|
||||
RpcResponse WSRequestHandler::SetRecordingFolder(const RpcRequest& request) {
|
||||
if (!request.hasField("rec-folder")) {
|
||||
return request.failed("missing request parameters");
|
||||
}
|
||||
|
||||
const char* newRecFolder = obs_data_get_string(req->data, "rec-folder");
|
||||
const char* newRecFolder = obs_data_get_string(request.parameters(), "rec-folder");
|
||||
bool success = Utils::SetRecordingFolder(newRecFolder);
|
||||
if (!success) {
|
||||
return req->SendErrorResponse("invalid request parameters");
|
||||
return request.failed("invalid request parameters");
|
||||
}
|
||||
|
||||
return req->SendOKResponse();
|
||||
return request.success();
|
||||
}
|
||||
|
||||
/**
|
||||
@ -144,11 +145,11 @@ HandlerResponse WSRequestHandler::HandleSetRecordingFolder(WSRequestHandler* req
|
||||
* @category recording
|
||||
* @since 4.1.0
|
||||
*/
|
||||
HandlerResponse WSRequestHandler::HandleGetRecordingFolder(WSRequestHandler* req) {
|
||||
RpcResponse WSRequestHandler::GetRecordingFolder(const RpcRequest& request) {
|
||||
const char* recFolder = Utils::GetRecordingFolder();
|
||||
|
||||
OBSDataAutoRelease response = obs_data_create();
|
||||
obs_data_set_string(response, "rec-folder", recFolder);
|
||||
|
||||
return req->SendOKResponse(response);
|
||||
return request.success(response);
|
||||
}
|
||||
|
@ -10,13 +10,13 @@
|
||||
* @category replay buffer
|
||||
* @since 4.2.0
|
||||
*/
|
||||
HandlerResponse WSRequestHandler::HandleStartStopReplayBuffer(WSRequestHandler* req) {
|
||||
RpcResponse WSRequestHandler::StartStopReplayBuffer(const RpcRequest& request) {
|
||||
if (obs_frontend_replay_buffer_active()) {
|
||||
obs_frontend_replay_buffer_stop();
|
||||
} else {
|
||||
Utils::StartReplayBuffer();
|
||||
}
|
||||
return req->SendOKResponse();
|
||||
return request.success();
|
||||
}
|
||||
|
||||
/**
|
||||
@ -31,17 +31,17 @@ HandlerResponse WSRequestHandler::HandleStartStopReplayBuffer(WSRequestHandler*
|
||||
* @category replay buffer
|
||||
* @since 4.2.0
|
||||
*/
|
||||
HandlerResponse WSRequestHandler::HandleStartReplayBuffer(WSRequestHandler* req) {
|
||||
RpcResponse WSRequestHandler::StartReplayBuffer(const RpcRequest& request) {
|
||||
if (!Utils::ReplayBufferEnabled()) {
|
||||
return req->SendErrorResponse("replay buffer disabled in settings");
|
||||
return request.failed("replay buffer disabled in settings");
|
||||
}
|
||||
|
||||
if (obs_frontend_replay_buffer_active() == true) {
|
||||
return req->SendErrorResponse("replay buffer already active");
|
||||
return request.failed("replay buffer already active");
|
||||
}
|
||||
|
||||
Utils::StartReplayBuffer();
|
||||
return req->SendOKResponse();
|
||||
return request.success();
|
||||
}
|
||||
|
||||
/**
|
||||
@ -53,12 +53,12 @@ HandlerResponse WSRequestHandler::HandleStartReplayBuffer(WSRequestHandler* req)
|
||||
* @category replay buffer
|
||||
* @since 4.2.0
|
||||
*/
|
||||
HandlerResponse WSRequestHandler::HandleStopReplayBuffer(WSRequestHandler* req) {
|
||||
RpcResponse WSRequestHandler::StopReplayBuffer(const RpcRequest& request) {
|
||||
if (obs_frontend_replay_buffer_active() == true) {
|
||||
obs_frontend_replay_buffer_stop();
|
||||
return req->SendOKResponse();
|
||||
return request.success();
|
||||
} else {
|
||||
return req->SendErrorResponse("replay buffer not active");
|
||||
return request.failed("replay buffer not active");
|
||||
}
|
||||
}
|
||||
|
||||
@ -72,9 +72,9 @@ HandlerResponse WSRequestHandler::HandleStopReplayBuffer(WSRequestHandler* req)
|
||||
* @category replay buffer
|
||||
* @since 4.2.0
|
||||
*/
|
||||
HandlerResponse WSRequestHandler::HandleSaveReplayBuffer(WSRequestHandler* req) {
|
||||
RpcResponse WSRequestHandler::SaveReplayBuffer(const RpcRequest& request) {
|
||||
if (!obs_frontend_replay_buffer_active()) {
|
||||
return req->SendErrorResponse("replay buffer not active");
|
||||
return request.failed("replay buffer not active");
|
||||
}
|
||||
|
||||
OBSOutputAutoRelease replayOutput = obs_frontend_get_replay_buffer_output();
|
||||
@ -84,5 +84,5 @@ HandlerResponse WSRequestHandler::HandleSaveReplayBuffer(WSRequestHandler* req)
|
||||
proc_handler_call(ph, "save", &cd);
|
||||
calldata_free(&cd);
|
||||
|
||||
return req->SendOKResponse();
|
||||
return request.success();
|
||||
}
|
||||
|
@ -12,19 +12,19 @@
|
||||
* @category scene collections
|
||||
* @since 4.0.0
|
||||
*/
|
||||
HandlerResponse WSRequestHandler::HandleSetCurrentSceneCollection(WSRequestHandler* req) {
|
||||
if (!req->hasField("sc-name")) {
|
||||
return req->SendErrorResponse("missing request parameters");
|
||||
RpcResponse WSRequestHandler::SetCurrentSceneCollection(const RpcRequest& request) {
|
||||
if (!request.hasField("sc-name")) {
|
||||
return request.failed("missing request parameters");
|
||||
}
|
||||
|
||||
QString sceneCollection = obs_data_get_string(req->data, "sc-name");
|
||||
QString sceneCollection = obs_data_get_string(request.parameters(), "sc-name");
|
||||
if (sceneCollection.isEmpty()) {
|
||||
return req->SendErrorResponse("invalid request parameters");
|
||||
return request.failed("invalid request parameters");
|
||||
}
|
||||
|
||||
// TODO : Check if specified profile exists and if changing is allowed
|
||||
obs_frontend_set_current_scene_collection(sceneCollection.toUtf8());
|
||||
return req->SendOKResponse();
|
||||
return request.success();
|
||||
}
|
||||
|
||||
/**
|
||||
@ -37,14 +37,14 @@ HandlerResponse WSRequestHandler::HandleSetCurrentSceneCollection(WSRequestHandl
|
||||
* @category scene collections
|
||||
* @since 4.0.0
|
||||
*/
|
||||
HandlerResponse WSRequestHandler::HandleGetCurrentSceneCollection(WSRequestHandler* req) {
|
||||
RpcResponse WSRequestHandler::GetCurrentSceneCollection(const RpcRequest& request) {
|
||||
OBSDataAutoRelease response = obs_data_create();
|
||||
|
||||
char* sceneCollection = obs_frontend_get_current_scene_collection();
|
||||
obs_data_set_string(response, "sc-name", sceneCollection);
|
||||
bfree(sceneCollection);
|
||||
|
||||
return req->SendOKResponse(response);
|
||||
return request.success(response);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -57,7 +57,7 @@ HandlerResponse WSRequestHandler::HandleGetCurrentSceneCollection(WSRequestHandl
|
||||
* @category scene collections
|
||||
* @since 4.0.0
|
||||
*/
|
||||
HandlerResponse WSRequestHandler::HandleListSceneCollections(WSRequestHandler* req) {
|
||||
RpcResponse WSRequestHandler::ListSceneCollections(const RpcRequest& request) {
|
||||
char** sceneCollections = obs_frontend_get_scene_collections();
|
||||
OBSDataArrayAutoRelease list =
|
||||
Utils::StringListToArray(sceneCollections, "sc-name");
|
||||
@ -66,5 +66,5 @@ HandlerResponse WSRequestHandler::HandleListSceneCollections(WSRequestHandler* r
|
||||
OBSDataAutoRelease response = obs_data_create();
|
||||
obs_data_set_array(response, "scene-collections", list);
|
||||
|
||||
return req->SendOKResponse(response);
|
||||
return request.success(response);
|
||||
}
|
||||
|
@ -38,31 +38,31 @@
|
||||
* @category scene items
|
||||
* @since 4.3.0
|
||||
*/
|
||||
HandlerResponse WSRequestHandler::HandleGetSceneItemProperties(WSRequestHandler* req) {
|
||||
if (!req->hasField("item")) {
|
||||
return req->SendErrorResponse("missing request parameters");
|
||||
RpcResponse WSRequestHandler::GetSceneItemProperties(const RpcRequest& request) {
|
||||
if (!request.hasField("item")) {
|
||||
return request.failed("missing request parameters");
|
||||
}
|
||||
|
||||
QString itemName = obs_data_get_string(req->data, "item");
|
||||
QString itemName = obs_data_get_string(request.parameters(), "item");
|
||||
if (itemName.isEmpty()) {
|
||||
return req->SendErrorResponse("invalid request parameters");
|
||||
return request.failed("invalid request parameters");
|
||||
}
|
||||
|
||||
QString sceneName = obs_data_get_string(req->data, "scene-name");
|
||||
QString sceneName = obs_data_get_string(request.parameters(), "scene-name");
|
||||
OBSScene scene = Utils::GetSceneFromNameOrCurrent(sceneName);
|
||||
if (!scene) {
|
||||
return req->SendErrorResponse("requested scene doesn't exist");
|
||||
return request.failed("requested scene doesn't exist");
|
||||
}
|
||||
|
||||
OBSSceneItemAutoRelease sceneItem = Utils::GetSceneItemFromName(scene, itemName);
|
||||
if (!sceneItem) {
|
||||
return req->SendErrorResponse("specified scene item doesn't exist");
|
||||
return request.failed("specified scene item doesn't exist");
|
||||
}
|
||||
|
||||
OBSDataAutoRelease data = Utils::GetSceneItemPropertiesData(sceneItem);
|
||||
obs_data_set_string(data, "name", itemName.toUtf8());
|
||||
|
||||
return req->SendOKResponse(data);
|
||||
return request.success(data);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -93,38 +93,38 @@ HandlerResponse WSRequestHandler::HandleGetSceneItemProperties(WSRequestHandler*
|
||||
* @category scene items
|
||||
* @since 4.3.0
|
||||
*/
|
||||
HandlerResponse WSRequestHandler::HandleSetSceneItemProperties(WSRequestHandler* req) {
|
||||
if (!req->hasField("item")) {
|
||||
return req->SendErrorResponse("missing request parameters");
|
||||
RpcResponse WSRequestHandler::SetSceneItemProperties(const RpcRequest& request) {
|
||||
if (!request.hasField("item")) {
|
||||
return request.failed("missing request parameters");
|
||||
}
|
||||
|
||||
QString itemName = obs_data_get_string(req->data, "item");
|
||||
QString itemName = obs_data_get_string(request.parameters(), "item");
|
||||
if (itemName.isEmpty()) {
|
||||
return req->SendErrorResponse("invalid request parameters");
|
||||
return request.failed("invalid request parameters");
|
||||
}
|
||||
|
||||
QString sceneName = obs_data_get_string(req->data, "scene-name");
|
||||
QString sceneName = obs_data_get_string(request.parameters(), "scene-name");
|
||||
OBSScene scene = Utils::GetSceneFromNameOrCurrent(sceneName);
|
||||
if (!scene) {
|
||||
return req->SendErrorResponse("requested scene doesn't exist");
|
||||
return request.failed("requested scene doesn't exist");
|
||||
}
|
||||
|
||||
OBSSceneItemAutoRelease sceneItem =
|
||||
Utils::GetSceneItemFromName(scene, itemName);
|
||||
if (!sceneItem) {
|
||||
return req->SendErrorResponse("specified scene item doesn't exist");
|
||||
return request.failed("specified scene item doesn't exist");
|
||||
}
|
||||
|
||||
bool badRequest = false;
|
||||
OBSDataAutoRelease errorMessage = obs_data_create();
|
||||
OBSDataAutoRelease errorData = obs_data_create();
|
||||
|
||||
obs_sceneitem_defer_update_begin(sceneItem);
|
||||
|
||||
if (req->hasField("position")) {
|
||||
if (request.hasField("position")) {
|
||||
vec2 oldPosition;
|
||||
OBSDataAutoRelease positionError = obs_data_create();
|
||||
obs_sceneitem_get_pos(sceneItem, &oldPosition);
|
||||
OBSDataAutoRelease reqPosition = obs_data_get_obj(req->data, "position");
|
||||
OBSDataAutoRelease reqPosition = obs_data_get_obj(request.parameters(), "position");
|
||||
vec2 newPosition = oldPosition;
|
||||
if (obs_data_has_user_value(reqPosition, "x")) {
|
||||
newPosition.x = obs_data_get_int(reqPosition, "x");
|
||||
@ -140,20 +140,20 @@ HandlerResponse WSRequestHandler::HandleSetSceneItemProperties(WSRequestHandler*
|
||||
else {
|
||||
badRequest = true;
|
||||
obs_data_set_string(positionError, "alignment", "invalid");
|
||||
obs_data_set_obj(errorMessage, "position", positionError);
|
||||
obs_data_set_obj(errorData, "position", positionError);
|
||||
}
|
||||
}
|
||||
obs_sceneitem_set_pos(sceneItem, &newPosition);
|
||||
}
|
||||
|
||||
if (req->hasField("rotation")) {
|
||||
obs_sceneitem_set_rot(sceneItem, (float)obs_data_get_double(req->data, "rotation"));
|
||||
if (request.hasField("rotation")) {
|
||||
obs_sceneitem_set_rot(sceneItem, (float)obs_data_get_double(request.parameters(), "rotation"));
|
||||
}
|
||||
|
||||
if (req->hasField("scale")) {
|
||||
if (request.hasField("scale")) {
|
||||
vec2 oldScale;
|
||||
obs_sceneitem_get_scale(sceneItem, &oldScale);
|
||||
OBSDataAutoRelease reqScale = obs_data_get_obj(req->data, "scale");
|
||||
OBSDataAutoRelease reqScale = obs_data_get_obj(request.parameters(), "scale");
|
||||
vec2 newScale = oldScale;
|
||||
if (obs_data_has_user_value(reqScale, "x")) {
|
||||
newScale.x = obs_data_get_double(reqScale, "x");
|
||||
@ -164,10 +164,10 @@ HandlerResponse WSRequestHandler::HandleSetSceneItemProperties(WSRequestHandler*
|
||||
obs_sceneitem_set_scale(sceneItem, &newScale);
|
||||
}
|
||||
|
||||
if (req->hasField("crop")) {
|
||||
if (request.hasField("crop")) {
|
||||
obs_sceneitem_crop oldCrop;
|
||||
obs_sceneitem_get_crop(sceneItem, &oldCrop);
|
||||
OBSDataAutoRelease reqCrop = obs_data_get_obj(req->data, "crop");
|
||||
OBSDataAutoRelease reqCrop = obs_data_get_obj(request.parameters(), "crop");
|
||||
obs_sceneitem_crop newCrop = oldCrop;
|
||||
if (obs_data_has_user_value(reqCrop, "top")) {
|
||||
newCrop.top = obs_data_get_int(reqCrop, "top");
|
||||
@ -184,18 +184,18 @@ HandlerResponse WSRequestHandler::HandleSetSceneItemProperties(WSRequestHandler*
|
||||
obs_sceneitem_set_crop(sceneItem, &newCrop);
|
||||
}
|
||||
|
||||
if (req->hasField("visible")) {
|
||||
obs_sceneitem_set_visible(sceneItem, obs_data_get_bool(req->data, "visible"));
|
||||
if (request.hasField("visible")) {
|
||||
obs_sceneitem_set_visible(sceneItem, obs_data_get_bool(request.parameters(), "visible"));
|
||||
}
|
||||
|
||||
if (req->hasField("locked")) {
|
||||
obs_sceneitem_set_locked(sceneItem, obs_data_get_bool(req->data, "locked"));
|
||||
if (request.hasField("locked")) {
|
||||
obs_sceneitem_set_locked(sceneItem, obs_data_get_bool(request.parameters(), "locked"));
|
||||
}
|
||||
|
||||
if (req->hasField("bounds")) {
|
||||
if (request.hasField("bounds")) {
|
||||
bool badBounds = false;
|
||||
OBSDataAutoRelease boundsError = obs_data_create();
|
||||
OBSDataAutoRelease reqBounds = obs_data_get_obj(req->data, "bounds");
|
||||
OBSDataAutoRelease reqBounds = obs_data_get_obj(request.parameters(), "bounds");
|
||||
if (obs_data_has_user_value(reqBounds, "type")) {
|
||||
QString newBoundsType = obs_data_get_string(reqBounds, "type");
|
||||
if (newBoundsType == "OBS_BOUNDS_NONE") {
|
||||
@ -245,17 +245,17 @@ HandlerResponse WSRequestHandler::HandleSetSceneItemProperties(WSRequestHandler*
|
||||
}
|
||||
}
|
||||
if (badBounds) {
|
||||
obs_data_set_obj(errorMessage, "bounds", boundsError);
|
||||
obs_data_set_obj(errorData, "bounds", boundsError);
|
||||
}
|
||||
}
|
||||
|
||||
obs_sceneitem_defer_update_end(sceneItem);
|
||||
|
||||
if (badRequest) {
|
||||
return req->SendErrorResponse(errorMessage);
|
||||
return request.failed("error", errorData);
|
||||
}
|
||||
|
||||
return req->SendOKResponse();
|
||||
return request.success();
|
||||
}
|
||||
|
||||
/**
|
||||
@ -269,27 +269,27 @@ HandlerResponse WSRequestHandler::HandleSetSceneItemProperties(WSRequestHandler*
|
||||
* @category scene items
|
||||
* @since 4.2.0
|
||||
*/
|
||||
HandlerResponse WSRequestHandler::HandleResetSceneItem(WSRequestHandler* req) {
|
||||
RpcResponse WSRequestHandler::ResetSceneItem(const RpcRequest& request) {
|
||||
// TODO: remove this request, or refactor it to ResetSource
|
||||
|
||||
if (!req->hasField("item")) {
|
||||
return req->SendErrorResponse("missing request parameters");
|
||||
if (!request.hasField("item")) {
|
||||
return request.failed("missing request parameters");
|
||||
}
|
||||
|
||||
const char* itemName = obs_data_get_string(req->data, "item");
|
||||
const char* itemName = obs_data_get_string(request.parameters(), "item");
|
||||
if (!itemName) {
|
||||
return req->SendErrorResponse("invalid request parameters");
|
||||
return request.failed("invalid request parameters");
|
||||
}
|
||||
|
||||
const char* sceneName = obs_data_get_string(req->data, "scene-name");
|
||||
const char* sceneName = obs_data_get_string(request.parameters(), "scene-name");
|
||||
OBSScene scene = Utils::GetSceneFromNameOrCurrent(sceneName);
|
||||
if (!scene) {
|
||||
return req->SendErrorResponse("requested scene doesn't exist");
|
||||
return request.failed("requested scene doesn't exist");
|
||||
}
|
||||
|
||||
OBSSceneItemAutoRelease sceneItem = Utils::GetSceneItemFromName(scene, itemName);
|
||||
if (!sceneItem) {
|
||||
return req->SendErrorResponse("specified scene item doesn't exist");
|
||||
return request.failed("specified scene item doesn't exist");
|
||||
}
|
||||
|
||||
OBSSource sceneItemSource = obs_sceneitem_get_source(sceneItem);
|
||||
@ -297,7 +297,7 @@ HandlerResponse WSRequestHandler::HandleResetSceneItem(WSRequestHandler* req) {
|
||||
OBSDataAutoRelease settings = obs_source_get_settings(sceneItemSource);
|
||||
obs_source_update(sceneItemSource, settings);
|
||||
|
||||
return req->SendOKResponse();
|
||||
return request.success();
|
||||
}
|
||||
|
||||
/**
|
||||
@ -313,34 +313,34 @@ HandlerResponse WSRequestHandler::HandleResetSceneItem(WSRequestHandler* req) {
|
||||
* @since 0.3
|
||||
* @deprecated Since 4.3.0. Prefer the use of SetSceneItemProperties.
|
||||
*/
|
||||
HandlerResponse WSRequestHandler::HandleSetSceneItemRender(WSRequestHandler* req) {
|
||||
if (!req->hasField("source") ||
|
||||
!req->hasField("render"))
|
||||
RpcResponse WSRequestHandler::SetSceneItemRender(const RpcRequest& request) {
|
||||
if (!request.hasField("source") ||
|
||||
!request.hasField("render"))
|
||||
{
|
||||
return req->SendErrorResponse("missing request parameters");
|
||||
return request.failed("missing request parameters");
|
||||
}
|
||||
|
||||
const char* itemName = obs_data_get_string(req->data, "source");
|
||||
bool isVisible = obs_data_get_bool(req->data, "render");
|
||||
const char* itemName = obs_data_get_string(request.parameters(), "source");
|
||||
bool isVisible = obs_data_get_bool(request.parameters(), "render");
|
||||
|
||||
if (!itemName) {
|
||||
return req->SendErrorResponse("invalid request parameters");
|
||||
return request.failed("invalid request parameters");
|
||||
}
|
||||
|
||||
const char* sceneName = obs_data_get_string(req->data, "scene-name");
|
||||
const char* sceneName = obs_data_get_string(request.parameters(), "scene-name");
|
||||
OBSScene scene = Utils::GetSceneFromNameOrCurrent(sceneName);
|
||||
if (!scene) {
|
||||
return req->SendErrorResponse("requested scene doesn't exist");
|
||||
return request.failed("requested scene doesn't exist");
|
||||
}
|
||||
|
||||
OBSSceneItemAutoRelease sceneItem =
|
||||
Utils::GetSceneItemFromName(scene, itemName);
|
||||
if (!sceneItem) {
|
||||
return req->SendErrorResponse("specified scene item doesn't exist");
|
||||
return request.failed("specified scene item doesn't exist");
|
||||
}
|
||||
|
||||
obs_sceneitem_set_visible(sceneItem, isVisible);
|
||||
return req->SendOKResponse();
|
||||
return request.success();
|
||||
}
|
||||
|
||||
/**
|
||||
@ -358,34 +358,34 @@ HandlerResponse WSRequestHandler::HandleSetSceneItemRender(WSRequestHandler* req
|
||||
* @since 4.0.0
|
||||
* @deprecated Since 4.3.0. Prefer the use of SetSceneItemProperties.
|
||||
*/
|
||||
HandlerResponse WSRequestHandler::HandleSetSceneItemPosition(WSRequestHandler* req) {
|
||||
if (!req->hasField("item") ||
|
||||
!req->hasField("x") || !req->hasField("y")) {
|
||||
return req->SendErrorResponse("missing request parameters");
|
||||
RpcResponse WSRequestHandler::SetSceneItemPosition(const RpcRequest& request) {
|
||||
if (!request.hasField("item") ||
|
||||
!request.hasField("x") || !request.hasField("y")) {
|
||||
return request.failed("missing request parameters");
|
||||
}
|
||||
|
||||
QString itemName = obs_data_get_string(req->data, "item");
|
||||
QString itemName = obs_data_get_string(request.parameters(), "item");
|
||||
if (itemName.isEmpty()) {
|
||||
return req->SendErrorResponse("invalid request parameters");
|
||||
return request.failed("invalid request parameters");
|
||||
}
|
||||
|
||||
QString sceneName = obs_data_get_string(req->data, "scene-name");
|
||||
QString sceneName = obs_data_get_string(request.parameters(), "scene-name");
|
||||
OBSScene scene = Utils::GetSceneFromNameOrCurrent(sceneName);
|
||||
if (!scene) {
|
||||
return req->SendErrorResponse("requested scene could not be found");
|
||||
return request.failed("requested scene could not be found");
|
||||
}
|
||||
|
||||
OBSSceneItem sceneItem = Utils::GetSceneItemFromName(scene, itemName);
|
||||
if (!sceneItem) {
|
||||
return req->SendErrorResponse("specified scene item doesn't exist");
|
||||
return request.failed("specified scene item doesn't exist");
|
||||
}
|
||||
|
||||
vec2 item_position = { 0 };
|
||||
item_position.x = obs_data_get_double(req->data, "x");
|
||||
item_position.y = obs_data_get_double(req->data, "y");
|
||||
item_position.x = obs_data_get_double(request.parameters(), "x");
|
||||
item_position.y = obs_data_get_double(request.parameters(), "y");
|
||||
obs_sceneitem_set_pos(sceneItem, &item_position);
|
||||
|
||||
return req->SendOKResponse();
|
||||
return request.success();
|
||||
}
|
||||
|
||||
/**
|
||||
@ -403,34 +403,34 @@ HandlerResponse WSRequestHandler::HandleSetSceneItemPosition(WSRequestHandler* r
|
||||
* @since 4.0.0
|
||||
* @deprecated Since 4.3.0. Prefer the use of SetSceneItemProperties.
|
||||
*/
|
||||
HandlerResponse WSRequestHandler::HandleSetSceneItemTransform(WSRequestHandler* req) {
|
||||
if (!req->hasField("item") ||
|
||||
!req->hasField("x-scale") ||
|
||||
!req->hasField("y-scale") ||
|
||||
!req->hasField("rotation"))
|
||||
RpcResponse WSRequestHandler::SetSceneItemTransform(const RpcRequest& request) {
|
||||
if (!request.hasField("item") ||
|
||||
!request.hasField("x-scale") ||
|
||||
!request.hasField("y-scale") ||
|
||||
!request.hasField("rotation"))
|
||||
{
|
||||
return req->SendErrorResponse("missing request parameters");
|
||||
return request.failed("missing request parameters");
|
||||
}
|
||||
|
||||
QString itemName = obs_data_get_string(req->data, "item");
|
||||
QString itemName = obs_data_get_string(request.parameters(), "item");
|
||||
if (itemName.isEmpty()) {
|
||||
return req->SendErrorResponse("invalid request parameters");
|
||||
return request.failed("invalid request parameters");
|
||||
}
|
||||
|
||||
QString sceneName = obs_data_get_string(req->data, "scene-name");
|
||||
QString sceneName = obs_data_get_string(request.parameters(), "scene-name");
|
||||
OBSScene scene = Utils::GetSceneFromNameOrCurrent(sceneName);
|
||||
if (!scene) {
|
||||
return req->SendErrorResponse("requested scene doesn't exist");
|
||||
return request.failed("requested scene doesn't exist");
|
||||
}
|
||||
|
||||
vec2 scale;
|
||||
scale.x = obs_data_get_double(req->data, "x-scale");
|
||||
scale.y = obs_data_get_double(req->data, "y-scale");
|
||||
float rotation = obs_data_get_double(req->data, "rotation");
|
||||
scale.x = obs_data_get_double(request.parameters(), "x-scale");
|
||||
scale.y = obs_data_get_double(request.parameters(), "y-scale");
|
||||
float rotation = obs_data_get_double(request.parameters(), "rotation");
|
||||
|
||||
OBSSceneItemAutoRelease sceneItem = Utils::GetSceneItemFromName(scene, itemName);
|
||||
if (!sceneItem) {
|
||||
return req->SendErrorResponse("specified scene item doesn't exist");
|
||||
return request.failed("specified scene item doesn't exist");
|
||||
}
|
||||
|
||||
obs_sceneitem_defer_update_begin(sceneItem);
|
||||
@ -440,7 +440,7 @@ HandlerResponse WSRequestHandler::HandleSetSceneItemTransform(WSRequestHandler*
|
||||
|
||||
obs_sceneitem_defer_update_end(sceneItem);
|
||||
|
||||
return req->SendOKResponse();
|
||||
return request.success();
|
||||
}
|
||||
|
||||
/**
|
||||
@ -459,36 +459,36 @@ HandlerResponse WSRequestHandler::HandleSetSceneItemTransform(WSRequestHandler*
|
||||
* @since 4.1.0
|
||||
* @deprecated Since 4.3.0. Prefer the use of SetSceneItemProperties.
|
||||
*/
|
||||
HandlerResponse WSRequestHandler::HandleSetSceneItemCrop(WSRequestHandler* req) {
|
||||
if (!req->hasField("item")) {
|
||||
return req->SendErrorResponse("missing request parameters");
|
||||
RpcResponse WSRequestHandler::SetSceneItemCrop(const RpcRequest& request) {
|
||||
if (!request.hasField("item")) {
|
||||
return request.failed("missing request parameters");
|
||||
}
|
||||
|
||||
QString itemName = obs_data_get_string(req->data, "item");
|
||||
QString itemName = obs_data_get_string(request.parameters(), "item");
|
||||
if (itemName.isEmpty()) {
|
||||
return req->SendErrorResponse("invalid request parameters");
|
||||
return request.failed("invalid request parameters");
|
||||
}
|
||||
|
||||
QString sceneName = obs_data_get_string(req->data, "scene-name");
|
||||
QString sceneName = obs_data_get_string(request.parameters(), "scene-name");
|
||||
OBSScene scene = Utils::GetSceneFromNameOrCurrent(sceneName);
|
||||
if (!scene) {
|
||||
return req->SendErrorResponse("requested scene doesn't exist");
|
||||
return request.failed("requested scene doesn't exist");
|
||||
}
|
||||
|
||||
OBSSceneItemAutoRelease sceneItem = Utils::GetSceneItemFromName(scene, itemName);
|
||||
if (!sceneItem) {
|
||||
return req->SendErrorResponse("specified scene item doesn't exist");
|
||||
return request.failed("specified scene item doesn't exist");
|
||||
}
|
||||
|
||||
struct obs_sceneitem_crop crop = { 0 };
|
||||
crop.top = obs_data_get_int(req->data, "top");
|
||||
crop.bottom = obs_data_get_int(req->data, "bottom");
|
||||
crop.left = obs_data_get_int(req->data, "left");
|
||||
crop.right = obs_data_get_int(req->data, "right");
|
||||
crop.top = obs_data_get_int(request.parameters(), "top");
|
||||
crop.bottom = obs_data_get_int(request.parameters(), "bottom");
|
||||
crop.left = obs_data_get_int(request.parameters(), "left");
|
||||
crop.right = obs_data_get_int(request.parameters(), "right");
|
||||
|
||||
obs_sceneitem_set_crop(sceneItem, &crop);
|
||||
|
||||
return req->SendOKResponse();
|
||||
return request.success();
|
||||
}
|
||||
|
||||
/**
|
||||
@ -504,38 +504,26 @@ HandlerResponse WSRequestHandler::HandleSetSceneItemCrop(WSRequestHandler* req)
|
||||
* @category scene items
|
||||
* @since 4.5.0
|
||||
*/
|
||||
HandlerResponse WSRequestHandler::HandleDeleteSceneItem(WSRequestHandler* req) {
|
||||
if (!req->hasField("item")) {
|
||||
return req->SendErrorResponse("missing request parameters");
|
||||
RpcResponse WSRequestHandler::DeleteSceneItem(const RpcRequest& request) {
|
||||
if (!request.hasField("item")) {
|
||||
return request.failed("missing request parameters");
|
||||
}
|
||||
|
||||
const char* sceneName = obs_data_get_string(req->data, "scene");
|
||||
const char* sceneName = obs_data_get_string(request.parameters(), "scene");
|
||||
OBSScene scene = Utils::GetSceneFromNameOrCurrent(sceneName);
|
||||
if (!scene) {
|
||||
return req->SendErrorResponse("requested scene doesn't exist");
|
||||
return request.failed("requested scene doesn't exist");
|
||||
}
|
||||
|
||||
OBSDataAutoRelease item = obs_data_get_obj(req->data, "item");
|
||||
OBSDataAutoRelease item = obs_data_get_obj(request.parameters(), "item");
|
||||
OBSSceneItemAutoRelease sceneItem = Utils::GetSceneItemFromItem(scene, item);
|
||||
if (!sceneItem) {
|
||||
return req->SendErrorResponse("item with id/name combination not found in specified scene");
|
||||
return request.failed("item with id/name combination not found in specified scene");
|
||||
}
|
||||
|
||||
obs_sceneitem_remove(sceneItem);
|
||||
|
||||
return req->SendOKResponse();
|
||||
}
|
||||
|
||||
struct DuplicateSceneItemData {
|
||||
obs_sceneitem_t *referenceItem;
|
||||
obs_source_t *fromSource;
|
||||
obs_sceneitem_t *newItem;
|
||||
};
|
||||
|
||||
static void DuplicateSceneItem(void *_data, obs_scene_t *scene) {
|
||||
DuplicateSceneItemData *data = (DuplicateSceneItemData *)_data;
|
||||
data->newItem = obs_scene_add(scene, data->fromSource);
|
||||
obs_sceneitem_set_visible(data->newItem, obs_sceneitem_visible(data->referenceItem));
|
||||
return request.success();
|
||||
}
|
||||
|
||||
/**
|
||||
@ -557,27 +545,33 @@ static void DuplicateSceneItem(void *_data, obs_scene_t *scene) {
|
||||
* @category scene items
|
||||
* @since 4.5.0
|
||||
*/
|
||||
HandlerResponse WSRequestHandler::HandleDuplicateSceneItem(WSRequestHandler* req) {
|
||||
if (!req->hasField("item")) {
|
||||
return req->SendErrorResponse("missing request parameters");
|
||||
RpcResponse WSRequestHandler::DuplicateSceneItem(const RpcRequest& request) {
|
||||
struct DuplicateSceneItemData {
|
||||
obs_sceneitem_t *referenceItem;
|
||||
obs_source_t *fromSource;
|
||||
obs_sceneitem_t *newItem;
|
||||
};
|
||||
|
||||
if (!request.hasField("item")) {
|
||||
return request.failed("missing request parameters");
|
||||
}
|
||||
|
||||
const char* fromSceneName = obs_data_get_string(req->data, "fromScene");
|
||||
const char* fromSceneName = obs_data_get_string(request.parameters(), "fromScene");
|
||||
OBSScene fromScene = Utils::GetSceneFromNameOrCurrent(fromSceneName);
|
||||
if (!fromScene) {
|
||||
return req->SendErrorResponse("requested fromScene doesn't exist");
|
||||
return request.failed("requested fromScene doesn't exist");
|
||||
}
|
||||
|
||||
const char* toSceneName = obs_data_get_string(req->data, "toScene");
|
||||
const char* toSceneName = obs_data_get_string(request.parameters(), "toScene");
|
||||
OBSScene toScene = Utils::GetSceneFromNameOrCurrent(toSceneName);
|
||||
if (!toScene) {
|
||||
return req->SendErrorResponse("requested toScene doesn't exist");
|
||||
return request.failed("requested toScene doesn't exist");
|
||||
}
|
||||
|
||||
OBSDataAutoRelease item = obs_data_get_obj(req->data, "item");
|
||||
OBSDataAutoRelease item = obs_data_get_obj(request.parameters(), "item");
|
||||
OBSSceneItemAutoRelease referenceItem = Utils::GetSceneItemFromItem(fromScene, item);
|
||||
if (!referenceItem) {
|
||||
return req->SendErrorResponse("item with id/name combination not found in specified scene");
|
||||
return request.failed("item with id/name combination not found in specified scene");
|
||||
}
|
||||
|
||||
DuplicateSceneItemData data;
|
||||
@ -585,12 +579,16 @@ HandlerResponse WSRequestHandler::HandleDuplicateSceneItem(WSRequestHandler* req
|
||||
data.referenceItem = referenceItem;
|
||||
|
||||
obs_enter_graphics();
|
||||
obs_scene_atomic_update(toScene, DuplicateSceneItem, &data);
|
||||
obs_scene_atomic_update(toScene, [](void *_data, obs_scene_t *scene) {
|
||||
auto data = reinterpret_cast<DuplicateSceneItemData*>(_data);
|
||||
data->newItem = obs_scene_add(scene, data->fromSource);
|
||||
obs_sceneitem_set_visible(data->newItem, obs_sceneitem_visible(data->referenceItem));
|
||||
}, &data);
|
||||
obs_leave_graphics();
|
||||
|
||||
obs_sceneitem_t *newItem = data.newItem;
|
||||
if (!newItem) {
|
||||
return req->SendErrorResponse("Error duplicating scene item");
|
||||
return request.failed("Error duplicating scene item");
|
||||
}
|
||||
|
||||
OBSDataAutoRelease itemData = obs_data_create();
|
||||
@ -601,5 +599,5 @@ HandlerResponse WSRequestHandler::HandleDuplicateSceneItem(WSRequestHandler* req
|
||||
obs_data_set_obj(responseData, "item", itemData);
|
||||
obs_data_set_string(responseData, "scene", obs_source_get_name(obs_scene_get_source(toScene)));
|
||||
|
||||
return req->SendOKResponse(responseData);
|
||||
return request.success(responseData);
|
||||
}
|
||||
|
@ -18,19 +18,19 @@
|
||||
* @category scenes
|
||||
* @since 0.3
|
||||
*/
|
||||
HandlerResponse WSRequestHandler::HandleSetCurrentScene(WSRequestHandler* req) {
|
||||
if (!req->hasField("scene-name")) {
|
||||
return req->SendErrorResponse("missing request parameters");
|
||||
RpcResponse WSRequestHandler::SetCurrentScene(const RpcRequest& request) {
|
||||
if (!request.hasField("scene-name")) {
|
||||
return request.failed("missing request parameters");
|
||||
}
|
||||
|
||||
const char* sceneName = obs_data_get_string(req->data, "scene-name");
|
||||
const char* sceneName = obs_data_get_string(request.parameters(), "scene-name");
|
||||
OBSSourceAutoRelease source = obs_get_source_by_name(sceneName);
|
||||
|
||||
if (source) {
|
||||
obs_frontend_set_current_scene(source);
|
||||
return req->SendOKResponse();
|
||||
return request.success();
|
||||
} else {
|
||||
return req->SendErrorResponse("requested scene does not exist");
|
||||
return request.failed("requested scene does not exist");
|
||||
}
|
||||
}
|
||||
|
||||
@ -45,7 +45,7 @@ HandlerResponse WSRequestHandler::HandleSetCurrentScene(WSRequestHandler* req) {
|
||||
* @category scenes
|
||||
* @since 0.3
|
||||
*/
|
||||
HandlerResponse WSRequestHandler::HandleGetCurrentScene(WSRequestHandler* req) {
|
||||
RpcResponse WSRequestHandler::GetCurrentScene(const RpcRequest& request) {
|
||||
OBSSourceAutoRelease currentScene = obs_frontend_get_current_scene();
|
||||
OBSDataArrayAutoRelease sceneItems = Utils::GetSceneItems(currentScene);
|
||||
|
||||
@ -53,7 +53,7 @@ HandlerResponse WSRequestHandler::HandleGetCurrentScene(WSRequestHandler* req) {
|
||||
obs_data_set_string(data, "name", obs_source_get_name(currentScene));
|
||||
obs_data_set_array(data, "sources", sceneItems);
|
||||
|
||||
return req->SendOKResponse(data);
|
||||
return request.success(data);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -67,7 +67,7 @@ HandlerResponse WSRequestHandler::HandleGetCurrentScene(WSRequestHandler* req) {
|
||||
* @category scenes
|
||||
* @since 0.3
|
||||
*/
|
||||
HandlerResponse WSRequestHandler::HandleGetSceneList(WSRequestHandler* req) {
|
||||
RpcResponse WSRequestHandler::GetSceneList(const RpcRequest& request) {
|
||||
OBSSourceAutoRelease currentScene = obs_frontend_get_current_scene();
|
||||
OBSDataArrayAutoRelease scenes = Utils::GetScenes();
|
||||
|
||||
@ -76,7 +76,7 @@ HandlerResponse WSRequestHandler::HandleGetSceneList(WSRequestHandler* req) {
|
||||
obs_source_get_name(currentScene));
|
||||
obs_data_set_array(data, "scenes", scenes);
|
||||
|
||||
return req->SendOKResponse(data);
|
||||
return request.success(data);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -92,16 +92,16 @@ HandlerResponse WSRequestHandler::HandleGetSceneList(WSRequestHandler* req) {
|
||||
* @category scenes
|
||||
* @since 4.5.0
|
||||
*/
|
||||
HandlerResponse WSRequestHandler::HandleReorderSceneItems(WSRequestHandler* req) {
|
||||
QString sceneName = obs_data_get_string(req->data, "scene");
|
||||
RpcResponse WSRequestHandler::ReorderSceneItems(const RpcRequest& request) {
|
||||
QString sceneName = obs_data_get_string(request.parameters(), "scene");
|
||||
OBSScene scene = Utils::GetSceneFromNameOrCurrent(sceneName);
|
||||
if (!scene) {
|
||||
return req->SendErrorResponse("requested scene doesn't exist");
|
||||
return request.failed("requested scene doesn't exist");
|
||||
}
|
||||
|
||||
OBSDataArrayAutoRelease items = obs_data_get_array(req->data, "items");
|
||||
OBSDataArrayAutoRelease items = obs_data_get_array(request.parameters(), "items");
|
||||
if (!items) {
|
||||
return req->SendErrorResponse("sceneItem order not specified");
|
||||
return request.failed("sceneItem order not specified");
|
||||
}
|
||||
|
||||
struct reorder_context {
|
||||
@ -143,8 +143,8 @@ HandlerResponse WSRequestHandler::HandleReorderSceneItems(WSRequestHandler* req)
|
||||
}, &ctx);
|
||||
|
||||
if (!ctx.success) {
|
||||
return req->SendErrorResponse(ctx.errorMessage);
|
||||
return request.failed(ctx.errorMessage);
|
||||
}
|
||||
|
||||
return req->SendOKResponse();
|
||||
return request.success();
|
||||
}
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -20,7 +20,7 @@
|
||||
* @category streaming
|
||||
* @since 0.3
|
||||
*/
|
||||
HandlerResponse WSRequestHandler::HandleGetStreamingStatus(WSRequestHandler* req) {
|
||||
RpcResponse WSRequestHandler::GetStreamingStatus(const RpcRequest& request) {
|
||||
auto events = GetEventsSystem();
|
||||
|
||||
OBSDataAutoRelease data = obs_data_create();
|
||||
@ -39,7 +39,7 @@ HandlerResponse WSRequestHandler::HandleGetStreamingStatus(WSRequestHandler* req
|
||||
obs_data_set_string(data, "rec-timecode", recordingTimecode.toUtf8().constData());
|
||||
}
|
||||
|
||||
return req->SendOKResponse(data);
|
||||
return request.success(data);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -50,11 +50,11 @@ HandlerResponse WSRequestHandler::HandleGetStreamingStatus(WSRequestHandler* req
|
||||
* @category streaming
|
||||
* @since 0.3
|
||||
*/
|
||||
HandlerResponse WSRequestHandler::HandleStartStopStreaming(WSRequestHandler* req) {
|
||||
RpcResponse WSRequestHandler::StartStopStreaming(const RpcRequest& request) {
|
||||
if (obs_frontend_streaming_active())
|
||||
return HandleStopStreaming(req);
|
||||
return StopStreaming(request);
|
||||
else
|
||||
return HandleStartStreaming(req);
|
||||
return StartStreaming(request);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -76,15 +76,15 @@ HandlerResponse WSRequestHandler::HandleStartStopStreaming(WSRequestHandler* req
|
||||
* @category streaming
|
||||
* @since 4.1.0
|
||||
*/
|
||||
HandlerResponse WSRequestHandler::HandleStartStreaming(WSRequestHandler* req) {
|
||||
RpcResponse WSRequestHandler::StartStreaming(const RpcRequest& request) {
|
||||
if (obs_frontend_streaming_active() == false) {
|
||||
OBSService configuredService = obs_frontend_get_streaming_service();
|
||||
OBSService newService = nullptr;
|
||||
|
||||
// TODO: fix service memory leak
|
||||
|
||||
if (req->hasField("stream")) {
|
||||
OBSDataAutoRelease streamData = obs_data_get_obj(req->data, "stream");
|
||||
if (request.hasField("stream")) {
|
||||
OBSDataAutoRelease streamData = obs_data_get_obj(request.parameters(), "stream");
|
||||
OBSDataAutoRelease newSettings = obs_data_get_obj(streamData, "settings");
|
||||
OBSDataAutoRelease newMetadata = obs_data_get_obj(streamData, "metadata");
|
||||
|
||||
@ -157,9 +157,9 @@ HandlerResponse WSRequestHandler::HandleStartStreaming(WSRequestHandler* req) {
|
||||
obs_frontend_set_streaming_service(configuredService);
|
||||
}
|
||||
|
||||
return req->SendOKResponse();
|
||||
return request.success();
|
||||
} else {
|
||||
return req->SendErrorResponse("streaming already active");
|
||||
return request.failed("streaming already active");
|
||||
}
|
||||
}
|
||||
|
||||
@ -172,12 +172,12 @@ HandlerResponse WSRequestHandler::HandleStartStreaming(WSRequestHandler* req) {
|
||||
* @category streaming
|
||||
* @since 4.1.0
|
||||
*/
|
||||
HandlerResponse WSRequestHandler::HandleStopStreaming(WSRequestHandler* req) {
|
||||
RpcResponse WSRequestHandler::StopStreaming(const RpcRequest& request) {
|
||||
if (obs_frontend_streaming_active() == true) {
|
||||
obs_frontend_streaming_stop();
|
||||
return req->SendOKResponse();
|
||||
return request.success();
|
||||
} else {
|
||||
return req->SendErrorResponse("streaming not active");
|
||||
return request.failed("streaming not active");
|
||||
}
|
||||
}
|
||||
|
||||
@ -198,16 +198,16 @@ HandlerResponse WSRequestHandler::HandleStopStreaming(WSRequestHandler* req) {
|
||||
* @category streaming
|
||||
* @since 4.1.0
|
||||
*/
|
||||
HandlerResponse WSRequestHandler::HandleSetStreamSettings(WSRequestHandler* req) {
|
||||
RpcResponse WSRequestHandler::SetStreamSettings(const RpcRequest& request) {
|
||||
OBSService service = obs_frontend_get_streaming_service();
|
||||
|
||||
OBSDataAutoRelease requestSettings = obs_data_get_obj(req->data, "settings");
|
||||
OBSDataAutoRelease requestSettings = obs_data_get_obj(request.parameters(), "settings");
|
||||
if (!requestSettings) {
|
||||
return req->SendErrorResponse("'settings' are required'");
|
||||
return request.failed("'settings' are required'");
|
||||
}
|
||||
|
||||
QString serviceType = obs_service_get_type(service);
|
||||
QString requestedType = obs_data_get_string(req->data, "type");
|
||||
QString requestedType = obs_data_get_string(request.parameters(), "type");
|
||||
|
||||
if (requestedType != nullptr && requestedType != serviceType) {
|
||||
OBSDataAutoRelease hotkeys = obs_hotkeys_save_service(service);
|
||||
@ -231,7 +231,7 @@ HandlerResponse WSRequestHandler::HandleSetStreamSettings(WSRequestHandler* req)
|
||||
}
|
||||
|
||||
//if save is specified we should immediately save the streaming service
|
||||
if (obs_data_get_bool(req->data, "save")) {
|
||||
if (obs_data_get_bool(request.parameters(), "save")) {
|
||||
obs_frontend_save_streaming_service();
|
||||
}
|
||||
|
||||
@ -241,7 +241,7 @@ HandlerResponse WSRequestHandler::HandleSetStreamSettings(WSRequestHandler* req)
|
||||
obs_data_set_string(response, "type", requestedType.toUtf8());
|
||||
obs_data_set_obj(response, "settings", serviceSettings);
|
||||
|
||||
return req->SendOKResponse(response);
|
||||
return request.success(response);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -260,7 +260,7 @@ HandlerResponse WSRequestHandler::HandleSetStreamSettings(WSRequestHandler* req)
|
||||
* @category streaming
|
||||
* @since 4.1.0
|
||||
*/
|
||||
HandlerResponse WSRequestHandler::HandleGetStreamSettings(WSRequestHandler* req) {
|
||||
RpcResponse WSRequestHandler::GetStreamSettings(const RpcRequest& request) {
|
||||
OBSService service = obs_frontend_get_streaming_service();
|
||||
|
||||
const char* serviceType = obs_service_get_type(service);
|
||||
@ -270,7 +270,7 @@ HandlerResponse WSRequestHandler::HandleGetStreamSettings(WSRequestHandler* req)
|
||||
obs_data_set_string(response, "type", serviceType);
|
||||
obs_data_set_obj(response, "settings", settings);
|
||||
|
||||
return req->SendOKResponse(response);
|
||||
return request.success(response);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -281,9 +281,9 @@ HandlerResponse WSRequestHandler::HandleGetStreamSettings(WSRequestHandler* req)
|
||||
* @category streaming
|
||||
* @since 4.1.0
|
||||
*/
|
||||
HandlerResponse WSRequestHandler::HandleSaveStreamSettings(WSRequestHandler* req) {
|
||||
RpcResponse WSRequestHandler::SaveStreamSettings(const RpcRequest& request) {
|
||||
obs_frontend_save_streaming_service();
|
||||
return req->SendOKResponse();
|
||||
return request.success();
|
||||
}
|
||||
|
||||
|
||||
@ -299,19 +299,19 @@ HandlerResponse WSRequestHandler::HandleSaveStreamSettings(WSRequestHandler* req
|
||||
* @since 4.6.0
|
||||
*/
|
||||
#if BUILD_CAPTIONS
|
||||
HandlerResponse WSRequestHandler::HandleSendCaptions(WSRequestHandler* req) {
|
||||
if (!req->hasField("text")) {
|
||||
return req->SendErrorResponse("missing request parameters");
|
||||
RpcResponse WSRequestHandler::SendCaptions(const RpcRequest& request) {
|
||||
if (!request.hasField("text")) {
|
||||
return request.failed("missing request parameters");
|
||||
}
|
||||
|
||||
OBSOutputAutoRelease output = obs_frontend_get_streaming_output();
|
||||
if (output) {
|
||||
const char* caption = obs_data_get_string(req->data, "text");
|
||||
const char* caption = obs_data_get_string(request.parameters(), "text");
|
||||
// Send caption text with immediately (0 second delay)
|
||||
obs_output_output_caption_text2(output, caption, 0.0);
|
||||
}
|
||||
|
||||
return req->SendOKResponse();
|
||||
return request.success();
|
||||
}
|
||||
#endif
|
||||
|
||||
|
@ -12,13 +12,13 @@
|
||||
* @category studio mode
|
||||
* @since 4.1.0
|
||||
*/
|
||||
HandlerResponse WSRequestHandler::HandleGetStudioModeStatus(WSRequestHandler* req) {
|
||||
RpcResponse WSRequestHandler::GetStudioModeStatus(const RpcRequest& request) {
|
||||
bool previewActive = obs_frontend_preview_program_mode_active();
|
||||
|
||||
OBSDataAutoRelease response = obs_data_create();
|
||||
obs_data_set_bool(response, "studio-mode", previewActive);
|
||||
|
||||
return req->SendOKResponse(response);
|
||||
return request.success(response);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -33,9 +33,9 @@ HandlerResponse WSRequestHandler::HandleGetStudioModeStatus(WSRequestHandler* re
|
||||
* @category studio mode
|
||||
* @since 4.1.0
|
||||
*/
|
||||
HandlerResponse WSRequestHandler::HandleGetPreviewScene(WSRequestHandler* req) {
|
||||
RpcResponse WSRequestHandler::GetPreviewScene(const RpcRequest& request) {
|
||||
if (!obs_frontend_preview_program_mode_active()) {
|
||||
return req->SendErrorResponse("studio mode not enabled");
|
||||
return request.failed("studio mode not enabled");
|
||||
}
|
||||
|
||||
OBSSourceAutoRelease scene = obs_frontend_get_current_preview_scene();
|
||||
@ -45,7 +45,7 @@ HandlerResponse WSRequestHandler::HandleGetPreviewScene(WSRequestHandler* req) {
|
||||
obs_data_set_string(data, "name", obs_source_get_name(scene));
|
||||
obs_data_set_array(data, "sources", sceneItems);
|
||||
|
||||
return req->SendOKResponse(data);
|
||||
return request.success(data);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -59,23 +59,23 @@ HandlerResponse WSRequestHandler::HandleGetPreviewScene(WSRequestHandler* req) {
|
||||
* @category studio mode
|
||||
* @since 4.1.0
|
||||
*/
|
||||
HandlerResponse WSRequestHandler::HandleSetPreviewScene(WSRequestHandler* req) {
|
||||
RpcResponse WSRequestHandler::SetPreviewScene(const RpcRequest& request) {
|
||||
if (!obs_frontend_preview_program_mode_active()) {
|
||||
return req->SendErrorResponse("studio mode not enabled");
|
||||
return request.failed("studio mode not enabled");
|
||||
}
|
||||
|
||||
if (!req->hasField("scene-name")) {
|
||||
return req->SendErrorResponse("missing request parameters");
|
||||
if (!request.hasField("scene-name")) {
|
||||
return request.failed("missing request parameters");
|
||||
}
|
||||
|
||||
const char* scene_name = obs_data_get_string(req->data, "scene-name");
|
||||
const char* scene_name = obs_data_get_string(request.parameters(), "scene-name");
|
||||
OBSScene scene = Utils::GetSceneFromNameOrCurrent(scene_name);
|
||||
if (!scene) {
|
||||
return req->SendErrorResponse("specified scene doesn't exist");
|
||||
return request.failed("specified scene doesn't exist");
|
||||
}
|
||||
|
||||
obs_frontend_set_current_preview_scene(obs_scene_get_source(scene));
|
||||
return req->SendOKResponse();
|
||||
return request.success();
|
||||
}
|
||||
|
||||
/**
|
||||
@ -91,25 +91,25 @@ HandlerResponse WSRequestHandler::HandleSetPreviewScene(WSRequestHandler* req) {
|
||||
* @category studio mode
|
||||
* @since 4.1.0
|
||||
*/
|
||||
HandlerResponse WSRequestHandler::HandleTransitionToProgram(WSRequestHandler* req) {
|
||||
RpcResponse WSRequestHandler::TransitionToProgram(const RpcRequest& request) {
|
||||
if (!obs_frontend_preview_program_mode_active()) {
|
||||
return req->SendErrorResponse("studio mode not enabled");
|
||||
return request.failed("studio mode not enabled");
|
||||
}
|
||||
|
||||
if (req->hasField("with-transition")) {
|
||||
if (request.hasField("with-transition")) {
|
||||
OBSDataAutoRelease transitionInfo =
|
||||
obs_data_get_obj(req->data, "with-transition");
|
||||
obs_data_get_obj(request.parameters(), "with-transition");
|
||||
|
||||
if (obs_data_has_user_value(transitionInfo, "name")) {
|
||||
QString transitionName =
|
||||
obs_data_get_string(transitionInfo, "name");
|
||||
if (transitionName.isEmpty()) {
|
||||
return req->SendErrorResponse("invalid request parameters");
|
||||
return request.failed("invalid request parameters");
|
||||
}
|
||||
|
||||
bool success = Utils::SetTransitionByName(transitionName);
|
||||
if (!success) {
|
||||
return req->SendErrorResponse("specified transition doesn't exist");
|
||||
return request.failed("specified transition doesn't exist");
|
||||
}
|
||||
}
|
||||
|
||||
@ -121,7 +121,7 @@ HandlerResponse WSRequestHandler::HandleTransitionToProgram(WSRequestHandler* re
|
||||
}
|
||||
|
||||
obs_frontend_preview_program_trigger_transition();
|
||||
return req->SendOKResponse();
|
||||
return request.success();
|
||||
}
|
||||
|
||||
/**
|
||||
@ -132,9 +132,9 @@ HandlerResponse WSRequestHandler::HandleTransitionToProgram(WSRequestHandler* re
|
||||
* @category studio mode
|
||||
* @since 4.1.0
|
||||
*/
|
||||
HandlerResponse WSRequestHandler::HandleEnableStudioMode(WSRequestHandler* req) {
|
||||
RpcResponse WSRequestHandler::EnableStudioMode(const RpcRequest& request) {
|
||||
obs_frontend_set_preview_program_mode(true);
|
||||
return req->SendOKResponse();
|
||||
return request.success();
|
||||
}
|
||||
|
||||
/**
|
||||
@ -145,9 +145,9 @@ HandlerResponse WSRequestHandler::HandleEnableStudioMode(WSRequestHandler* req)
|
||||
* @category studio mode
|
||||
* @since 4.1.0
|
||||
*/
|
||||
HandlerResponse WSRequestHandler::HandleDisableStudioMode(WSRequestHandler* req) {
|
||||
RpcResponse WSRequestHandler::DisableStudioMode(const RpcRequest& request) {
|
||||
obs_frontend_set_preview_program_mode(false);
|
||||
return req->SendOKResponse();
|
||||
return request.success();
|
||||
}
|
||||
|
||||
/**
|
||||
@ -158,8 +158,8 @@ HandlerResponse WSRequestHandler::HandleDisableStudioMode(WSRequestHandler* req)
|
||||
* @category studio mode
|
||||
* @since 4.1.0
|
||||
*/
|
||||
HandlerResponse WSRequestHandler::HandleToggleStudioMode(WSRequestHandler* req) {
|
||||
RpcResponse WSRequestHandler::ToggleStudioMode(const RpcRequest& request) {
|
||||
bool previewProgramMode = obs_frontend_preview_program_mode_active();
|
||||
obs_frontend_set_preview_program_mode(!previewProgramMode);
|
||||
return req->SendOKResponse();
|
||||
return request.success();
|
||||
}
|
||||
|
@ -14,7 +14,7 @@
|
||||
* @category transitions
|
||||
* @since 4.1.0
|
||||
*/
|
||||
HandlerResponse WSRequestHandler::HandleGetTransitionList(WSRequestHandler* req) {
|
||||
RpcResponse WSRequestHandler::GetTransitionList(const RpcRequest& request) {
|
||||
OBSSourceAutoRelease currentTransition = obs_frontend_get_current_transition();
|
||||
obs_frontend_source_list transitionList = {};
|
||||
obs_frontend_get_transitions(&transitionList);
|
||||
@ -34,7 +34,7 @@ HandlerResponse WSRequestHandler::HandleGetTransitionList(WSRequestHandler* req)
|
||||
obs_source_get_name(currentTransition));
|
||||
obs_data_set_array(response, "transitions", transitions);
|
||||
|
||||
return req->SendOKResponse(response);
|
||||
return request.success(response);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -48,7 +48,7 @@ HandlerResponse WSRequestHandler::HandleGetTransitionList(WSRequestHandler* req)
|
||||
* @category transitions
|
||||
* @since 0.3
|
||||
*/
|
||||
HandlerResponse WSRequestHandler::HandleGetCurrentTransition(WSRequestHandler* req) {
|
||||
RpcResponse WSRequestHandler::GetCurrentTransition(const RpcRequest& request) {
|
||||
OBSSourceAutoRelease currentTransition = obs_frontend_get_current_transition();
|
||||
|
||||
OBSDataAutoRelease response = obs_data_create();
|
||||
@ -58,7 +58,7 @@ HandlerResponse WSRequestHandler::HandleGetCurrentTransition(WSRequestHandler* r
|
||||
if (!obs_transition_fixed(currentTransition))
|
||||
obs_data_set_int(response, "duration", obs_frontend_get_transition_duration());
|
||||
|
||||
return req->SendOKResponse(response);
|
||||
return request.success(response);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -71,18 +71,18 @@ HandlerResponse WSRequestHandler::HandleGetCurrentTransition(WSRequestHandler* r
|
||||
* @category transitions
|
||||
* @since 0.3
|
||||
*/
|
||||
HandlerResponse WSRequestHandler::HandleSetCurrentTransition(WSRequestHandler* req) {
|
||||
if (!req->hasField("transition-name")) {
|
||||
return req->SendErrorResponse("missing request parameters");
|
||||
RpcResponse WSRequestHandler::SetCurrentTransition(const RpcRequest& request) {
|
||||
if (!request.hasField("transition-name")) {
|
||||
return request.failed("missing request parameters");
|
||||
}
|
||||
|
||||
QString name = obs_data_get_string(req->data, "transition-name");
|
||||
QString name = obs_data_get_string(request.parameters(), "transition-name");
|
||||
bool success = Utils::SetTransitionByName(name);
|
||||
if (!success) {
|
||||
return req->SendErrorResponse("requested transition does not exist");
|
||||
return request.failed("requested transition does not exist");
|
||||
}
|
||||
|
||||
return req->SendOKResponse();
|
||||
return request.success();
|
||||
}
|
||||
|
||||
/**
|
||||
@ -95,14 +95,14 @@ HandlerResponse WSRequestHandler::HandleSetCurrentTransition(WSRequestHandler* r
|
||||
* @category transitions
|
||||
* @since 4.0.0
|
||||
*/
|
||||
HandlerResponse WSRequestHandler::HandleSetTransitionDuration(WSRequestHandler* req) {
|
||||
if (!req->hasField("duration")) {
|
||||
return req->SendErrorResponse("missing request parameters");
|
||||
RpcResponse WSRequestHandler::SetTransitionDuration(const RpcRequest& request) {
|
||||
if (!request.hasField("duration")) {
|
||||
return request.failed("missing request parameters");
|
||||
}
|
||||
|
||||
int ms = obs_data_get_int(req->data, "duration");
|
||||
int ms = obs_data_get_int(request.parameters(), "duration");
|
||||
obs_frontend_set_transition_duration(ms);
|
||||
return req->SendOKResponse();
|
||||
return request.success();
|
||||
}
|
||||
|
||||
/**
|
||||
@ -115,8 +115,8 @@ HandlerResponse WSRequestHandler::HandleSetTransitionDuration(WSRequestHandler*
|
||||
* @category transitions
|
||||
* @since 4.1.0
|
||||
*/
|
||||
HandlerResponse WSRequestHandler::HandleGetTransitionDuration(WSRequestHandler* req) {
|
||||
RpcResponse WSRequestHandler::GetTransitionDuration(const RpcRequest& request) {
|
||||
OBSDataAutoRelease response = obs_data_create();
|
||||
obs_data_set_int(response, "transition-duration", obs_frontend_get_transition_duration());
|
||||
return req->SendOKResponse(response);
|
||||
return request.success(response);
|
||||
}
|
||||
|
@ -31,6 +31,7 @@ with this program. If not, see <https://www.gnu.org/licenses/>
|
||||
#include "obs-websocket.h"
|
||||
#include "Config.h"
|
||||
#include "Utils.h"
|
||||
#include "protocol/OBSRemoteProtocol.h"
|
||||
|
||||
QT_USE_NAMESPACE
|
||||
|
||||
@ -124,8 +125,15 @@ void WSServer::stop()
|
||||
blog(LOG_INFO, "server stopped successfully");
|
||||
}
|
||||
|
||||
void WSServer::broadcast(std::string message)
|
||||
void WSServer::broadcast(const RpcEvent& event)
|
||||
{
|
||||
OBSRemoteProtocol protocol;
|
||||
std::string message = protocol.encodeEvent(event);
|
||||
|
||||
if (GetConfig()->DebugEnabled) {
|
||||
blog(LOG_INFO, "Update << '%s'", message.c_str());
|
||||
}
|
||||
|
||||
QMutexLocker locker(&_clMutex);
|
||||
for (connection_hdl hdl : _connections) {
|
||||
if (GetConfig()->AuthRequired) {
|
||||
@ -171,8 +179,17 @@ void WSServer::onMessage(connection_hdl hdl, server::message_ptr message)
|
||||
ConnectionProperties& connProperties = _connectionProperties[hdl];
|
||||
locker.unlock();
|
||||
|
||||
WSRequestHandler handler(connProperties);
|
||||
std::string response = handler.processIncomingMessage(payload);
|
||||
if (GetConfig()->DebugEnabled) {
|
||||
blog(LOG_INFO, "Request >> '%s'", payload.c_str());
|
||||
}
|
||||
|
||||
WSRequestHandler requestHandler(connProperties);
|
||||
OBSRemoteProtocol protocol;
|
||||
std::string response = protocol.processMessage(requestHandler, payload);
|
||||
|
||||
if (GetConfig()->DebugEnabled) {
|
||||
blog(LOG_INFO, "Response << '%s'", response.c_str());
|
||||
}
|
||||
|
||||
websocketpp::lib::error_code errorCode;
|
||||
_server.send(hdl, response, websocketpp::frame::opcode::text, errorCode);
|
||||
|
@ -30,8 +30,8 @@ with this program. If not, see <https://www.gnu.org/licenses/>
|
||||
#include <websocketpp/server.hpp>
|
||||
|
||||
#include "ConnectionProperties.h"
|
||||
|
||||
#include "WSRequestHandler.h"
|
||||
#include "rpc/RpcEvent.h"
|
||||
|
||||
using websocketpp::connection_hdl;
|
||||
|
||||
@ -46,7 +46,7 @@ public:
|
||||
virtual ~WSServer();
|
||||
void start(quint16 port);
|
||||
void stop();
|
||||
void broadcast(std::string message);
|
||||
void broadcast(const RpcEvent& event);
|
||||
QThreadPool* threadPool() {
|
||||
return &_threadPool;
|
||||
}
|
||||
|
117
src/protocol/OBSRemoteProtocol.cpp
Normal file
117
src/protocol/OBSRemoteProtocol.cpp
Normal file
@ -0,0 +1,117 @@
|
||||
/*
|
||||
obs-websocket
|
||||
Copyright (C) 2016-2019 Stéphane Lepin <stephane.lepin@gmail.com>
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License along
|
||||
with this program. If not, see <https://www.gnu.org/licenses/>
|
||||
*/
|
||||
|
||||
#include <inttypes.h>
|
||||
|
||||
#include "OBSRemoteProtocol.h"
|
||||
#include "../WSRequestHandler.h"
|
||||
#include "../rpc/RpcEvent.h"
|
||||
#include "../Utils.h"
|
||||
|
||||
std::string OBSRemoteProtocol::processMessage(WSRequestHandler& requestHandler, std::string message)
|
||||
{
|
||||
std::string msgContainer(message);
|
||||
const char* msg = msgContainer.c_str();
|
||||
|
||||
OBSDataAutoRelease data = obs_data_create_from_json(msg);
|
||||
if (!data) {
|
||||
blog(LOG_ERROR, "invalid JSON payload received for '%s'", msg);
|
||||
return errorResponse(QString::Null(), "invalid JSON payload");
|
||||
}
|
||||
|
||||
if (!obs_data_has_user_value(data, "request-type") || !obs_data_has_user_value(data, "message-id")) {
|
||||
return errorResponse(QString::Null(), "missing request parameters");
|
||||
}
|
||||
|
||||
QString methodName = obs_data_get_string(data, "request-type");
|
||||
QString messageId = obs_data_get_string(data, "message-id");
|
||||
|
||||
OBSDataAutoRelease params = obs_data_create();
|
||||
obs_data_apply(params, data);
|
||||
obs_data_unset_user_value(params, "request-type");
|
||||
obs_data_unset_user_value(params, "message-id");
|
||||
|
||||
RpcRequest request(messageId, methodName, params);
|
||||
RpcResponse response = requestHandler.processRequest(request);
|
||||
|
||||
OBSData additionalFields = response.additionalFields();
|
||||
switch (response.status()) {
|
||||
case RpcResponse::Status::Ok:
|
||||
return successResponse(messageId, additionalFields);
|
||||
case RpcResponse::Status::Error:
|
||||
return errorResponse(messageId, response.errorMessage(), additionalFields);
|
||||
}
|
||||
|
||||
return std::string();
|
||||
}
|
||||
|
||||
std::string OBSRemoteProtocol::encodeEvent(const RpcEvent& event)
|
||||
{
|
||||
OBSDataAutoRelease eventData = obs_data_create();
|
||||
|
||||
QString updateType = event.updateType();
|
||||
obs_data_set_string(eventData, "update-type", updateType.toUtf8().constData());
|
||||
|
||||
if (obs_frontend_streaming_active()) {
|
||||
QString streamingTimecode = Utils::nsToTimestamp(event.streamTime());
|
||||
obs_data_set_string(eventData, "stream-timecode", streamingTimecode.toUtf8().constData());
|
||||
}
|
||||
|
||||
if (obs_frontend_recording_active()) {
|
||||
QString recordingTimecode = Utils::nsToTimestamp(event.recordingTime());
|
||||
obs_data_set_string(eventData, "rec-timecode", recordingTimecode.toUtf8().constData());
|
||||
}
|
||||
|
||||
OBSData additionalFields = event.additionalFields();
|
||||
if (additionalFields) {
|
||||
obs_data_apply(eventData, additionalFields);
|
||||
}
|
||||
|
||||
return std::string(obs_data_get_json(eventData));
|
||||
}
|
||||
|
||||
std::string OBSRemoteProtocol::buildResponse(QString messageId, QString status, obs_data_t* fields)
|
||||
{
|
||||
OBSDataAutoRelease response = obs_data_create();
|
||||
if (!messageId.isNull()) {
|
||||
obs_data_set_string(response, "message-id", messageId.toUtf8().constData());
|
||||
}
|
||||
obs_data_set_string(response, "status", status.toUtf8().constData());
|
||||
|
||||
if (fields) {
|
||||
obs_data_apply(response, fields);
|
||||
}
|
||||
|
||||
std::string responseString = obs_data_get_json(response);
|
||||
return responseString;
|
||||
}
|
||||
|
||||
std::string OBSRemoteProtocol::successResponse(QString messageId, obs_data_t* fields)
|
||||
{
|
||||
return buildResponse(messageId, "ok", fields);
|
||||
}
|
||||
|
||||
std::string OBSRemoteProtocol::errorResponse(QString messageId, QString errorMessage, obs_data_t* additionalFields)
|
||||
{
|
||||
OBSDataAutoRelease fields = obs_data_create();
|
||||
if (additionalFields) {
|
||||
obs_data_apply(fields, additionalFields);
|
||||
}
|
||||
obs_data_set_string(fields, "error", errorMessage.toUtf8().constData());
|
||||
return buildResponse(messageId, "error", fields);
|
||||
}
|
38
src/protocol/OBSRemoteProtocol.h
Normal file
38
src/protocol/OBSRemoteProtocol.h
Normal file
@ -0,0 +1,38 @@
|
||||
/*
|
||||
obs-websocket
|
||||
Copyright (C) 2016-2019 Stéphane Lepin <stephane.lepin@gmail.com>
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License along
|
||||
with this program. If not, see <https://www.gnu.org/licenses/>
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <string>
|
||||
#include <obs-data.h>
|
||||
#include <QtCore/QString>
|
||||
|
||||
class WSRequestHandler;
|
||||
class RpcEvent;
|
||||
|
||||
class OBSRemoteProtocol
|
||||
{
|
||||
public:
|
||||
std::string processMessage(WSRequestHandler& requestHandler, std::string message);
|
||||
std::string encodeEvent(const RpcEvent& event);
|
||||
|
||||
private:
|
||||
std::string buildResponse(QString messageId, QString status, obs_data_t* fields = nullptr);
|
||||
std::string successResponse(QString messageId, obs_data_t* fields = nullptr);
|
||||
std::string errorResponse(QString messageId, QString errorMessage, obs_data_t* additionalFields = nullptr);
|
||||
};
|
35
src/rpc/RpcEvent.cpp
Normal file
35
src/rpc/RpcEvent.cpp
Normal file
@ -0,0 +1,35 @@
|
||||
/*
|
||||
obs-websocket
|
||||
Copyright (C) 2016-2020 Stéphane Lepin <stephane.lepin@gmail.com>
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License along
|
||||
with this program. If not, see <https://www.gnu.org/licenses/>
|
||||
*/
|
||||
|
||||
#include "RpcEvent.h"
|
||||
|
||||
RpcEvent::RpcEvent(
|
||||
const QString& updateType,
|
||||
uint64_t streamTime, uint64_t recordingTime,
|
||||
obs_data_t* additionalFields
|
||||
) :
|
||||
_updateType(updateType),
|
||||
_streamTime(streamTime),
|
||||
_recordingTime(recordingTime),
|
||||
_additionalFields(nullptr)
|
||||
{
|
||||
if (additionalFields) {
|
||||
_additionalFields = obs_data_create();
|
||||
obs_data_apply(_additionalFields, additionalFields);
|
||||
}
|
||||
}
|
60
src/rpc/RpcEvent.h
Normal file
60
src/rpc/RpcEvent.h
Normal file
@ -0,0 +1,60 @@
|
||||
/*
|
||||
obs-websocket
|
||||
Copyright (C) 2016-2020 Stéphane Lepin <stephane.lepin@gmail.com>
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License along
|
||||
with this program. If not, see <https://www.gnu.org/licenses/>
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <obs-data.h>
|
||||
#include <QtCore/QString>
|
||||
|
||||
#include "../obs-websocket.h"
|
||||
|
||||
class RpcEvent
|
||||
{
|
||||
public:
|
||||
explicit RpcEvent(
|
||||
const QString& updateType,
|
||||
uint64_t streamTime, uint64_t recordingTime,
|
||||
obs_data_t* additionalFields = nullptr
|
||||
);
|
||||
|
||||
const QString& updateType() const
|
||||
{
|
||||
return _updateType;
|
||||
}
|
||||
|
||||
const uint64_t streamTime() const
|
||||
{
|
||||
return _streamTime;
|
||||
}
|
||||
|
||||
const uint64_t recordingTime() const
|
||||
{
|
||||
return _recordingTime;
|
||||
}
|
||||
|
||||
const OBSData additionalFields() const
|
||||
{
|
||||
return OBSData(_additionalFields);
|
||||
}
|
||||
|
||||
private:
|
||||
QString _updateType;
|
||||
uint64_t _streamTime;
|
||||
uint64_t _recordingTime;
|
||||
OBSDataAutoRelease _additionalFields;
|
||||
};
|
104
src/rpc/RpcRequest.cpp
Normal file
104
src/rpc/RpcRequest.cpp
Normal file
@ -0,0 +1,104 @@
|
||||
/*
|
||||
obs-websocket
|
||||
Copyright (C) 2016-2019 Stéphane Lepin <stephane.lepin@gmail.com>
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License along
|
||||
with this program. If not, see <https://www.gnu.org/licenses/>
|
||||
*/
|
||||
|
||||
#include "RpcRequest.h"
|
||||
#include "RpcResponse.h"
|
||||
|
||||
RpcRequest::RpcRequest(const QString& messageId, const QString& methodName, obs_data_t* params) :
|
||||
_messageId(messageId),
|
||||
_methodName(methodName),
|
||||
_parameters(nullptr)
|
||||
{
|
||||
if (params) {
|
||||
_parameters = obs_data_create();
|
||||
obs_data_apply(_parameters, params);
|
||||
}
|
||||
}
|
||||
|
||||
const RpcResponse RpcRequest::success(obs_data_t* additionalFields) const
|
||||
{
|
||||
return RpcResponse::ok(*this, additionalFields);
|
||||
}
|
||||
|
||||
const RpcResponse RpcRequest::failed(const QString& errorMessage, obs_data_t* additionalFields) const
|
||||
{
|
||||
return RpcResponse::fail(*this, errorMessage, additionalFields);
|
||||
}
|
||||
|
||||
const bool RpcRequest::hasField(QString name, obs_data_type expectedFieldType, obs_data_number_type expectedNumberType) const
|
||||
{
|
||||
if (!_parameters || name.isEmpty() || name.isNull()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
OBSDataItemAutoRelease dataItem = obs_data_item_byname(_parameters, name.toUtf8());
|
||||
if (!dataItem) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (expectedFieldType != OBS_DATA_NULL) {
|
||||
obs_data_type fieldType = obs_data_item_gettype(dataItem);
|
||||
if (fieldType != expectedFieldType) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (fieldType == OBS_DATA_NUMBER && expectedNumberType != OBS_DATA_NUM_INVALID) {
|
||||
obs_data_number_type numberType = obs_data_item_numtype(dataItem);
|
||||
if (numberType != expectedNumberType) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
const bool RpcRequest::hasBool(QString fieldName) const
|
||||
{
|
||||
return this->hasField(fieldName, OBS_DATA_BOOLEAN);
|
||||
}
|
||||
|
||||
const bool RpcRequest::hasString(QString fieldName) const
|
||||
{
|
||||
return this->hasField(fieldName, OBS_DATA_STRING);
|
||||
}
|
||||
|
||||
const bool RpcRequest::hasNumber(QString fieldName, obs_data_number_type expectedNumberType) const
|
||||
{
|
||||
return this->hasField(fieldName, OBS_DATA_NUMBER, expectedNumberType);
|
||||
}
|
||||
|
||||
const bool RpcRequest::hasInteger(QString fieldName) const
|
||||
{
|
||||
return this->hasNumber(fieldName, OBS_DATA_NUM_INT);
|
||||
}
|
||||
|
||||
const bool RpcRequest::hasDouble(QString fieldName) const
|
||||
{
|
||||
return this->hasNumber(fieldName, OBS_DATA_NUM_DOUBLE);
|
||||
}
|
||||
|
||||
const bool RpcRequest::hasArray(QString fieldName) const
|
||||
{
|
||||
return this->hasField(fieldName, OBS_DATA_ARRAY);
|
||||
}
|
||||
|
||||
const bool RpcRequest::hasObject(QString fieldName) const
|
||||
{
|
||||
return this->hasField(fieldName, OBS_DATA_OBJECT);
|
||||
}
|
65
src/rpc/RpcRequest.h
Normal file
65
src/rpc/RpcRequest.h
Normal file
@ -0,0 +1,65 @@
|
||||
/*
|
||||
obs-websocket
|
||||
Copyright (C) 2016-2019 Stéphane Lepin <stephane.lepin@gmail.com>
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License along
|
||||
with this program. If not, see <https://www.gnu.org/licenses/>
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <obs-data.h>
|
||||
#include <QtCore/QString>
|
||||
#include "../obs-websocket.h"
|
||||
|
||||
// forward declarations
|
||||
class RpcResponse;
|
||||
|
||||
class RpcRequest
|
||||
{
|
||||
public:
|
||||
explicit RpcRequest(const QString& messageId, const QString& methodName, obs_data_t* params);
|
||||
|
||||
const QString& messageId() const
|
||||
{
|
||||
return _messageId;
|
||||
}
|
||||
|
||||
const QString& methodName() const
|
||||
{
|
||||
return _methodName;
|
||||
}
|
||||
|
||||
const OBSData parameters() const
|
||||
{
|
||||
return OBSData(_parameters);
|
||||
}
|
||||
|
||||
const RpcResponse success(obs_data_t* additionalFields = nullptr) const;
|
||||
const RpcResponse failed(const QString& errorMessage, obs_data_t* additionalFields = nullptr) const;
|
||||
|
||||
const bool hasField(QString fieldName, obs_data_type expectedFieldType = OBS_DATA_NULL,
|
||||
obs_data_number_type expectedNumberType = OBS_DATA_NUM_INVALID) const;
|
||||
const bool hasBool(QString fieldName) const;
|
||||
const bool hasString(QString fieldName) const;
|
||||
const bool hasNumber(QString fieldName, obs_data_number_type expectedNumberType = OBS_DATA_NUM_INVALID) const;
|
||||
const bool hasInteger(QString fieldName) const;
|
||||
const bool hasDouble(QString fieldName) const;
|
||||
const bool hasArray(QString fieldName) const;
|
||||
const bool hasObject(QString fieldName) const;
|
||||
|
||||
private:
|
||||
const QString _messageId;
|
||||
const QString _methodName;
|
||||
OBSDataAutoRelease _parameters;
|
||||
};
|
48
src/rpc/RpcResponse.cpp
Normal file
48
src/rpc/RpcResponse.cpp
Normal file
@ -0,0 +1,48 @@
|
||||
/*
|
||||
obs-websocket
|
||||
Copyright (C) 2016-2019 Stéphane Lepin <stephane.lepin@gmail.com>
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License along
|
||||
with this program. If not, see <https://www.gnu.org/licenses/>
|
||||
*/
|
||||
|
||||
#include "RpcResponse.h"
|
||||
#include "RpcRequest.h"
|
||||
|
||||
RpcResponse::RpcResponse(
|
||||
Status status, const QString& messageId,
|
||||
const QString& methodName, obs_data_t* additionalFields
|
||||
) :
|
||||
_status(status),
|
||||
_messageId(messageId),
|
||||
_methodName(methodName),
|
||||
_additionalFields(nullptr)
|
||||
{
|
||||
if (additionalFields) {
|
||||
_additionalFields = obs_data_create();
|
||||
obs_data_apply(_additionalFields, additionalFields);
|
||||
}
|
||||
}
|
||||
|
||||
const RpcResponse RpcResponse::ok(const RpcRequest& request, obs_data_t* additionalFields)
|
||||
{
|
||||
RpcResponse response(Status::Ok, request.messageId(), request.methodName(), additionalFields);
|
||||
return response;
|
||||
}
|
||||
|
||||
const RpcResponse RpcResponse::fail(const RpcRequest& request, const QString& errorMessage, obs_data_t* additionalFields)
|
||||
{
|
||||
RpcResponse response(Status::Error, request.messageId(), request.methodName(), additionalFields);
|
||||
response._errorMessage = errorMessage;
|
||||
return response;
|
||||
}
|
70
src/rpc/RpcResponse.h
Normal file
70
src/rpc/RpcResponse.h
Normal file
@ -0,0 +1,70 @@
|
||||
/*
|
||||
obs-websocket
|
||||
Copyright (C) 2016-2019 Stéphane Lepin <stephane.lepin@gmail.com>
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License along
|
||||
with this program. If not, see <https://www.gnu.org/licenses/>
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <obs-data.h>
|
||||
#include <QtCore/QString>
|
||||
#include "../obs-websocket.h"
|
||||
|
||||
class RpcRequest;
|
||||
|
||||
class RpcResponse
|
||||
{
|
||||
public:
|
||||
enum Status { Unknown, Ok, Error };
|
||||
|
||||
static RpcResponse ofRequest(const RpcRequest& request);
|
||||
static const RpcResponse ok(const RpcRequest& request, obs_data_t* additionalFields = nullptr);
|
||||
static const RpcResponse fail(
|
||||
const RpcRequest& request, const QString& errorMessage,
|
||||
obs_data_t* additionalFields = nullptr
|
||||
);
|
||||
|
||||
Status status() {
|
||||
return _status;
|
||||
}
|
||||
|
||||
const QString& messageId() const {
|
||||
return _messageId;
|
||||
}
|
||||
|
||||
const QString& methodName() const {
|
||||
return _methodName;
|
||||
}
|
||||
|
||||
const QString& errorMessage() const {
|
||||
return _errorMessage;
|
||||
}
|
||||
|
||||
const OBSData additionalFields() const {
|
||||
return OBSData(_additionalFields);
|
||||
}
|
||||
|
||||
private:
|
||||
explicit RpcResponse(
|
||||
Status status,
|
||||
const QString& messageId, const QString& methodName,
|
||||
obs_data_t* additionalFields = nullptr
|
||||
);
|
||||
const Status _status;
|
||||
const QString _messageId;
|
||||
const QString _methodName;
|
||||
QString _errorMessage;
|
||||
OBSDataAutoRelease _additionalFields;
|
||||
};
|
Loading…
x
Reference in New Issue
Block a user