mirror of
https://github.com/Palakis/obs-websocket.git
synced 2024-08-30 18:12:16 +00:00
Requests: Add more requests
- GetStreamServiceSettings - SetStreamServiceSettings - CreateInput - GetStreamStatus - StartStream - StopStream
This commit is contained in:
parent
4d271da541
commit
d0e05ae45c
@ -91,6 +91,7 @@ set(obs-websocket_SOURCES
|
|||||||
src/requesthandler/RequestHandler_Sources.cpp
|
src/requesthandler/RequestHandler_Sources.cpp
|
||||||
src/requesthandler/RequestHandler_Scenes.cpp
|
src/requesthandler/RequestHandler_Scenes.cpp
|
||||||
src/requesthandler/RequestHandler_Inputs.cpp
|
src/requesthandler/RequestHandler_Inputs.cpp
|
||||||
|
src/requesthandler/RequestHandler_Stream.cpp
|
||||||
src/requesthandler/rpc/Request.cpp
|
src/requesthandler/rpc/Request.cpp
|
||||||
src/requesthandler/rpc/RequestResult.cpp
|
src/requesthandler/rpc/RequestResult.cpp
|
||||||
src/forms/SettingsDialog.cpp
|
src/forms/SettingsDialog.cpp
|
||||||
|
@ -22,6 +22,8 @@ const std::map<std::string, RequestMethodHandler> RequestHandler::_handlerMap
|
|||||||
{"SetProfileParameter", &RequestHandler::SetProfileParameter},
|
{"SetProfileParameter", &RequestHandler::SetProfileParameter},
|
||||||
{"GetVideoSettings", &RequestHandler::GetVideoSettings},
|
{"GetVideoSettings", &RequestHandler::GetVideoSettings},
|
||||||
{"SetVideoSettings", &RequestHandler::SetVideoSettings},
|
{"SetVideoSettings", &RequestHandler::SetVideoSettings},
|
||||||
|
{"GetStreamServiceSettings", &RequestHandler::GetStreamServiceSettings},
|
||||||
|
{"SetStreamServiceSettings", &RequestHandler::SetStreamServiceSettings},
|
||||||
|
|
||||||
// Sources
|
// Sources
|
||||||
{"GetSourceActive", &RequestHandler::GetSourceActive},
|
{"GetSourceActive", &RequestHandler::GetSourceActive},
|
||||||
@ -51,6 +53,11 @@ const std::map<std::string, RequestMethodHandler> RequestHandler::_handlerMap
|
|||||||
{"SetInputVolume", &RequestHandler::SetInputVolume},
|
{"SetInputVolume", &RequestHandler::SetInputVolume},
|
||||||
{"SetInputName", &RequestHandler::SetInputName},
|
{"SetInputName", &RequestHandler::SetInputName},
|
||||||
{"CreateInput", &RequestHandler::CreateInput},
|
{"CreateInput", &RequestHandler::CreateInput},
|
||||||
|
|
||||||
|
// Stream
|
||||||
|
{"GetStreamStatus", &RequestHandler::GetStreamStatus},
|
||||||
|
{"StartStream", &RequestHandler::StartStream},
|
||||||
|
{"StopStream", &RequestHandler::StopStream},
|
||||||
};
|
};
|
||||||
|
|
||||||
RequestResult RequestHandler::ProcessRequest(const Request& request)
|
RequestResult RequestHandler::ProcessRequest(const Request& request)
|
||||||
|
@ -37,6 +37,8 @@ class RequestHandler {
|
|||||||
RequestResult SetProfileParameter(const Request&);
|
RequestResult SetProfileParameter(const Request&);
|
||||||
RequestResult GetVideoSettings(const Request&);
|
RequestResult GetVideoSettings(const Request&);
|
||||||
RequestResult SetVideoSettings(const Request&);
|
RequestResult SetVideoSettings(const Request&);
|
||||||
|
RequestResult GetStreamServiceSettings(const Request&);
|
||||||
|
RequestResult SetStreamServiceSettings(const Request&);
|
||||||
|
|
||||||
// Sources
|
// Sources
|
||||||
RequestResult GetSourceActive(const Request&);
|
RequestResult GetSourceActive(const Request&);
|
||||||
@ -67,5 +69,10 @@ class RequestHandler {
|
|||||||
RequestResult SetInputName(const Request&);
|
RequestResult SetInputName(const Request&);
|
||||||
RequestResult CreateInput(const Request&);
|
RequestResult CreateInput(const Request&);
|
||||||
|
|
||||||
|
// Stream
|
||||||
|
RequestResult GetStreamStatus(const Request&);
|
||||||
|
RequestResult StartStream(const Request&);
|
||||||
|
RequestResult StopStream(const Request&);
|
||||||
|
|
||||||
static const std::map<std::string, RequestMethodHandler> _handlerMap;
|
static const std::map<std::string, RequestMethodHandler> _handlerMap;
|
||||||
};
|
};
|
||||||
|
@ -175,3 +175,55 @@ RequestResult RequestHandler::SetVideoSettings(const Request& request)
|
|||||||
|
|
||||||
return RequestResult::Error(RequestStatus::MissingRequestParameter, "You must specify at least one video-changing pair.");
|
return RequestResult::Error(RequestStatus::MissingRequestParameter, "You must specify at least one video-changing pair.");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
RequestResult RequestHandler::GetStreamServiceSettings(const Request& request)
|
||||||
|
{
|
||||||
|
json responseData;
|
||||||
|
|
||||||
|
OBSService service = obs_frontend_get_streaming_service();
|
||||||
|
responseData["streamServiceType"] = obs_service_get_type(service);
|
||||||
|
OBSDataAutoRelease serviceSettings = obs_service_get_settings(service);
|
||||||
|
responseData["streamServiceSettings"] = Utils::Json::ObsDataToJson(serviceSettings, true);
|
||||||
|
|
||||||
|
return RequestResult::Success(responseData);
|
||||||
|
}
|
||||||
|
|
||||||
|
RequestResult RequestHandler::SetStreamServiceSettings(const Request& request)
|
||||||
|
{
|
||||||
|
if (obs_frontend_streaming_active())
|
||||||
|
return RequestResult::Error(RequestStatus::StreamRunning);
|
||||||
|
|
||||||
|
RequestStatus::RequestStatus statusCode;
|
||||||
|
std::string comment;
|
||||||
|
if (!(request.ValidateString("streamServiceType", statusCode, comment) && request.ValidateObject("streamServiceSettings", statusCode, comment)))
|
||||||
|
return RequestResult::Error(statusCode, comment);
|
||||||
|
|
||||||
|
OBSService currentStreamService = obs_frontend_get_streaming_service();
|
||||||
|
|
||||||
|
std::string streamServiceType = obs_service_get_type(currentStreamService);
|
||||||
|
std::string requestedStreamServiceType = request.RequestData["streamServiceType"];
|
||||||
|
OBSDataAutoRelease requestedStreamServiceSettings = Utils::Json::JsonToObsData(request.RequestData["streamServiceSettings"]);
|
||||||
|
|
||||||
|
// Don't create a new service if the current service is the same type.
|
||||||
|
if (streamServiceType == requestedStreamServiceType) {
|
||||||
|
OBSDataAutoRelease currentStreamServiceSettings = obs_service_get_settings(currentStreamService);
|
||||||
|
|
||||||
|
OBSDataAutoRelease newStreamServiceSettings = obs_data_create();
|
||||||
|
obs_data_apply(newStreamServiceSettings, currentStreamServiceSettings);
|
||||||
|
obs_data_apply(newStreamServiceSettings, requestedStreamServiceSettings);
|
||||||
|
|
||||||
|
obs_service_update(currentStreamService, newStreamServiceSettings);
|
||||||
|
} else {
|
||||||
|
// TODO: This leaks memory. I have no idea why.
|
||||||
|
OBSService newStreamService = obs_service_create(requestedStreamServiceType.c_str(), "obs_websocket_custom_service", requestedStreamServiceSettings, NULL);
|
||||||
|
// TODO: Check service type here, instead of relying on service creation to fail.
|
||||||
|
if (!newStreamService)
|
||||||
|
return RequestResult::Error(RequestStatus::StreamServiceCreationFailed, "Creating the stream service with the requested streamServiceType failed. It may be an invalid type.");
|
||||||
|
|
||||||
|
obs_frontend_set_streaming_service(newStreamService);
|
||||||
|
}
|
||||||
|
|
||||||
|
obs_frontend_save_streaming_service();
|
||||||
|
|
||||||
|
return RequestResult::Success();
|
||||||
|
}
|
||||||
|
36
src/requesthandler/RequestHandler_Stream.cpp
Normal file
36
src/requesthandler/RequestHandler_Stream.cpp
Normal file
@ -0,0 +1,36 @@
|
|||||||
|
#include "RequestHandler.h"
|
||||||
|
#include "../plugin-macros.generated.h"
|
||||||
|
|
||||||
|
RequestResult RequestHandler::GetStreamStatus(const Request& request)
|
||||||
|
{
|
||||||
|
json responseData;
|
||||||
|
|
||||||
|
OBSOutputAutoRelease streamOutput = obs_frontend_get_streaming_output();
|
||||||
|
responseData["outputActive"] = obs_output_active(streamOutput);
|
||||||
|
responseData["outputTimecode"] = Utils::Obs::StringHelper::GetOutputTimecodeString(streamOutput);
|
||||||
|
responseData["outputDuration"] = Utils::Obs::NumberHelper::GetOutputDuration(streamOutput);
|
||||||
|
|
||||||
|
return RequestResult::Success(responseData);
|
||||||
|
}
|
||||||
|
|
||||||
|
RequestResult RequestHandler::StartStream(const Request& request)
|
||||||
|
{
|
||||||
|
if (obs_frontend_streaming_active())
|
||||||
|
return RequestResult::Error(RequestStatus::StreamRunning);
|
||||||
|
|
||||||
|
// TODO: Call signal directly to perform blocking wait
|
||||||
|
obs_frontend_streaming_start();
|
||||||
|
|
||||||
|
return RequestResult::Success();
|
||||||
|
}
|
||||||
|
|
||||||
|
RequestResult RequestHandler::StopStream(const Request& request)
|
||||||
|
{
|
||||||
|
if (!obs_frontend_streaming_active())
|
||||||
|
return RequestResult::Error(RequestStatus::StreamNotRunning);
|
||||||
|
|
||||||
|
// TODO: Call signal directly to perform blocking wait
|
||||||
|
obs_frontend_streaming_stop();
|
||||||
|
|
||||||
|
return RequestResult::Success();
|
||||||
|
}
|
@ -118,5 +118,7 @@ namespace RequestStatus {
|
|||||||
DirectoryCreationFailed = 706,
|
DirectoryCreationFailed = 706,
|
||||||
// The combination of request parameters cannot be used to perform an action
|
// The combination of request parameters cannot be used to perform an action
|
||||||
CannotAct = 707,
|
CannotAct = 707,
|
||||||
|
// Creation of a new stream service failed
|
||||||
|
StreamServiceCreationFailed = 708,
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
@ -1,4 +1,9 @@
|
|||||||
|
#include <inttypes.h>
|
||||||
|
#include <memory>
|
||||||
|
#include <string>
|
||||||
|
#include <stdexcept>
|
||||||
#include <obs-frontend-api.h>
|
#include <obs-frontend-api.h>
|
||||||
|
#include <util/util_uint64.h>
|
||||||
|
|
||||||
#include "Utils.h"
|
#include "Utils.h"
|
||||||
#include "../obs-websocket.h"
|
#include "../obs-websocket.h"
|
||||||
@ -6,6 +11,17 @@
|
|||||||
|
|
||||||
#define CASE(x) case x: return #x;
|
#define CASE(x) case x: return #x;
|
||||||
|
|
||||||
|
template<typename ... Args>
|
||||||
|
std::string string_format( const std::string& format, Args ... args )
|
||||||
|
{
|
||||||
|
int size_s = std::snprintf( nullptr, 0, format.c_str(), args ... ) + 1;
|
||||||
|
if( size_s <= 0 ){ throw std::runtime_error( "Error during formatting." ); }
|
||||||
|
auto size = static_cast<size_t>( size_s );
|
||||||
|
auto buf = std::make_unique<char[]>( size );
|
||||||
|
std::snprintf( buf.get(), size, format.c_str(), args ... );
|
||||||
|
return std::string( buf.get(), buf.get() + size - 1 ); // We don't want the '\0' inside
|
||||||
|
}
|
||||||
|
|
||||||
std::vector<std::string> ConvertStringArray(char **array)
|
std::vector<std::string> ConvertStringArray(char **array)
|
||||||
{
|
{
|
||||||
std::vector<std::string> ret;
|
std::vector<std::string> ret;
|
||||||
@ -107,6 +123,40 @@ std::string Utils::Obs::StringHelper::GetLastReplayBufferFilePath()
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::string Utils::Obs::StringHelper::GetOutputTimecodeString(obs_output_t *output)
|
||||||
|
{
|
||||||
|
if (!output || !obs_output_active(output))
|
||||||
|
return "00:00:00.000";
|
||||||
|
|
||||||
|
video_t* video = obs_output_video(output);
|
||||||
|
uint64_t frameTimeNs = video_output_get_frame_time(video);
|
||||||
|
int totalFrames = obs_output_get_total_frames(output);
|
||||||
|
|
||||||
|
uint64_t ms = (((uint64_t)totalFrames) * frameTimeNs) / 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 string_format("%02" PRIu64 ":%02" PRIu64 ":%02" PRIu64 ".%03" PRIu64, hoursPart, minutesPart, secsPart, msPart);
|
||||||
|
}
|
||||||
|
|
||||||
|
uint64_t Utils::Obs::NumberHelper::GetOutputDuration(obs_output_t *output)
|
||||||
|
{
|
||||||
|
if (!output || !obs_output_active(output))
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
video_t* video = obs_output_video(output);
|
||||||
|
uint64_t frameTimeNs = video_output_get_frame_time(video);
|
||||||
|
int totalFrames = obs_output_get_total_frames(output);
|
||||||
|
|
||||||
|
return util_mul_div64(totalFrames, frameTimeNs, 1000000ULL);
|
||||||
|
//return (((uint64_t)totalFrames) * frameTimeNs) / ;
|
||||||
|
}
|
||||||
|
|
||||||
std::vector<std::string> Utils::Obs::ListHelper::GetSceneCollectionList()
|
std::vector<std::string> Utils::Obs::ListHelper::GetSceneCollectionList()
|
||||||
{
|
{
|
||||||
char** sceneCollections = obs_frontend_get_scene_collections();
|
char** sceneCollections = obs_frontend_get_scene_collections();
|
||||||
|
@ -38,6 +38,11 @@ namespace Utils {
|
|||||||
std::string GetInputMonitorTypeString(obs_source_t *input);
|
std::string GetInputMonitorTypeString(obs_source_t *input);
|
||||||
std::string GetMediaInputStateString(obs_source_t *input);
|
std::string GetMediaInputStateString(obs_source_t *input);
|
||||||
std::string GetLastReplayBufferFilePath();
|
std::string GetLastReplayBufferFilePath();
|
||||||
|
std::string GetOutputTimecodeString(obs_output_t *output);
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace NumberHelper {
|
||||||
|
uint64_t GetOutputDuration(obs_output_t *output);
|
||||||
}
|
}
|
||||||
|
|
||||||
namespace ListHelper {
|
namespace ListHelper {
|
||||||
|
Loading…
Reference in New Issue
Block a user