mirror of
https://github.com/Palakis/obs-websocket.git
synced 2024-08-30 18:12:16 +00:00
Merge pull request #851 from obs-websocket/event/changing_events
Put normal commits on this branch by accident dammit
This commit is contained in:
commit
061c228ad5
4
.github/pull_request_template.md
vendored
4
.github/pull_request_template.md
vendored
@ -1,6 +1,6 @@
|
||||
<!--- Please fill out the following template, which will help other contributors review your Pull Request. -->
|
||||
|
||||
<!--- Make sure you’ve read the contribution guidelines here: https://github.com/Palakis/obs-websocket/blob/master/CONTRIBUTING.md -->
|
||||
<!--- Make sure you’ve read the contribution guidelines here: https://github.com/obs-websocket/obs-websocket/blob/master/CONTRIBUTING.md -->
|
||||
|
||||
### Description
|
||||
<!--- Describe your changes. -->
|
||||
@ -27,7 +27,7 @@ Tested OS(s):
|
||||
### Checklist:
|
||||
<!--- Go over all the following points, and put an `x` in all the boxes that apply. -->
|
||||
<!--- If you're unsure about any of these, don't hesitate to ask. We're here to help! -->
|
||||
- [ ] I have read the [**contributing** document](https://github.com/Palakis/obs-websocket/blob/4.x-current/CONTRIBUTING.md).
|
||||
- [ ] I have read the [**contributing** document](https://github.com/obs-websocket/obs-websocket/blob/4.x-current/CONTRIBUTING.md).
|
||||
- [ ] My code is not on the master branch.
|
||||
- [ ] The code has been tested.
|
||||
- [ ] All commit messages are properly formatted and commits squashed where appropriate.
|
||||
|
@ -21,7 +21,7 @@ On Debian/Ubuntu :
|
||||
|
||||
```shell
|
||||
sudo apt-get install libboost-all-dev
|
||||
git clone --recursive https://github.com/Palakis/obs-websocket.git
|
||||
git clone --recursive https://github.com/obs-websocket/obs-websocket.git
|
||||
cd obs-websocket
|
||||
mkdir build && cd build
|
||||
cmake -DLIBOBS_INCLUDE_DIR="<path to the libobs sub-folder in obs-studio's source code>" -DCMAKE_INSTALL_PREFIX=/usr -DUSE_UBUNTU_FIX=true ..
|
||||
@ -51,7 +51,7 @@ Of course, you're encouraged to dig through the contents of these scripts to
|
||||
look for issues or specificities.
|
||||
|
||||
```shell
|
||||
git clone --recursive https://github.com/Palakis/obs-websocket.git
|
||||
git clone --recursive https://github.com/obs-websocket/obs-websocket.git
|
||||
cd obs-websocket
|
||||
./CI/install-dependencies-macos.sh
|
||||
./CI/install-build-obs-macos.sh
|
||||
@ -63,4 +63,4 @@ This will result in a ready-to-use `obs-websocket.pkg` installer in the `release
|
||||
|
||||
## Automated Builds
|
||||
|
||||

|
||||

|
||||
|
@ -108,6 +108,7 @@ set(obs-websocket_SOURCES
|
||||
src/requesthandler/RequestHandler_SceneItems.cpp
|
||||
src/requesthandler/RequestHandler_Stream.cpp
|
||||
src/requesthandler/RequestHandler_Record.cpp
|
||||
src/requesthandler/RequestHandler_MediaInputs.cpp
|
||||
src/requesthandler/rpc/Request.cpp
|
||||
src/requesthandler/rpc/RequestResult.cpp
|
||||
src/forms/SettingsDialog.cpp
|
||||
|
@ -29,21 +29,20 @@ These are required to automatically generate the [protocol specification documen
|
||||
|
||||
* Favor return-early code and avoid wrapping huge portions of code in conditionals. As an example, this:
|
||||
```cpp
|
||||
if (success) {
|
||||
if (success)
|
||||
return RequestResult::Success();
|
||||
} else {
|
||||
else
|
||||
return RequestResult::Error(RequestStatus::GenericError);
|
||||
}
|
||||
```
|
||||
is better like this:
|
||||
```cpp
|
||||
if (!success) {
|
||||
if (!success)
|
||||
return RequestResult::Error(RequestStatus::GenericError);
|
||||
}
|
||||
|
||||
return RequestResult::Success();
|
||||
```
|
||||
|
||||
* Try to use the [built-in](https://github.com/Palakis/obs-websocket/blob/master/src/requesthandler/rpc/Request.h) request checks when possible.
|
||||
* Try to use the [built-in](https://github.com/obs-websocket/obs-websocket/blob/master/src/requesthandler/rpc/Request.h) request checks when possible.
|
||||
* Refer to existing requests for usage examples.
|
||||
|
||||
* Some example common response/request property names are:
|
||||
@ -54,12 +53,14 @@ return RequestResult::Success();
|
||||
|
||||
* Response parameters which have no attributed data due to an invalid state should be set to `null` (versus being left out)
|
||||
* For example, when `GetSceneList` is called and OBS is not in studio mode, `currentPreviewSceneName` will be `null`
|
||||
* If a request's core response data depends on a state, an error should be thrown unless `ignoreNonFatalRequestChecks` is set. See `GetCurrentPreviewScene` as an example.
|
||||
* If a request's core response data depends on a state, an error should be thrown. See `GetCurrentPreviewScene` as an example.
|
||||
|
||||
* In general, try to match the style of existing code as best as possible. We try our best to keep a consistent code style, and may suggest nitpicks as necessary.
|
||||
|
||||
### Commit Guidelines
|
||||
|
||||
* Commits follow the 50/72 standard:
|
||||
* 50 characters max for the commit title (excluding scope name)
|
||||
* 50 characters suggested max for the commit title (absolute maximum 72 including scope)
|
||||
* One empty line after the title
|
||||
* Description wrapped to 72 columns max width per line.
|
||||
|
||||
|
@ -12,13 +12,13 @@
|
||||
|
||||
WebSockets API for OBS Studio.
|
||||
|
||||
[](https://github.com/Palakis/obs-websocket/actions/workflows/main.yml)
|
||||
[](https://github.com/obs-websocket/obs-websocket/actions/workflows/main.yml)
|
||||
[](https://discord.gg/WBaSQ3A)
|
||||
[](https://opencollective.com/obs-websocket)
|
||||
|
||||
## Downloads
|
||||
|
||||
Binaries for Windows, MacOS, and Linux are available in the [Releases](https://github.com/Palakis/obs-websocket/releases) section.
|
||||
Binaries for Windows, MacOS, and Linux are available in the [Releases](https://github.com/obs-websocket/obs-websocket/releases) section.
|
||||
|
||||
### Homebrew
|
||||
|
||||
@ -75,7 +75,7 @@ Please join the localization project on [Crowdin](https://crowdin.com/project/ob
|
||||
### Code Contributors
|
||||
|
||||
This project exists thanks to all the people who contribute. [Contribute](CONTRIBUTING.md).
|
||||
<a href="https://github.com/Palakis/obs-websocket/graphs/contributors"><img src="https://opencollective.com/obs-websocket/contributors.svg?width=890&button=false" /></a>
|
||||
<a href="https://github.com/obs-websocket/obs-websocket/graphs/contributors"><img src="https://opencollective.com/obs-websocket/contributors.svg?width=890&button=false" /></a>
|
||||
|
||||
### Financial Contributors
|
||||
|
||||
|
@ -1,7 +1,7 @@
|
||||
#define MyAppName "obs-websocket"
|
||||
#define MyAppVersion "@OBS_WEBSOCKET_VERSION@"
|
||||
#define MyAppPublisher "Stephane Lepin"
|
||||
#define MyAppURL "http://github.com/Palakis/obs-websocket"
|
||||
#define MyAppURL "http://github.com/obs-websocket/obs-websocket"
|
||||
|
||||
[Setup]
|
||||
; NOTE: The value of AppId uniquely identifies this application.
|
||||
|
@ -237,18 +237,18 @@ void EventHandler::OnFrontendEvent(enum obs_frontend_event event, void *private_
|
||||
break;
|
||||
|
||||
// Config
|
||||
//case OBS_FRONTEND_EVENT_SCENE_COLLECTION_CHANGING:
|
||||
// eventHandler->HandleCurrentSceneCollectionChanging();
|
||||
// break;
|
||||
case OBS_FRONTEND_EVENT_SCENE_COLLECTION_CHANGING:
|
||||
eventHandler->HandleCurrentSceneCollectionChanging();
|
||||
break;
|
||||
case OBS_FRONTEND_EVENT_SCENE_COLLECTION_CHANGED:
|
||||
eventHandler->HandleCurrentSceneCollectionChanged();
|
||||
break;
|
||||
case OBS_FRONTEND_EVENT_SCENE_COLLECTION_LIST_CHANGED:
|
||||
eventHandler->HandleSceneCollectionListChanged();
|
||||
break;
|
||||
//case OBS_FRONTEND_EVENT_PROFILE_CHANGING:
|
||||
// eventHandler->HandleCurrentProfileChanging();
|
||||
// break;
|
||||
case OBS_FRONTEND_EVENT_PROFILE_CHANGING:
|
||||
eventHandler->HandleCurrentProfileChanging();
|
||||
break;
|
||||
case OBS_FRONTEND_EVENT_PROFILE_CHANGED:
|
||||
eventHandler->HandleCurrentProfileChanged();
|
||||
break;
|
||||
|
@ -97,6 +97,12 @@ const std::map<std::string, RequestMethodHandler> RequestHandler::_handlerMap
|
||||
{"PauseRecord", &RequestHandler::PauseRecord},
|
||||
{"ResumeRecord", &RequestHandler::ResumeRecord},
|
||||
//{"GetRecordDirectory", &RequestHandler::GetRecordDirectory},
|
||||
|
||||
// Media Inputs
|
||||
{"GetMediaInputStatus", &RequestHandler::GetMediaInputStatus},
|
||||
{"SetMediaInputCursor", &RequestHandler::SetMediaInputCursor},
|
||||
{"OffsetMediaInputCursor", &RequestHandler::OffsetMediaInputCursor},
|
||||
{"TriggerMediaInputAction", &RequestHandler::TriggerMediaInputAction},
|
||||
};
|
||||
|
||||
RequestHandler::RequestHandler(SessionPtr session) :
|
||||
|
@ -119,6 +119,12 @@ class RequestHandler {
|
||||
RequestResult ResumeRecord(const Request&);
|
||||
RequestResult GetRecordDirectory(const Request&);
|
||||
|
||||
// Media Inputs
|
||||
RequestResult GetMediaInputStatus(const Request&);
|
||||
RequestResult SetMediaInputCursor(const Request&);
|
||||
RequestResult OffsetMediaInputCursor(const Request&);
|
||||
RequestResult TriggerMediaInputAction(const Request&);
|
||||
|
||||
SessionPtr _session;
|
||||
static const std::map<std::string, RequestMethodHandler> _handlerMap;
|
||||
};
|
||||
|
@ -23,10 +23,10 @@ RequestResult RequestHandler::GetPersistentData(const Request& request)
|
||||
|
||||
json responseData;
|
||||
json persistentData;
|
||||
if (!(Utils::Json::GetJsonFileContent(persistentDataPath, persistentData) && persistentData.contains(slotName)))
|
||||
responseData["slotValue"] = nullptr;
|
||||
else
|
||||
if (Utils::Json::GetJsonFileContent(persistentDataPath, persistentData) && persistentData.contains(slotName))
|
||||
responseData["slotValue"] = persistentData[slotName];
|
||||
else
|
||||
responseData["slotValue"] = nullptr;
|
||||
|
||||
return RequestResult::Success(responseData);
|
||||
}
|
||||
@ -347,7 +347,7 @@ RequestResult RequestHandler::SetStreamServiceSettings(const Request& request)
|
||||
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);
|
||||
OBSService newStreamService = obs_service_create(requestedStreamServiceType.c_str(), "obs_websocket_custom_service", requestedStreamServiceSettings, nullptr);
|
||||
// TODO: Check service type here, instead of relying on service creation to fail.
|
||||
if (!newStreamService)
|
||||
return RequestResult::Error(RequestStatus::ResourceCreationFailed, "Failed to create the stream service with the requested streamServiceType. It may be an invalid type.");
|
||||
|
@ -8,7 +8,7 @@
|
||||
RequestResult RequestHandler::GetVersion(const Request& request)
|
||||
{
|
||||
json responseData;
|
||||
responseData["obsVersion"] = Utils::Obs::StringHelper::GetObsVersionString();
|
||||
responseData["obsVersion"] = Utils::Obs::StringHelper::GetObsVersion();
|
||||
responseData["obsWebSocketVersion"] = OBS_WEBSOCKET_VERSION;
|
||||
responseData["rpcVersion"] = OBS_WEBSOCKET_RPC_VERSION;
|
||||
responseData["availableRequests"] = GetRequestList();
|
||||
|
@ -319,7 +319,7 @@ RequestResult RequestHandler::GetInputAudioMonitorType(const Request& request)
|
||||
return RequestResult::Error(statusCode, comment);
|
||||
|
||||
json responseData;
|
||||
responseData["monitorType"] = Utils::Obs::StringHelper::GetInputMonitorTypeString(input);
|
||||
responseData["monitorType"] = Utils::Obs::StringHelper::GetInputMonitorType(input);
|
||||
|
||||
return RequestResult::Success(responseData);
|
||||
}
|
||||
@ -365,6 +365,8 @@ std::vector<json> GetListPropertyItems(obs_property_t *property)
|
||||
itemData["itemValue"] = obs_property_list_item_float(property, i);
|
||||
} else if (itemFormat == OBS_COMBO_FORMAT_STRING) {
|
||||
itemData["itemValue"] = obs_property_list_item_string(property, i);
|
||||
} else {
|
||||
itemData["itemValue"] = nullptr;
|
||||
}
|
||||
ret.push_back(itemData);
|
||||
}
|
||||
|
110
src/requesthandler/RequestHandler_MediaInputs.cpp
Normal file
110
src/requesthandler/RequestHandler_MediaInputs.cpp
Normal file
@ -0,0 +1,110 @@
|
||||
#include "RequestHandler.h"
|
||||
|
||||
bool IsMediaTimeValid(obs_source_t *input)
|
||||
{
|
||||
auto mediaState = obs_source_media_get_state(input);
|
||||
return mediaState == OBS_MEDIA_STATE_PLAYING || mediaState == OBS_MEDIA_STATE_PAUSED;
|
||||
}
|
||||
|
||||
RequestResult RequestHandler::GetMediaInputStatus(const Request& request)
|
||||
{
|
||||
RequestStatus::RequestStatus statusCode;
|
||||
std::string comment;
|
||||
OBSSourceAutoRelease input = request.ValidateInput("inputName", statusCode, comment);
|
||||
if (!input)
|
||||
return RequestResult::Error(statusCode, comment);
|
||||
|
||||
json responseData;
|
||||
responseData["mediaState"] = Utils::Obs::StringHelper::GetMediaInputState(input);
|
||||
|
||||
if (IsMediaTimeValid(input)) {
|
||||
responseData["mediaDuration"] = obs_source_media_get_duration(input);
|
||||
responseData["mediaCursor"] = obs_source_media_get_time(input);
|
||||
} else {
|
||||
responseData["mediaDuration"] = nullptr;
|
||||
responseData["mediaCursor"] = nullptr;
|
||||
}
|
||||
|
||||
return RequestResult::Success(responseData);
|
||||
}
|
||||
|
||||
RequestResult RequestHandler::SetMediaInputCursor(const Request& request)
|
||||
{
|
||||
RequestStatus::RequestStatus statusCode;
|
||||
std::string comment;
|
||||
OBSSourceAutoRelease input = request.ValidateInput("inputName", statusCode, comment);
|
||||
if (!(input && request.ValidateNumber("mediaCursor", statusCode, comment, 0)))
|
||||
return RequestResult::Error(statusCode, comment);
|
||||
|
||||
if (!IsMediaTimeValid(input))
|
||||
return RequestResult::Error(RequestStatus::InvalidResourceState, "The media input must be playing or paused in order to set the cursor position.");
|
||||
|
||||
int64_t mediaCursor = request.RequestData["mediaCursor"];
|
||||
|
||||
// Yes, we're setting the time without checking if it's valid. Can't baby everything.
|
||||
obs_source_media_set_time(input, mediaCursor);
|
||||
|
||||
return RequestResult::Success();
|
||||
}
|
||||
|
||||
RequestResult RequestHandler::OffsetMediaInputCursor(const Request& request)
|
||||
{
|
||||
RequestStatus::RequestStatus statusCode;
|
||||
std::string comment;
|
||||
OBSSourceAutoRelease input = request.ValidateInput("inputName", statusCode, comment);
|
||||
if (!(input && request.ValidateNumber("mediaCursorOffset", statusCode, comment)))
|
||||
return RequestResult::Error(statusCode, comment);
|
||||
|
||||
if (!IsMediaTimeValid(input))
|
||||
return RequestResult::Error(RequestStatus::InvalidResourceState, "The media input must be playing or paused in order to set the cursor position.");
|
||||
|
||||
int64_t mediaCursorOffset = request.RequestData["mediaCursorOffset"];
|
||||
int64_t mediaCursor = obs_source_media_get_time(input) + mediaCursorOffset;
|
||||
|
||||
if (mediaCursor < 0)
|
||||
mediaCursor = 0;
|
||||
|
||||
obs_source_media_set_time(input, mediaCursor);
|
||||
|
||||
return RequestResult::Success();
|
||||
}
|
||||
|
||||
RequestResult RequestHandler::TriggerMediaInputAction(const Request& request)
|
||||
{
|
||||
RequestStatus::RequestStatus statusCode;
|
||||
std::string comment;
|
||||
OBSSourceAutoRelease input = request.ValidateInput("inputName", statusCode, comment);
|
||||
if (!(input && request.ValidateString("mediaAction", statusCode, comment)))
|
||||
return RequestResult::Error(statusCode, comment);
|
||||
|
||||
std::string mediaActionString = request.RequestData["mediaAction"];
|
||||
auto mediaAction = Utils::Obs::EnumHelper::GetMediaInputAction(mediaActionString);
|
||||
|
||||
switch (mediaAction) {
|
||||
default:
|
||||
case OBS_WEBSOCKET_MEDIA_INPUT_ACTION_NONE:
|
||||
return RequestResult::Error(RequestStatus::InvalidRequestParameter, "You have specified an invalid media input action.");
|
||||
case OBS_WEBSOCKET_MEDIA_INPUT_ACTION_PLAY:
|
||||
// Shoutout to whoever implemented this API call like this
|
||||
obs_source_media_play_pause(input, false);
|
||||
break;
|
||||
case OBS_WEBSOCKET_MEDIA_INPUT_ACTION_PAUSE:
|
||||
obs_source_media_play_pause(input, true);
|
||||
break;
|
||||
case OBS_WEBSOCKET_MEDIA_INPUT_ACTION_STOP:
|
||||
obs_source_media_stop(input);
|
||||
break;
|
||||
case OBS_WEBSOCKET_MEDIA_INPUT_ACTION_RESTART:
|
||||
// I'm only implementing this because I'm nice. I think its a really dumb action.
|
||||
obs_source_media_restart(input);
|
||||
break;
|
||||
case OBS_WEBSOCKET_MEDIA_INPUT_ACTION_NEXT:
|
||||
obs_source_media_next(input);
|
||||
break;
|
||||
case OBS_WEBSOCKET_MEDIA_INPUT_ACTION_PREVIOUS:
|
||||
obs_source_media_previous(input);
|
||||
break;
|
||||
}
|
||||
|
||||
return RequestResult::Success();
|
||||
}
|
@ -4,11 +4,13 @@ RequestResult RequestHandler::GetRecordStatus(const Request& request)
|
||||
{
|
||||
OBSOutputAutoRelease recordOutput = obs_frontend_get_streaming_output();
|
||||
|
||||
uint64_t outputDuration = Utils::Obs::NumberHelper::GetOutputDuration(recordOutput);
|
||||
|
||||
json responseData;
|
||||
responseData["outputActive"] = obs_output_active(recordOutput);
|
||||
responseData["outputPaused"] = obs_output_paused(recordOutput);
|
||||
responseData["outputTimecode"] = Utils::Obs::StringHelper::GetOutputTimecodeString(recordOutput);
|
||||
responseData["outputDuration"] = Utils::Obs::NumberHelper::GetOutputDuration(recordOutput);
|
||||
responseData["outputTimecode"] = Utils::Obs::StringHelper::DurationToTimecode(outputDuration);
|
||||
responseData["outputDuration"] = outputDuration;
|
||||
responseData["outputBytes"] = (uint64_t)obs_output_get_total_bytes(recordOutput);
|
||||
|
||||
return RequestResult::Success(responseData);
|
||||
|
@ -4,11 +4,13 @@ RequestResult RequestHandler::GetStreamStatus(const Request& request)
|
||||
{
|
||||
OBSOutputAutoRelease streamOutput = obs_frontend_get_streaming_output();
|
||||
|
||||
uint64_t outputDuration = Utils::Obs::NumberHelper::GetOutputDuration(streamOutput);
|
||||
|
||||
json responseData;
|
||||
responseData["outputActive"] = obs_output_active(streamOutput);
|
||||
responseData["outputReconnecting"] = obs_output_reconnecting(streamOutput);
|
||||
responseData["outputTimecode"] = Utils::Obs::StringHelper::GetOutputTimecodeString(streamOutput);
|
||||
responseData["outputDuration"] = Utils::Obs::NumberHelper::GetOutputDuration(streamOutput);
|
||||
responseData["outputTimecode"] = Utils::Obs::StringHelper::DurationToTimecode(outputDuration);
|
||||
responseData["outputDuration"] = outputDuration;
|
||||
responseData["outputBytes"] = (uint64_t)obs_output_get_total_bytes(streamOutput);
|
||||
responseData["outputSkippedFrames"] = obs_output_get_frames_dropped(streamOutput);
|
||||
responseData["outputTotalFrames"] = obs_output_get_total_frames(streamOutput);
|
||||
|
@ -30,7 +30,7 @@ std::vector<std::string> ConvertStringArray(char **array)
|
||||
return ret;
|
||||
}
|
||||
|
||||
std::string Utils::Obs::StringHelper::GetObsVersionString()
|
||||
std::string Utils::Obs::StringHelper::GetObsVersion()
|
||||
{
|
||||
uint32_t version = obs_get_version();
|
||||
|
||||
@ -77,7 +77,7 @@ std::string Utils::Obs::StringHelper::GetCurrentRecordOutputPath()
|
||||
return "";
|
||||
}
|
||||
|
||||
std::string Utils::Obs::StringHelper::GetSourceTypeString(obs_source_t *source)
|
||||
std::string Utils::Obs::StringHelper::GetSourceType(obs_source_t *source)
|
||||
{
|
||||
obs_source_type sourceType = obs_source_get_type(source);
|
||||
|
||||
@ -90,7 +90,7 @@ std::string Utils::Obs::StringHelper::GetSourceTypeString(obs_source_t *source)
|
||||
}
|
||||
}
|
||||
|
||||
std::string Utils::Obs::StringHelper::GetInputMonitorTypeString(obs_source_t *input)
|
||||
std::string Utils::Obs::StringHelper::GetInputMonitorType(obs_source_t *input)
|
||||
{
|
||||
obs_monitoring_type monitorType = obs_source_get_monitoring_type(input);
|
||||
|
||||
@ -102,7 +102,7 @@ std::string Utils::Obs::StringHelper::GetInputMonitorTypeString(obs_source_t *in
|
||||
}
|
||||
}
|
||||
|
||||
std::string Utils::Obs::StringHelper::GetMediaInputStateString(obs_source_t *input)
|
||||
std::string Utils::Obs::StringHelper::GetMediaInputState(obs_source_t *input)
|
||||
{
|
||||
obs_media_state mediaState = obs_source_media_get_state(input);
|
||||
|
||||
@ -130,7 +130,7 @@ std::string Utils::Obs::StringHelper::GetLastReplayBufferFilePath()
|
||||
return ret;
|
||||
}
|
||||
|
||||
std::string Utils::Obs::StringHelper::GetSceneItemBoundsTypeString(enum obs_bounds_type type)
|
||||
std::string Utils::Obs::StringHelper::GetSceneItemBoundsType(enum obs_bounds_type type)
|
||||
{
|
||||
switch (type) {
|
||||
default:
|
||||
@ -144,16 +144,8 @@ std::string Utils::Obs::StringHelper::GetSceneItemBoundsTypeString(enum obs_boun
|
||||
}
|
||||
}
|
||||
|
||||
std::string Utils::Obs::StringHelper::GetOutputTimecodeString(obs_output_t *output)
|
||||
std::string Utils::Obs::StringHelper::DurationToTimecode(uint64_t ms)
|
||||
{
|
||||
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 = util_mul_div64(totalFrames, frameTimeNs, 1000000ULL);
|
||||
uint64_t secs = ms / 1000ULL;
|
||||
uint64_t minutes = secs / 60ULL;
|
||||
|
||||
@ -179,6 +171,18 @@ enum obs_bounds_type Utils::Obs::EnumHelper::GetSceneItemBoundsType(std::string
|
||||
return OBS_BOUNDS_NONE;
|
||||
}
|
||||
|
||||
enum ObsMediaInputAction Utils::Obs::EnumHelper::GetMediaInputAction(std::string mediaAction)
|
||||
{
|
||||
RET_COMPARE(mediaAction, OBS_WEBSOCKET_MEDIA_INPUT_ACTION_PLAY);
|
||||
RET_COMPARE(mediaAction, OBS_WEBSOCKET_MEDIA_INPUT_ACTION_PAUSE);
|
||||
RET_COMPARE(mediaAction, OBS_WEBSOCKET_MEDIA_INPUT_ACTION_STOP);
|
||||
RET_COMPARE(mediaAction, OBS_WEBSOCKET_MEDIA_INPUT_ACTION_RESTART);
|
||||
RET_COMPARE(mediaAction, OBS_WEBSOCKET_MEDIA_INPUT_ACTION_NEXT);
|
||||
RET_COMPARE(mediaAction, OBS_WEBSOCKET_MEDIA_INPUT_ACTION_PREVIOUS);
|
||||
|
||||
return OBS_WEBSOCKET_MEDIA_INPUT_ACTION_NONE;
|
||||
}
|
||||
|
||||
uint64_t Utils::Obs::NumberHelper::GetOutputDuration(obs_output_t *output)
|
||||
{
|
||||
if (!output || !obs_output_active(output))
|
||||
@ -288,11 +292,15 @@ std::vector<json> Utils::Obs::ListHelper::GetSceneItemList(obs_scene_t *scene, b
|
||||
if (!enumData->second) {
|
||||
OBSSource itemSource = obs_sceneitem_get_source(sceneItem);
|
||||
item["sourceName"] = obs_source_get_name(itemSource);
|
||||
item["sourceType"] = StringHelper::GetSourceTypeString(itemSource);
|
||||
item["sourceType"] = StringHelper::GetSourceType(itemSource);
|
||||
if (obs_source_get_type(itemSource) == OBS_SOURCE_TYPE_INPUT)
|
||||
item["inputKind"] = obs_source_get_id(itemSource);
|
||||
else if (obs_source_get_type(itemSource) == OBS_SOURCE_TYPE_SCENE)
|
||||
else
|
||||
item["inputKind"] = nullptr;
|
||||
if (obs_source_get_type(itemSource) == OBS_SOURCE_TYPE_SCENE)
|
||||
item["isGroup"] = obs_source_is_group(itemSource);
|
||||
else
|
||||
item["isGroup"] = nullptr;
|
||||
}
|
||||
|
||||
enumData->first.push_back(item);
|
||||
@ -433,7 +441,7 @@ json Utils::Obs::DataHelper::GetSceneItemTransform(obs_sceneitem_t *item)
|
||||
|
||||
ret["alignment"] = osi.alignment;
|
||||
|
||||
ret["boundsType"] = StringHelper::GetSceneItemBoundsTypeString(osi.bounds_type);
|
||||
ret["boundsType"] = StringHelper::GetSceneItemBoundsType(osi.bounds_type);
|
||||
ret["boundsAlignment"] = osi.bounds_alignment;
|
||||
ret["boundsWidth"] = osi.bounds.x;
|
||||
ret["boundsHeight"] = osi.bounds.y;
|
||||
|
@ -16,10 +16,11 @@ enum ObsOutputState {
|
||||
};
|
||||
|
||||
enum ObsMediaInputAction {
|
||||
OBS_WEBSOCKET_MEDIA_INPUT_ACTION_PAUSE,
|
||||
OBS_WEBSOCKET_MEDIA_INPUT_ACTION_NONE,
|
||||
OBS_WEBSOCKET_MEDIA_INPUT_ACTION_PLAY,
|
||||
OBS_WEBSOCKET_MEDIA_INPUT_ACTION_RESTART,
|
||||
OBS_WEBSOCKET_MEDIA_INPUT_ACTION_PAUSE,
|
||||
OBS_WEBSOCKET_MEDIA_INPUT_ACTION_STOP,
|
||||
OBS_WEBSOCKET_MEDIA_INPUT_ACTION_RESTART,
|
||||
OBS_WEBSOCKET_MEDIA_INPUT_ACTION_NEXT,
|
||||
OBS_WEBSOCKET_MEDIA_INPUT_ACTION_PREVIOUS
|
||||
};
|
||||
@ -27,21 +28,22 @@ enum ObsMediaInputAction {
|
||||
namespace Utils {
|
||||
namespace Obs {
|
||||
namespace StringHelper {
|
||||
std::string GetObsVersionString();
|
||||
std::string GetObsVersion();
|
||||
std::string GetCurrentSceneCollection();
|
||||
std::string GetCurrentProfile();
|
||||
std::string GetCurrentProfilePath();
|
||||
std::string GetCurrentRecordOutputPath();
|
||||
std::string GetSourceTypeString(obs_source_t *source);
|
||||
std::string GetInputMonitorTypeString(obs_source_t *input);
|
||||
std::string GetMediaInputStateString(obs_source_t *input);
|
||||
std::string GetSourceType(obs_source_t *source);
|
||||
std::string GetInputMonitorType(obs_source_t *input);
|
||||
std::string GetMediaInputState(obs_source_t *input);
|
||||
std::string GetLastReplayBufferFilePath();
|
||||
std::string GetSceneItemBoundsTypeString(enum obs_bounds_type type);
|
||||
std::string GetOutputTimecodeString(obs_output_t *output);
|
||||
std::string GetSceneItemBoundsType(enum obs_bounds_type type);
|
||||
std::string DurationToTimecode(uint64_t);
|
||||
}
|
||||
|
||||
namespace EnumHelper {
|
||||
enum obs_bounds_type GetSceneItemBoundsType(std::string boundsType);
|
||||
enum ObsMediaInputAction GetMediaInputAction(std::string mediaAction);
|
||||
}
|
||||
|
||||
namespace NumberHelper {
|
||||
|
Loading…
Reference in New Issue
Block a user