new request types for filter management

This commit is contained in:
Stéphane L 2018-05-27 19:22:10 +02:00
parent 03f1035690
commit 953f07f21f
3 changed files with 325 additions and 0 deletions

View File

@ -82,6 +82,13 @@ QHash<QString, void(*)(WSRequestHandler*)> WSRequestHandler::messageMap {
{ "GetSourceSettings", WSRequestHandler::HandleGetSourceSettings },
{ "SetSourceSettings", WSRequestHandler::HandleSetSourceSettings },
{ "GetSourceFilters", WSRequestHandler::HandleGetSourceFilters },
{ "AddFilterToSource", WSRequestHandler::HandleAddFilterToSource },
{ "RemoveFilterFromSource", WSRequestHandler::HandleRemoveFilterFromSource },
{ "ReorderSourceFilter", WSRequestHandler::HandleReorderSourceFilter },
{ "MoveSourceFilter", WSRequestHandler::HandleMoveSourceFilter },
{ "SetSourceFilterSettings", WSRequestHandler::HandleSetSourceFilterSettings },
{ "SetCurrentSceneCollection", WSRequestHandler::HandleSetCurrentSceneCollection },
{ "GetCurrentSceneCollection", WSRequestHandler::HandleGetCurrentSceneCollection },
{ "ListSceneCollections", WSRequestHandler::HandleListSceneCollections },

View File

@ -107,6 +107,13 @@ class WSRequestHandler : public QObject {
static void HandleGetSourceSettings(WSRequestHandler* req);
static void HandleSetSourceSettings(WSRequestHandler* req);
static void HandleGetSourceFilters(WSRequestHandler* req);
static void HandleAddFilterToSource(WSRequestHandler* req);
static void HandleRemoveFilterFromSource(WSRequestHandler* req);
static void HandleReorderSourceFilter(WSRequestHandler* req);
static void HandleMoveSourceFilter(WSRequestHandler* req);
static void HandleSetSourceFilterSettings(WSRequestHandler* req);
static void HandleSetCurrentSceneCollection(WSRequestHandler* req);
static void HandleGetCurrentSceneCollection(WSRequestHandler* req);
static void HandleListSceneCollections(WSRequestHandler* req);

View File

@ -1001,3 +1001,314 @@ void WSRequestHandler::HandleSetBrowserSourceProperties(WSRequestHandler* req) {
req->SendOKResponse(response);
}
/**
* List filters applied to a source
*
* @param {String} `sourceName` Source name
*
* @return {Array of Objects} `filters` List of filters for the specified source
* @return {String} `filters.*.type` Filter type
* @return {String} `filters.*.name` Filter name
* @return {Object} `filters.*.settings` Filter settings
*
* @api requests
* @name GetSourceFilters
* @category sources
* @since unreleased
*/
void WSRequestHandler::HandleGetSourceFilters(WSRequestHandler* req)
{
if (!req->hasField("sourceName")) {
req->SendErrorResponse("missing request parameters");
return;
}
const char* sourceName = obs_data_get_string(req->data, "sourceName");
OBSSourceAutoRelease source = obs_get_source_by_name(sourceName);
if (!source) {
req->SendErrorResponse("specified source doesn't exist");
return;
}
OBSDataArrayAutoRelease filters = obs_data_array_create();
obs_source_enum_filters(source, [](obs_source_t *parent, obs_source_t *child, void *param)
{
OBSDataAutoRelease filter = obs_data_create();
obs_data_set_string(filter, "type", obs_source_get_id(child));
obs_data_set_string(filter, "name", obs_source_get_name(child));
obs_data_set_obj(filter, "settings", obs_source_get_settings(child));
obs_data_array_push_back((obs_data_array_t*)param, filter);
}, filters);
OBSDataAutoRelease response = obs_data_create();
obs_data_set_array(response, "filters", filters);
req->SendOKResponse(response);
}
/**
* Add a new filter to a source. Available source types along with their settings properties are available from `GetSourceTypesList`.
*
* @param {String} `sourceName` Name of the source on which the filter is added
* @param {String} `filterName` Name of the new filter
* @param {String} `filterType` Filter type
* @param {Object} `filterSettings` Filter settings
*
* @api requests
* @name AddFilterToSource
* @category sources
* @since unreleased
*/
void WSRequestHandler::HandleAddFilterToSource(WSRequestHandler* req)
{
if (!req->hasField("sourceName") || !req->hasField("filterName") ||
!req->hasField("filterType") || !req->hasField("filterSettings"))
{
req->SendErrorResponse("missing request parameters");
return;
}
const char* sourceName = obs_data_get_string(req->data, "sourceName");
const char* filterName = obs_data_get_string(req->data, "filterName");
const char* filterType = obs_data_get_string(req->data, "filterType");
OBSDataAutoRelease filterSettings = obs_data_get_obj(req->data, "filterSettings");
OBSSourceAutoRelease source = obs_get_source_by_name(sourceName);
if (!source) {
req->SendErrorResponse("specified source doesn't exist");
return;
}
OBSSourceAutoRelease existingFilter = obs_source_get_filter_by_name(source, filterName);
if (existingFilter) {
req->SendErrorResponse("filter name already taken");
return;
}
OBSSourceAutoRelease filter = obs_source_create_private(filterType, filterName, filterSettings);
if (!filter) {
req->SendErrorResponse("filter creation failed");
return;
}
if (obs_source_get_type(filter) != OBS_SOURCE_TYPE_FILTER) {
req->SendErrorResponse("invalid filter type");
return;
}
obs_source_filter_add(source, filter);
req->SendOKResponse();
}
/**
* Remove a filter from a source
*
* @param {String} `sourceName` Name of the source from which the specified filter is removed
* @param {String} `filterName` Name of the filter to remove
*
* @api requests
* @name RemoveFilterFromSource
* @category sources
* @since unreleased
*/
void WSRequestHandler::HandleRemoveFilterFromSource(WSRequestHandler* req)
{
if (!req->hasField("sourceName") || !req->hasField("filterName")) {
req->SendErrorResponse("missing request parameters");
return;
}
const char* sourceName = obs_data_get_string(req->data, "sourceName");
const char* filterName = obs_data_get_string(req->data, "filterName");
OBSSourceAutoRelease source = obs_get_source_by_name(sourceName);
if (!source) {
req->SendErrorResponse("specified source doesn't exist");
return;
}
OBSSourceAutoRelease filter = obs_source_get_filter_by_name(source, filterName);
if (!filter) {
req->SendErrorResponse("specified filter doesn't exist");
}
obs_source_filter_remove(source, filter);
req->SendOKResponse();
}
/**
* Move a filter in the chain (absolute index positioning)
*
* @param {String} `sourceName` Name of the source to which the filter belongs
* @param {String} `filterName` Name of the filter to reorder
* @param {Integer} `newIndex` Desired position of the filter in the chain
*
* @api requests
* @name ReorderSourceFilter
* @category sources
* @since unreleased
*/
void WSRequestHandler::HandleReorderSourceFilter(WSRequestHandler* req)
{
if (!req->hasField("sourceName") || !req->hasField("filterName") || !req->hasField("newIndex")) {
req->SendErrorResponse("missing request parameters");
return;
}
const char* sourceName = obs_data_get_string(req->data, "sourceName");
const char* filterName = obs_data_get_string(req->data, "filterName");
int newIndex = obs_data_get_int(req->data, "newIndex");
if (newIndex < 0) {
req->SendErrorResponse("invalid index");
return;
}
OBSSourceAutoRelease source = obs_get_source_by_name(sourceName);
if (!source) {
req->SendErrorResponse("specified source doesn't exist");
return;
}
OBSSourceAutoRelease filter = obs_source_get_filter_by_name(source, filterName);
if (!filter) {
req->SendErrorResponse("specified filter doesn't exist");
}
struct filterSearch {
int i;
int filterIndex;
obs_source_t* filter;
};
struct filterSearch ctx = { 0, 0, filter };
obs_source_enum_filters(source, [](obs_source_t *parent, obs_source_t *child, void *param)
{
struct filterSearch* ctx = (struct filterSearch*)param;
if (child == ctx->filter) {
ctx->filterIndex = ctx->i;
}
ctx->i++;
}, &ctx);
int lastFilterIndex = ctx.i + 1;
if (newIndex > lastFilterIndex) {
req->SendErrorResponse("index out of bounds");
return;
}
int currentIndex = ctx.filterIndex;
if (newIndex > currentIndex) {
int downSteps = newIndex - currentIndex;
for (int i = 0; i < downSteps; i++) {
obs_source_filter_set_order(source, filter, OBS_ORDER_MOVE_DOWN);
}
}
else if (newIndex < currentIndex) {
int upSteps = currentIndex - newIndex;
for (int i = 0; i < upSteps; i++) {
obs_source_filter_set_order(source, filter, OBS_ORDER_MOVE_UP);
}
}
req->SendOKResponse();
}
/**
* Move a filter in the chain (relative positioning)
*
* @param {String} `sourceName` Name of the source to which the filter belongs
* @param {String} `filterName` Name of the filter to reorder
* @param {String} `movementType` How to move the filter around in the source's filter chain. Either "up", "down", "top" or "bottom".
*
* @api requests
* @name MoveSourceFilter
* @category sources
* @since unreleased
*/
void WSRequestHandler::HandleMoveSourceFilter(WSRequestHandler* req)
{
if (!req->hasField("sourceName") || !req->hasField("filterName") || !req->hasField("movementType")) {
req->SendErrorResponse("missing request parameters");
return;
}
const char* sourceName = obs_data_get_string(req->data, "sourceName");
const char* filterName = obs_data_get_string(req->data, "filterName");
QString movementType(obs_data_get_string(req->data, "movementType"));
OBSSourceAutoRelease source = obs_get_source_by_name(sourceName);
if (!source) {
req->SendErrorResponse("specified source doesn't exist");
return;
}
OBSSourceAutoRelease filter = obs_source_get_filter_by_name(source, filterName);
if (!filter) {
req->SendErrorResponse("specified filter doesn't exist");
}
obs_order_movement movement;
if (movementType == "up") {
movement = OBS_ORDER_MOVE_UP;
}
else if (movementType == "down") {
movement = OBS_ORDER_MOVE_DOWN;
}
else if (movementType == "top") {
movement = OBS_ORDER_MOVE_TOP;
}
else if (movementType == "bottom") {
movement = OBS_ORDER_MOVE_BOTTOM;
}
else {
req->SendErrorResponse("invalid value for movementType: must be either 'up', 'down', 'top' or 'bottom'.");
return;
}
obs_source_filter_set_order(source, filter, movement);
req->SendOKResponse();
}
/**
* Update settings of a filter
*
* @param {String} `sourceName` Name of the source to which the filter belongs
* @param {String} `filterName` Name of the filter to reconfigure
* @param {Object} `filterSettings` New settings. These will be merged to the current filter settings.
*
* @api requests
* @name SetSourceFilterSettings
* @category sources
* @since unreleased
*/
void WSRequestHandler::HandleSetSourceFilterSettings(WSRequestHandler* req)
{
if (!req->hasField("sourceName") || !req->hasField("filterName") || !req->hasField("filterSettings")) {
req->SendErrorResponse("missing request parameters");
return;
}
const char* sourceName = obs_data_get_string(req->data, "sourceName");
const char* filterName = obs_data_get_string(req->data, "filterName");
OBSDataAutoRelease newFilterSettings = obs_data_get_obj(req->data, "filterSettings");
OBSSourceAutoRelease source = obs_get_source_by_name(sourceName);
if (!source) {
req->SendErrorResponse("specified source doesn't exist");
return;
}
OBSSourceAutoRelease filter = obs_source_get_filter_by_name(source, filterName);
if (!filter) {
req->SendErrorResponse("specified filter doesn't exist");
}
OBSDataAutoRelease settings = obs_source_get_settings(filter);
obs_data_apply(settings, newFilterSettings);
obs_source_update(filter, settings);
req->SendOKResponse();
}