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_Scenes.cpp
|
||||
src/requesthandler/RequestHandler_Inputs.cpp
|
||||
src/requesthandler/RequestHandler_Stream.cpp
|
||||
src/requesthandler/rpc/Request.cpp
|
||||
src/requesthandler/rpc/RequestResult.cpp
|
||||
src/forms/SettingsDialog.cpp
|
||||
|
@ -22,6 +22,8 @@ const std::map<std::string, RequestMethodHandler> RequestHandler::_handlerMap
|
||||
{"SetProfileParameter", &RequestHandler::SetProfileParameter},
|
||||
{"GetVideoSettings", &RequestHandler::GetVideoSettings},
|
||||
{"SetVideoSettings", &RequestHandler::SetVideoSettings},
|
||||
{"GetStreamServiceSettings", &RequestHandler::GetStreamServiceSettings},
|
||||
{"SetStreamServiceSettings", &RequestHandler::SetStreamServiceSettings},
|
||||
|
||||
// Sources
|
||||
{"GetSourceActive", &RequestHandler::GetSourceActive},
|
||||
@ -51,6 +53,11 @@ const std::map<std::string, RequestMethodHandler> RequestHandler::_handlerMap
|
||||
{"SetInputVolume", &RequestHandler::SetInputVolume},
|
||||
{"SetInputName", &RequestHandler::SetInputName},
|
||||
{"CreateInput", &RequestHandler::CreateInput},
|
||||
|
||||
// Stream
|
||||
{"GetStreamStatus", &RequestHandler::GetStreamStatus},
|
||||
{"StartStream", &RequestHandler::StartStream},
|
||||
{"StopStream", &RequestHandler::StopStream},
|
||||
};
|
||||
|
||||
RequestResult RequestHandler::ProcessRequest(const Request& request)
|
||||
|
@ -37,6 +37,8 @@ class RequestHandler {
|
||||
RequestResult SetProfileParameter(const Request&);
|
||||
RequestResult GetVideoSettings(const Request&);
|
||||
RequestResult SetVideoSettings(const Request&);
|
||||
RequestResult GetStreamServiceSettings(const Request&);
|
||||
RequestResult SetStreamServiceSettings(const Request&);
|
||||
|
||||
// Sources
|
||||
RequestResult GetSourceActive(const Request&);
|
||||
@ -67,5 +69,10 @@ class RequestHandler {
|
||||
RequestResult SetInputName(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;
|
||||
};
|
||||
|
@ -175,3 +175,55 @@ RequestResult RequestHandler::SetVideoSettings(const Request& request)
|
||||
|
||||
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,
|
||||
// The combination of request parameters cannot be used to perform an action
|
||||
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 <util/util_uint64.h>
|
||||
|
||||
#include "Utils.h"
|
||||
#include "../obs-websocket.h"
|
||||
@ -6,6 +11,17 @@
|
||||
|
||||
#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> ret;
|
||||
@ -107,6 +123,40 @@ std::string Utils::Obs::StringHelper::GetLastReplayBufferFilePath()
|
||||
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()
|
||||
{
|
||||
char** sceneCollections = obs_frontend_get_scene_collections();
|
||||
|
@ -38,6 +38,11 @@ namespace Utils {
|
||||
std::string GetInputMonitorTypeString(obs_source_t *input);
|
||||
std::string GetMediaInputStateString(obs_source_t *input);
|
||||
std::string GetLastReplayBufferFilePath();
|
||||
std::string GetOutputTimecodeString(obs_output_t *output);
|
||||
}
|
||||
|
||||
namespace NumberHelper {
|
||||
uint64_t GetOutputDuration(obs_output_t *output);
|
||||
}
|
||||
|
||||
namespace ListHelper {
|
||||
|
Loading…
Reference in New Issue
Block a user