mirror of
https://github.com/Palakis/obs-websocket.git
synced 2024-08-30 18:12:16 +00:00
Protocol: add Replay Buffer Events and Requests (#104)
This commit is contained in:
@ -65,6 +65,18 @@ if(WIN32)
|
|||||||
message(FATAL_ERROR "Could not find OBS Frontend API\'s library !")
|
message(FATAL_ERROR "Could not find OBS Frontend API\'s library !")
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
if(CMAKE_SIZEOF_VOID_P EQUAL 8)
|
||||||
|
set(ARCH_NAME "64bit")
|
||||||
|
set(OBS_BUILDDIR_ARCH "build64")
|
||||||
|
else()
|
||||||
|
set(ARCH_NAME "32bit")
|
||||||
|
set(OBS_BUILDDIR_ARCH "build32")
|
||||||
|
endif()
|
||||||
|
|
||||||
|
include_directories(
|
||||||
|
"${LIBOBS_INCLUDE_DIR}/../${OBS_BUILDDIR_ARCH}/UI"
|
||||||
|
)
|
||||||
|
|
||||||
target_link_libraries(obs-websocket
|
target_link_libraries(obs-websocket
|
||||||
"${OBS_FRONTEND_LIB}")
|
"${OBS_FRONTEND_LIB}")
|
||||||
|
|
||||||
@ -84,14 +96,6 @@ if(WIN32)
|
|||||||
# The "release" folder has a structure similar OBS' one on Windows
|
# The "release" folder has a structure similar OBS' one on Windows
|
||||||
set(RELEASE_DIR "${PROJECT_SOURCE_DIR}/release")
|
set(RELEASE_DIR "${PROJECT_SOURCE_DIR}/release")
|
||||||
|
|
||||||
if(CMAKE_SIZEOF_VOID_P EQUAL 8)
|
|
||||||
set(ARCH_NAME "64bit")
|
|
||||||
set(OBS_BUILDDIR_ARCH "build64")
|
|
||||||
else()
|
|
||||||
set(ARCH_NAME "32bit")
|
|
||||||
set(OBS_BUILDDIR_ARCH "build32")
|
|
||||||
endif()
|
|
||||||
|
|
||||||
add_custom_command(TARGET obs-websocket POST_BUILD
|
add_custom_command(TARGET obs-websocket POST_BUILD
|
||||||
COMMAND if $<CONFIG:Release>==1 (
|
COMMAND if $<CONFIG:Release>==1 (
|
||||||
"${CMAKE_COMMAND}" -E make_directory
|
"${CMAKE_COMMAND}" -E make_directory
|
||||||
|
56
Utils.cpp
56
Utils.cpp
@ -432,12 +432,12 @@ QString* Utils::ParseDataToQueryString(obs_data_t* data) {
|
|||||||
do {
|
do {
|
||||||
if (!obs_data_item_has_user_value(item))
|
if (!obs_data_item_has_user_value(item))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (!isFirst)
|
if (!isFirst)
|
||||||
query->append('&');
|
query->append('&');
|
||||||
else
|
else
|
||||||
isFirst = false;
|
isFirst = false;
|
||||||
|
|
||||||
const char* attrName = obs_data_item_get_name(item);
|
const char* attrName = obs_data_item_get_name(item);
|
||||||
query->append(attrName).append("=");
|
query->append(attrName).append("=");
|
||||||
|
|
||||||
@ -473,3 +473,55 @@ QString* Utils::ParseDataToQueryString(obs_data_t* data) {
|
|||||||
}
|
}
|
||||||
return query;
|
return query;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
obs_hotkey_t* Utils::FindHotkeyByName(const char* name) {
|
||||||
|
struct current_search {
|
||||||
|
const char* query;
|
||||||
|
obs_hotkey_t* result;
|
||||||
|
};
|
||||||
|
|
||||||
|
current_search search;
|
||||||
|
search.query = name;
|
||||||
|
search.result = nullptr;
|
||||||
|
|
||||||
|
obs_enum_hotkeys([](void* data, obs_hotkey_id id, obs_hotkey_t* hotkey) {
|
||||||
|
current_search* search = static_cast<current_search*>(data);
|
||||||
|
|
||||||
|
const char* hk_name = obs_hotkey_get_name(hotkey);
|
||||||
|
if (strcmp(hk_name, search->query) == 0) {
|
||||||
|
search->result = hotkey;
|
||||||
|
blog(LOG_INFO, "Utils::FindHotkeyByName: found %s", hk_name);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}, &search);
|
||||||
|
|
||||||
|
return search.result;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Utils::ReplayBufferEnabled() {
|
||||||
|
config_t* profile = obs_frontend_get_profile_config();
|
||||||
|
const char* outputMode = config_get_string(profile, "Output", "Mode");
|
||||||
|
|
||||||
|
if (strcmp(outputMode, "Simple") == 0) {
|
||||||
|
return config_get_bool(profile, "SimpleOutput", "RecRB");
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Utils::RPHotkeySet() {
|
||||||
|
obs_output_t* rp_output = obs_frontend_get_replay_buffer_output();
|
||||||
|
|
||||||
|
obs_data_t *hotkeys = obs_hotkeys_save_output(rp_output);
|
||||||
|
obs_data_array_t *bindings = obs_data_get_array(hotkeys,
|
||||||
|
"ReplayBuffer.Save");
|
||||||
|
|
||||||
|
size_t count = obs_data_array_count(bindings);
|
||||||
|
|
||||||
|
obs_data_array_release(bindings);
|
||||||
|
obs_data_release(hotkeys);
|
||||||
|
obs_output_release(rp_output);
|
||||||
|
|
||||||
|
return (count > 0);
|
||||||
|
}
|
||||||
|
5
Utils.h
5
Utils.h
@ -76,8 +76,11 @@ class Utils {
|
|||||||
static QString FormatIPAddress(QHostAddress &addr);
|
static QString FormatIPAddress(QHostAddress &addr);
|
||||||
static const char* GetRecordingFolder();
|
static const char* GetRecordingFolder();
|
||||||
static bool SetRecordingFolder(const char* path);
|
static bool SetRecordingFolder(const char* path);
|
||||||
|
|
||||||
static QString* ParseDataToQueryString(obs_data_t * data);
|
static QString* ParseDataToQueryString(obs_data_t * data);
|
||||||
|
static obs_hotkey_t* FindHotkeyByName(const char* name);
|
||||||
|
static bool ReplayBufferEnabled();
|
||||||
|
static bool RPHotkeySet();
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // UTILS_H
|
#endif // UTILS_H
|
||||||
|
56
WSEvents.cpp
56
WSEvents.cpp
@ -164,6 +164,18 @@ void WSEvents::FrontendEventHandler(enum obs_frontend_event event, void* private
|
|||||||
owner->_recording_active = false;
|
owner->_recording_active = false;
|
||||||
owner->OnRecordingStopped();
|
owner->OnRecordingStopped();
|
||||||
}
|
}
|
||||||
|
else if (event == OBS_FRONTEND_EVENT_REPLAY_BUFFER_STARTING) {
|
||||||
|
owner->OnReplayStarting();
|
||||||
|
}
|
||||||
|
else if (event == OBS_FRONTEND_EVENT_REPLAY_BUFFER_STARTED) {
|
||||||
|
owner->OnReplayStarted();
|
||||||
|
}
|
||||||
|
else if (event == OBS_FRONTEND_EVENT_REPLAY_BUFFER_STOPPING) {
|
||||||
|
owner->OnReplayStopping();
|
||||||
|
}
|
||||||
|
else if (event == OBS_FRONTEND_EVENT_REPLAY_BUFFER_STOPPED) {
|
||||||
|
owner->OnReplayStopped();
|
||||||
|
}
|
||||||
else if (event == OBS_FRONTEND_EVENT_EXIT) {
|
else if (event == OBS_FRONTEND_EVENT_EXIT) {
|
||||||
owner->OnExit();
|
owner->OnExit();
|
||||||
}
|
}
|
||||||
@ -500,6 +512,50 @@ void WSEvents::OnRecordingStopped() {
|
|||||||
broadcastUpdate("RecordingStopped");
|
broadcastUpdate("RecordingStopped");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A request to start the replay buffer has been issued.
|
||||||
|
*
|
||||||
|
* @api events
|
||||||
|
* @name ReplayStarting
|
||||||
|
* @category replay buffer
|
||||||
|
*/
|
||||||
|
void WSEvents::OnReplayStarting() {
|
||||||
|
broadcastUpdate("ReplayStarting");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Replay Buffer started successfully
|
||||||
|
*
|
||||||
|
* @api events
|
||||||
|
* @name ReplayStarted
|
||||||
|
* @category replay buffer
|
||||||
|
*/
|
||||||
|
void WSEvents::OnReplayStarted() {
|
||||||
|
broadcastUpdate("ReplayStarted");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A request to start the replay buffer has been issued.
|
||||||
|
*
|
||||||
|
* @api events
|
||||||
|
* @name ReplayStopping
|
||||||
|
* @category replay buffer
|
||||||
|
*/
|
||||||
|
void WSEvents::OnReplayStopping() {
|
||||||
|
broadcastUpdate("ReplayStopping");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Replay Buffer stopped successfully
|
||||||
|
*
|
||||||
|
* @api events
|
||||||
|
* @name ReplayStopped
|
||||||
|
* @category replay buffer
|
||||||
|
*/
|
||||||
|
void WSEvents::OnReplayStopped() {
|
||||||
|
broadcastUpdate("ReplayStopped");
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* OBS is exiting.
|
* OBS is exiting.
|
||||||
*
|
*
|
||||||
|
@ -87,6 +87,11 @@ class WSEvents : public QObject {
|
|||||||
void OnRecordingStopping();
|
void OnRecordingStopping();
|
||||||
void OnRecordingStopped();
|
void OnRecordingStopped();
|
||||||
|
|
||||||
|
void OnReplayStarting();
|
||||||
|
void OnReplayStarted();
|
||||||
|
void OnReplayStopping();
|
||||||
|
void OnReplayStopped();
|
||||||
|
|
||||||
void OnExit();
|
void OnExit();
|
||||||
|
|
||||||
static void OnTransitionBegin(void* param, calldata_t* data);
|
static void OnTransitionBegin(void* param, calldata_t* data);
|
||||||
|
@ -20,6 +20,7 @@
|
|||||||
#include <obs-data.h>
|
#include <obs-data.h>
|
||||||
|
|
||||||
#include <QList>
|
#include <QList>
|
||||||
|
#include <QObject>
|
||||||
#include <QString>
|
#include <QString>
|
||||||
|
|
||||||
#include "WSEvents.h"
|
#include "WSEvents.h"
|
||||||
@ -63,6 +64,11 @@ WSRequestHandler::WSRequestHandler(QWebSocket* client) :
|
|||||||
messageMap["StartRecording"] = WSRequestHandler::HandleStartRecording;
|
messageMap["StartRecording"] = WSRequestHandler::HandleStartRecording;
|
||||||
messageMap["StopRecording"] = WSRequestHandler::HandleStopRecording;
|
messageMap["StopRecording"] = WSRequestHandler::HandleStopRecording;
|
||||||
|
|
||||||
|
messageMap["StartStopReplayBuffer"] = WSRequestHandler::HandleStartStopReplayBuffer;
|
||||||
|
messageMap["StartReplayBuffer"] = WSRequestHandler::HandleStartReplayBuffer;
|
||||||
|
messageMap["StopReplayBuffer"] = WSRequestHandler::HandleStopReplayBuffer;
|
||||||
|
messageMap["SaveReplayBuffer"] = WSRequestHandler::HandleSaveReplayBuffer;
|
||||||
|
|
||||||
messageMap["SetRecordingFolder"] = WSRequestHandler::HandleSetRecordingFolder;
|
messageMap["SetRecordingFolder"] = WSRequestHandler::HandleSetRecordingFolder;
|
||||||
messageMap["GetRecordingFolder"] = WSRequestHandler::HandleGetRecordingFolder;
|
messageMap["GetRecordingFolder"] = WSRequestHandler::HandleGetRecordingFolder;
|
||||||
|
|
||||||
@ -184,7 +190,7 @@ void WSRequestHandler::SendResponse(obs_data_t* response) {
|
|||||||
_client->sendTextMessage(json);
|
_client->sendTextMessage(json);
|
||||||
if (Config::Current()->DebugEnabled)
|
if (Config::Current()->DebugEnabled)
|
||||||
blog(LOG_DEBUG, "Response << '%s'", json);
|
blog(LOG_DEBUG, "Response << '%s'", json);
|
||||||
|
|
||||||
obs_data_release(response);
|
obs_data_release(response);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -505,23 +511,23 @@ void WSRequestHandler::HandleStartStreaming(WSRequestHandler* req)
|
|||||||
if (obs_frontend_streaming_active() == false) {
|
if (obs_frontend_streaming_active() == false) {
|
||||||
obs_data_t* streamData = obs_data_get_obj(req->data, "stream");
|
obs_data_t* streamData = obs_data_get_obj(req->data, "stream");
|
||||||
obs_service_t* currentService = nullptr;
|
obs_service_t* currentService = nullptr;
|
||||||
|
|
||||||
if (streamData) {
|
if (streamData) {
|
||||||
currentService = obs_frontend_get_streaming_service();
|
currentService = obs_frontend_get_streaming_service();
|
||||||
obs_service_addref(currentService);
|
obs_service_addref(currentService);
|
||||||
|
|
||||||
obs_service_t* service = _service;
|
obs_service_t* service = _service;
|
||||||
const char* currentServiceType = obs_service_get_type(currentService);
|
const char* currentServiceType = obs_service_get_type(currentService);
|
||||||
|
|
||||||
const char* requestedType =
|
const char* requestedType =
|
||||||
obs_data_has_user_value(streamData, "type") ? obs_data_get_string(streamData, "type") : currentServiceType;
|
obs_data_has_user_value(streamData, "type") ? obs_data_get_string(streamData, "type") : currentServiceType;
|
||||||
const char* serviceType =
|
const char* serviceType =
|
||||||
service != nullptr ? obs_service_get_type(service) : currentServiceType;
|
service != nullptr ? obs_service_get_type(service) : currentServiceType;
|
||||||
obs_data_t* settings = obs_data_get_obj(streamData, "settings");
|
obs_data_t* settings = obs_data_get_obj(streamData, "settings");
|
||||||
|
|
||||||
obs_data_t* metadata = obs_data_get_obj(streamData, "metadata");
|
obs_data_t* metadata = obs_data_get_obj(streamData, "metadata");
|
||||||
QString* query = Utils::ParseDataToQueryString(metadata);
|
QString* query = Utils::ParseDataToQueryString(metadata);
|
||||||
|
|
||||||
if (strcmp(requestedType, serviceType) != 0) {
|
if (strcmp(requestedType, serviceType) != 0) {
|
||||||
if (settings) {
|
if (settings) {
|
||||||
obs_service_release(service);
|
obs_service_release(service);
|
||||||
@ -534,20 +540,20 @@ void WSRequestHandler::HandleStartStreaming(WSRequestHandler* req)
|
|||||||
//if type isn't changing we should overlay the settings we got with the existing settings
|
//if type isn't changing we should overlay the settings we got with the existing settings
|
||||||
obs_data_t* existingSettings = obs_service_get_settings(currentService);
|
obs_data_t* existingSettings = obs_service_get_settings(currentService);
|
||||||
obs_data_t* newSettings = obs_data_create(); //by doing this you can send a request to the websocket that only contains a setting you want to change instead of having to do a get and then change them
|
obs_data_t* newSettings = obs_data_create(); //by doing this you can send a request to the websocket that only contains a setting you want to change instead of having to do a get and then change them
|
||||||
|
|
||||||
obs_data_apply(newSettings, existingSettings); //first apply the existing settings
|
obs_data_apply(newSettings, existingSettings); //first apply the existing settings
|
||||||
|
|
||||||
obs_data_apply(newSettings, settings); //then apply the settings from the request should they exist
|
obs_data_apply(newSettings, settings); //then apply the settings from the request should they exist
|
||||||
obs_data_release(settings);
|
obs_data_release(settings);
|
||||||
|
|
||||||
settings = newSettings;
|
settings = newSettings;
|
||||||
obs_data_release(existingSettings);
|
obs_data_release(existingSettings);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!service){
|
if (!service){
|
||||||
service = obs_service_create(requestedType, "websocket_custom_service", settings, nullptr);
|
service = obs_service_create(requestedType, "websocket_custom_service", settings, nullptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
//Supporting adding metadata parameters to key query string
|
//Supporting adding metadata parameters to key query string
|
||||||
if (query && query->length() > 0) {
|
if (query && query->length() > 0) {
|
||||||
const char* key = obs_data_get_string(settings, "key");
|
const char* key = obs_data_get_string(settings, "key");
|
||||||
@ -568,7 +574,7 @@ void WSRequestHandler::HandleStartStreaming(WSRequestHandler* req)
|
|||||||
key = query->toUtf8();
|
key = query->toUtf8();
|
||||||
obs_data_set_string(settings, "key", key);
|
obs_data_set_string(settings, "key", key);
|
||||||
}
|
}
|
||||||
|
|
||||||
obs_service_update(service, settings);
|
obs_service_update(service, settings);
|
||||||
obs_data_release(settings);
|
obs_data_release(settings);
|
||||||
obs_data_release(metadata);
|
obs_data_release(metadata);
|
||||||
@ -579,13 +585,13 @@ void WSRequestHandler::HandleStartStreaming(WSRequestHandler* req)
|
|||||||
obs_service_release(_service);
|
obs_service_release(_service);
|
||||||
_service = nullptr;
|
_service = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
obs_frontend_streaming_start();
|
obs_frontend_streaming_start();
|
||||||
|
|
||||||
if (_service != nullptr) {
|
if (_service != nullptr) {
|
||||||
obs_frontend_set_streaming_service(currentService);
|
obs_frontend_set_streaming_service(currentService);
|
||||||
}
|
}
|
||||||
|
|
||||||
req->SendOKResponse();
|
req->SendOKResponse();
|
||||||
obs_service_release(currentService);
|
obs_service_release(currentService);
|
||||||
} else {
|
} else {
|
||||||
@ -644,6 +650,98 @@ void WSRequestHandler::HandleStopRecording(WSRequestHandler* req) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Toggle the Replay Buffer on/off.
|
||||||
|
*
|
||||||
|
* @api requests
|
||||||
|
* @name StartStopReplayBuffer
|
||||||
|
* @category replay buffer
|
||||||
|
*/
|
||||||
|
void WSRequestHandler::HandleStartStopReplayBuffer(WSRequestHandler* req) {
|
||||||
|
if (obs_frontend_replay_buffer_active()) {
|
||||||
|
obs_frontend_replay_buffer_stop();
|
||||||
|
} else {
|
||||||
|
if (!Utils::RPHotkeySet()) {
|
||||||
|
req->SendErrorResponse("replay buffer hotkey not set");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
obs_frontend_replay_buffer_start();
|
||||||
|
}
|
||||||
|
req->SendOKResponse();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Start recording into the Replay Buffer.
|
||||||
|
* Will return an `error` if the Replay Buffer is already active or if the
|
||||||
|
* "Save Replay Buffer" hotkey is not set in OBS' settings.
|
||||||
|
* Setting this hotkey is mandatory, even when triggering saves only
|
||||||
|
* through obs-websocket.
|
||||||
|
*
|
||||||
|
* @api requests
|
||||||
|
* @name StartReplayBuffer
|
||||||
|
* @category replay buffer
|
||||||
|
*/
|
||||||
|
void WSRequestHandler::HandleStartReplayBuffer(WSRequestHandler* req) {
|
||||||
|
if (!Utils::ReplayBufferEnabled()) {
|
||||||
|
req->SendErrorResponse("replay buffer disabled in settings");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (obs_frontend_replay_buffer_active() == true) {
|
||||||
|
req->SendErrorResponse("replay buffer already active");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!Utils::RPHotkeySet()) {
|
||||||
|
req->SendErrorResponse("replay buffer hotkey not set");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
obs_frontend_replay_buffer_start();
|
||||||
|
req->SendOKResponse();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Stop recording into the Replay Buffer.
|
||||||
|
* Will return an `error` if the Replay Buffer is not active.
|
||||||
|
*
|
||||||
|
* @api requests
|
||||||
|
* @name StopReplayBuffer
|
||||||
|
* @category replay buffer
|
||||||
|
*/
|
||||||
|
void WSRequestHandler::HandleStopReplayBuffer(WSRequestHandler* req) {
|
||||||
|
if (obs_frontend_replay_buffer_active() == true) {
|
||||||
|
obs_frontend_replay_buffer_stop();
|
||||||
|
req->SendOKResponse();
|
||||||
|
} else {
|
||||||
|
req->SendErrorResponse("replay buffer not active");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Save and flush the contents of the Replay Buffer to disk. This is
|
||||||
|
* basically the same as triggering the "Save Replay Buffer" hotkey.
|
||||||
|
* Will return an `error` if the Replay Buffer is not active.
|
||||||
|
*
|
||||||
|
* @api requests
|
||||||
|
* @name SaveReplayBuffer
|
||||||
|
* @category replay buffer
|
||||||
|
*/
|
||||||
|
void WSRequestHandler::HandleSaveReplayBuffer(WSRequestHandler* req) {
|
||||||
|
if (!obs_frontend_replay_buffer_active()) {
|
||||||
|
req->SendErrorResponse("replay buffer not active");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
obs_hotkey_t* hk = Utils::FindHotkeyByName("ReplayBuffer.Save");
|
||||||
|
if (hk) {
|
||||||
|
obs_hotkey_trigger_routed_callback(obs_hotkey_get_id(hk), true);
|
||||||
|
req->SendOKResponse();
|
||||||
|
} else {
|
||||||
|
req->SendErrorResponse("failed to save replay buffer");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* List of all transitions available in the frontend's dropdown menu.
|
* List of all transitions available in the frontend's dropdown menu.
|
||||||
*
|
*
|
||||||
@ -1298,13 +1396,13 @@ void WSRequestHandler::HandleGetCurrentProfile(WSRequestHandler* req) {
|
|||||||
*/
|
*/
|
||||||
void WSRequestHandler::HandleSetStreamSettings(WSRequestHandler* req) {
|
void WSRequestHandler::HandleSetStreamSettings(WSRequestHandler* req) {
|
||||||
obs_service_t* service = obs_frontend_get_streaming_service();
|
obs_service_t* service = obs_frontend_get_streaming_service();
|
||||||
|
|
||||||
obs_data_t* settings = obs_data_get_obj(req->data, "settings");
|
obs_data_t* settings = obs_data_get_obj(req->data, "settings");
|
||||||
if (!settings) {
|
if (!settings) {
|
||||||
req->SendErrorResponse("'settings' are required'");
|
req->SendErrorResponse("'settings' are required'");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const char* serviceType = obs_service_get_type(service);
|
const char* serviceType = obs_service_get_type(service);
|
||||||
const char* requestedType = obs_data_get_string(req->data, "type");
|
const char* requestedType = obs_data_get_string(req->data, "type");
|
||||||
if (requestedType != nullptr && strcmp(requestedType, serviceType) != 0) {
|
if (requestedType != nullptr && strcmp(requestedType, serviceType) != 0) {
|
||||||
@ -1316,27 +1414,27 @@ void WSRequestHandler::HandleSetStreamSettings(WSRequestHandler* req) {
|
|||||||
//if type isn't changing we should overlay the settings we got with the existing settings
|
//if type isn't changing we should overlay the settings we got with the existing settings
|
||||||
obs_data_t* existingSettings = obs_service_get_settings(service);
|
obs_data_t* existingSettings = obs_service_get_settings(service);
|
||||||
//by doing this you can send a request to the websocket that only contains a setting you want to change instead of having to do a get and then change them
|
//by doing this you can send a request to the websocket that only contains a setting you want to change instead of having to do a get and then change them
|
||||||
obs_data_t* newSettings = obs_data_create();
|
obs_data_t* newSettings = obs_data_create();
|
||||||
|
|
||||||
obs_data_apply(newSettings, existingSettings); //first apply the existing settings
|
obs_data_apply(newSettings, existingSettings); //first apply the existing settings
|
||||||
obs_data_apply(newSettings, settings); //then apply the settings from the request
|
obs_data_apply(newSettings, settings); //then apply the settings from the request
|
||||||
|
|
||||||
obs_data_release(settings);
|
obs_data_release(settings);
|
||||||
obs_data_release(existingSettings);
|
obs_data_release(existingSettings);
|
||||||
|
|
||||||
obs_service_update(service, settings);
|
obs_service_update(service, settings);
|
||||||
settings = newSettings;
|
settings = newSettings;
|
||||||
}
|
}
|
||||||
|
|
||||||
//if save is specified we should immediately save the streaming service
|
//if save is specified we should immediately save the streaming service
|
||||||
if (obs_data_get_bool(req->data, "save")) {
|
if (obs_data_get_bool(req->data, "save")) {
|
||||||
obs_frontend_save_streaming_service();
|
obs_frontend_save_streaming_service();
|
||||||
}
|
}
|
||||||
|
|
||||||
obs_data_t* response = obs_data_create();
|
obs_data_t* response = obs_data_create();
|
||||||
obs_data_set_string(response, "type", requestedType);
|
obs_data_set_string(response, "type", requestedType);
|
||||||
obs_data_set_obj(response, "settings", settings);
|
obs_data_set_obj(response, "settings", settings);
|
||||||
|
|
||||||
req->SendOKResponse(response);
|
req->SendOKResponse(response);
|
||||||
obs_data_release(settings);
|
obs_data_release(settings);
|
||||||
obs_data_release(response);
|
obs_data_release(response);
|
||||||
@ -1361,11 +1459,11 @@ void WSRequestHandler::HandleGetStreamSettings(WSRequestHandler* req) {
|
|||||||
obs_service_t* service = obs_frontend_get_streaming_service();
|
obs_service_t* service = obs_frontend_get_streaming_service();
|
||||||
const char* serviceType = obs_service_get_type(service);
|
const char* serviceType = obs_service_get_type(service);
|
||||||
obs_data_t* settings = obs_service_get_settings(service);
|
obs_data_t* settings = obs_service_get_settings(service);
|
||||||
|
|
||||||
obs_data_t* response = obs_data_create();
|
obs_data_t* response = obs_data_create();
|
||||||
obs_data_set_string(response, "type", serviceType);
|
obs_data_set_string(response, "type", serviceType);
|
||||||
obs_data_set_obj(response, "settings", settings);
|
obs_data_set_obj(response, "settings", settings);
|
||||||
|
|
||||||
req->SendOKResponse(response);
|
req->SendOKResponse(response);
|
||||||
obs_data_release(settings);
|
obs_data_release(settings);
|
||||||
obs_data_release(response);
|
obs_data_release(response);
|
||||||
@ -1638,7 +1736,7 @@ void WSRequestHandler::HandleSetRecordingFolder(WSRequestHandler* req) {
|
|||||||
/**
|
/**
|
||||||
* Get the path of the current recording folder.
|
* Get the path of the current recording folder.
|
||||||
*
|
*
|
||||||
* @return {Stsring} `rec-folder` Path of the recording folder.
|
* @return {String} `rec-folder` Path of the recording folder.
|
||||||
*
|
*
|
||||||
* @api requests
|
* @api requests
|
||||||
* @name GetRecordingFolder
|
* @name GetRecordingFolder
|
||||||
@ -1799,37 +1897,37 @@ void WSRequestHandler::HandleSetTextGDIPlusProperties(WSRequestHandler* req) {
|
|||||||
obs_data_t* settings = obs_source_get_settings(sceneItemSource);
|
obs_data_t* settings = obs_source_get_settings(sceneItemSource);
|
||||||
|
|
||||||
if (req->hasField("align")) {
|
if (req->hasField("align")) {
|
||||||
obs_data_set_string(settings, "align",
|
obs_data_set_string(settings, "align",
|
||||||
obs_data_get_string(req->data, "align"));
|
obs_data_get_string(req->data, "align"));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (req->hasField("bk_color")) {
|
if (req->hasField("bk_color")) {
|
||||||
obs_data_set_int(settings, "bk_color",
|
obs_data_set_int(settings, "bk_color",
|
||||||
obs_data_get_int(req->data, "bk_color"));
|
obs_data_get_int(req->data, "bk_color"));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (req->hasField("bk-opacity")) {
|
if (req->hasField("bk-opacity")) {
|
||||||
obs_data_set_int(settings, "bk_opacity",
|
obs_data_set_int(settings, "bk_opacity",
|
||||||
obs_data_get_int(req->data, "bk_opacity"));
|
obs_data_get_int(req->data, "bk_opacity"));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (req->hasField("chatlog")) {
|
if (req->hasField("chatlog")) {
|
||||||
obs_data_set_bool(settings, "chatlog",
|
obs_data_set_bool(settings, "chatlog",
|
||||||
obs_data_get_bool(req->data, "chatlog"));
|
obs_data_get_bool(req->data, "chatlog"));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (req->hasField("chatlog_lines")) {
|
if (req->hasField("chatlog_lines")) {
|
||||||
obs_data_set_int(settings, "chatlog_lines",
|
obs_data_set_int(settings, "chatlog_lines",
|
||||||
obs_data_get_int(req->data, "chatlog_lines"));
|
obs_data_get_int(req->data, "chatlog_lines"));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (req->hasField("color")) {
|
if (req->hasField("color")) {
|
||||||
obs_data_set_int(settings, "color",
|
obs_data_set_int(settings, "color",
|
||||||
obs_data_get_int(req->data, "color"));
|
obs_data_get_int(req->data, "color"));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (req->hasField("extents")) {
|
if (req->hasField("extents")) {
|
||||||
obs_data_set_bool(settings, "extents",
|
obs_data_set_bool(settings, "extents",
|
||||||
obs_data_get_bool(req->data, "extents"));
|
obs_data_get_bool(req->data, "extents"));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1849,7 +1947,7 @@ void WSRequestHandler::HandleSetTextGDIPlusProperties(WSRequestHandler* req) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (req->hasField("file")) {
|
if (req->hasField("file")) {
|
||||||
obs_data_set_string(settings, "file",
|
obs_data_set_string(settings, "file",
|
||||||
obs_data_get_string(req->data, "file"));
|
obs_data_get_string(req->data, "file"));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1869,7 +1967,7 @@ void WSRequestHandler::HandleSetTextGDIPlusProperties(WSRequestHandler* req) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (obs_data_has_user_value(req_font_obj, "size")) {
|
if (obs_data_has_user_value(req_font_obj, "size")) {
|
||||||
obs_data_set_int(font_obj, "size",
|
obs_data_set_int(font_obj, "size",
|
||||||
obs_data_get_int(req_font_obj, "size"));
|
obs_data_get_int(req_font_obj, "size"));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1884,7 +1982,7 @@ void WSRequestHandler::HandleSetTextGDIPlusProperties(WSRequestHandler* req) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (req->hasField("gradient")) {
|
if (req->hasField("gradient")) {
|
||||||
obs_data_set_bool(settings, "gradient",
|
obs_data_set_bool(settings, "gradient",
|
||||||
obs_data_get_bool(req->data, "gradient"));
|
obs_data_get_bool(req->data, "gradient"));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1904,7 +2002,7 @@ void WSRequestHandler::HandleSetTextGDIPlusProperties(WSRequestHandler* req) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (req->hasField("outline")) {
|
if (req->hasField("outline")) {
|
||||||
obs_data_set_bool(settings, "outline",
|
obs_data_set_bool(settings, "outline",
|
||||||
obs_data_get_bool(req->data, "outline"));
|
obs_data_get_bool(req->data, "outline"));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1919,34 +2017,34 @@ void WSRequestHandler::HandleSetTextGDIPlusProperties(WSRequestHandler* req) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (req->hasField("outline_opacity")) {
|
if (req->hasField("outline_opacity")) {
|
||||||
obs_data_set_int(settings, "outline_opacity",
|
obs_data_set_int(settings, "outline_opacity",
|
||||||
obs_data_get_int(req->data, "outline_opacity"));
|
obs_data_get_int(req->data, "outline_opacity"));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (req->hasField("read_from_file")) {
|
if (req->hasField("read_from_file")) {
|
||||||
obs_data_set_bool(settings, "read_from_file",
|
obs_data_set_bool(settings, "read_from_file",
|
||||||
obs_data_get_bool(req->data, "read_from_file"));
|
obs_data_get_bool(req->data, "read_from_file"));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (req->hasField("text")) {
|
if (req->hasField("text")) {
|
||||||
obs_data_set_string(settings, "text",
|
obs_data_set_string(settings, "text",
|
||||||
obs_data_get_string(req->data, "text"));
|
obs_data_get_string(req->data, "text"));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (req->hasField("valign")) {
|
if (req->hasField("valign")) {
|
||||||
obs_data_set_string(settings, "valign",
|
obs_data_set_string(settings, "valign",
|
||||||
obs_data_get_string(req->data, "valign"));
|
obs_data_get_string(req->data, "valign"));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (req->hasField("vertical")) {
|
if (req->hasField("vertical")) {
|
||||||
obs_data_set_bool(settings, "vertical",
|
obs_data_set_bool(settings, "vertical",
|
||||||
obs_data_get_bool(req->data, "vertical"));
|
obs_data_get_bool(req->data, "vertical"));
|
||||||
}
|
}
|
||||||
|
|
||||||
obs_source_update(sceneItemSource, settings);
|
obs_source_update(sceneItemSource, settings);
|
||||||
|
|
||||||
if (req->hasField("render")) {
|
if (req->hasField("render")) {
|
||||||
obs_sceneitem_set_visible(sceneItem,
|
obs_sceneitem_set_visible(sceneItem,
|
||||||
obs_data_get_bool(req->data, "render"));
|
obs_data_get_bool(req->data, "render"));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1959,7 +2057,7 @@ void WSRequestHandler::HandleSetTextGDIPlusProperties(WSRequestHandler* req) {
|
|||||||
} else {
|
} else {
|
||||||
req->SendErrorResponse("specified scene item doesn't exist");
|
req->SendErrorResponse("specified scene item doesn't exist");
|
||||||
}
|
}
|
||||||
|
|
||||||
obs_source_release(scene);
|
obs_source_release(scene);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2100,7 +2198,7 @@ void WSRequestHandler::HandleSetBrowserSourceProperties(WSRequestHandler* req) {
|
|||||||
obs_data_set_int(settings, "height",
|
obs_data_set_int(settings, "height",
|
||||||
obs_data_get_int(req->data, "height"));
|
obs_data_get_int(req->data, "height"));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (req->hasField("fps")) {
|
if (req->hasField("fps")) {
|
||||||
obs_data_set_int(settings, "fps",
|
obs_data_set_int(settings, "fps",
|
||||||
obs_data_get_int(req->data, "fps"));
|
obs_data_get_int(req->data, "fps"));
|
||||||
|
@ -71,6 +71,11 @@ class WSRequestHandler : public QObject {
|
|||||||
static void HandleStartRecording(WSRequestHandler* req);
|
static void HandleStartRecording(WSRequestHandler* req);
|
||||||
static void HandleStopRecording(WSRequestHandler* req);
|
static void HandleStopRecording(WSRequestHandler* req);
|
||||||
|
|
||||||
|
static void HandleStartStopReplayBuffer(WSRequestHandler* req);
|
||||||
|
static void HandleStartReplayBuffer(WSRequestHandler* req);
|
||||||
|
static void HandleStopReplayBuffer(WSRequestHandler* req);
|
||||||
|
static void HandleSaveReplayBuffer(WSRequestHandler* req);
|
||||||
|
|
||||||
static void HandleSetRecordingFolder(WSRequestHandler* req);
|
static void HandleSetRecordingFolder(WSRequestHandler* req);
|
||||||
static void HandleGetRecordingFolder(WSRequestHandler* req);
|
static void HandleGetRecordingFolder(WSRequestHandler* req);
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user