diff --git a/.cmake-format.json b/.cmake-format.json index 7e5f23697..20610be23 100644 --- a/.cmake-format.json +++ b/.cmake-format.json @@ -1,13 +1,46 @@ { - "additional_commands": { - "find_qt": { - "flags": [], - "kwargs": { - "COMPONENTS": "+", - "COMPONENTS_WIN": "+", - "COMPONENTS_MACOS": "+", - "COMPONENTS_LINUX": "+" + "format": { + "line_width": 120, + "tab_size": 2, + "enable_sort": true, + "autosort": true + }, + "additional_commands": { + "find_qt": { + "flags": [], + "kwargs": { + "COMPONENTS": "+", + "COMPONENTS_WIN": "+", + "COMPONENTS_MACOS": "+", + "COMPONENTS_LINUX": "+" + } + }, + "set_target_properties_obs": { + "pargs": 1, + "flags": [], + "kwargs": { + "PROPERTIES": { + "kwargs": { + "PREFIX": 1, + "OUTPUT_NAME": 1, + "FOLDER": 1, + "VERSION": 1, + "SOVERSION": 1, + "FRAMEWORK": 1, + "BUNDLE": 1, + "AUTOMOC": 1, + "AUTOUIC": 1, + "AUTORCC": 1, + "AUTOUIC_SEARCH_PATHS": 1, + "BUILD_RPATH": 1, + "INSTALL_RPATH": 1, + "XCODE_ATTRIBUTE_CLANG_ENABLE_OBJC_ARC": 1, + "XCODE_ATTRIBUTE_CLANG_WARN_SUSPICIOUS_IMPLICIT_CONVERSION": 1, + "XCODE_ATTRIBUTE_GCC_WARN_SHADOW":1 , + "LIBRARY_OUTPUT_DIRECTORY": 1 + } } } } + } } diff --git a/.github/workflows/crowdin_upload.yml b/.github/workflows/crowdin_upload.yml new file mode 100644 index 000000000..65664b0f8 --- /dev/null +++ b/.github/workflows/crowdin_upload.yml @@ -0,0 +1,22 @@ +name: Upload Language Files 🌐 +on: + push: + branches: + - master + paths: + - "**/en-US.ini" +jobs: + upload-language-files: + name: Upload Language Files 🌐 + if: github.repository_owner == 'obsproject' + runs-on: ubuntu-22.04 + steps: + - uses: actions/checkout@v3 + with: + fetch-depth: 100 + - name: Upload US English Language Files 🇺🇸 + uses: obsproject/obs-crowdin-sync/upload@30b5446e3b5eb19595aa68a81ddf896a857302cf + env: + CROWDIN_PAT: ${{ secrets.CROWDIN_SYNC_CROWDIN_PAT }} + GITHUB_EVENT_BEFORE: ${{ github.event.before }} + SUBMODULE_NAME: obs-websocket diff --git a/.gitignore b/.gitignore index fa6248061..6ef1aaa91 100644 --- a/.gitignore +++ b/.gitignore @@ -2,7 +2,6 @@ .DS_Store .idea .vscode -**.generated.h /build/ /build32/ /build64/ @@ -10,5 +9,4 @@ /package/ /installer/Output/ /docs/node_modules/ -/installer/installer-windows.generated.iss /cmake-build-debug/ diff --git a/.gitmodules b/.gitmodules index ce13f339b..e69de29bb 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,12 +0,0 @@ -[submodule "deps/websocketpp"] - path = deps/websocketpp - url = https://github.com/zaphoyd/websocketpp.git -[submodule "deps/asio"] - path = deps/asio - url = https://github.com/chriskohlhoff/asio.git -[submodule "deps/json"] - path = deps/json - url = https://github.com/nlohmann/json.git -[submodule "deps/qr"] - path = deps/qr - url = https://github.com/nayuki/QR-Code-generator.git diff --git a/CMakeLists.txt b/CMakeLists.txt index a900288e4..3f7b3d4a5 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,138 +1,154 @@ -project(obs-websocket VERSION 5.1.0) +cmake_minimum_required(VERSION 3.16...3.25) + +legacy_check() + +set(obs-websocket_VERSION 5.4.0) set(OBS_WEBSOCKET_RPC_VERSION 1) option(ENABLE_WEBSOCKET "Enable building OBS with websocket plugin" ON) - -if(NOT ENABLE_WEBSOCKET OR NOT ENABLE_UI) - message(STATUS "OBS: DISABLED obs-websocket") +if(NOT ENABLE_WEBSOCKET) + target_disable(obs-websocket) return() endif() -# Submodule deps check -if(NOT - (EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/deps/json/CMakeLists.txt - AND EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/deps/websocketpp/CMakeLists.txt - AND EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/deps/qr/cpp/QrCode.hpp - AND EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/deps/asio/asio/include/asio.hpp)) - obs_status(FATAL_ERROR "obs-websocket submodule deps not available.") -endif() - -# Plugin tests flag -option(PLUGIN_TESTS "Enable plugin runtime tests" OFF) - -# Qt build stuff -set(CMAKE_PREFIX_PATH "${QTDIR}") -set(CMAKE_INCLUDE_CURRENT_DIR ON) -set(CMAKE_AUTOMOC ON) -set(CMAKE_AUTOUIC ON) -set(CMAKE_AUTORCC ON) # For resources.qrc - # Find Qt -find_qt(COMPONENTS Core Widgets Svg Network) +find_package(Qt6 REQUIRED Core Widgets Svg Network) + +# Find nlohmann JSON +find_package(nlohmann_json 3 REQUIRED) -# Find nlohmann -set(JSON_BuildTests - OFF - CACHE INTERNAL "") -add_subdirectory(deps/json) +# Find qrcodegencpp +set(CMAKE_FIND_PACKAGE_PREFER_CONFIG ON) +find_package(qrcodegencpp REQUIRED) +set(CMAKE_FIND_PACKAGE_PREFER_CONFIG OFF) -# Tell websocketpp not to use system boost -add_definitions(-DASIO_STANDALONE) +# Find WebSocket++ +find_package(Websocketpp 0.8 REQUIRED) -# Configure files -configure_file(${CMAKE_CURRENT_SOURCE_DIR}/src/plugin-macros.h.in - ${CMAKE_CURRENT_SOURCE_DIR}/src/plugin-macros.generated.h) +# Find Asio +find_package(Asio 1.12.1 REQUIRED) -# Setup target add_library(obs-websocket MODULE) add_library(OBS::websocket ALIAS obs-websocket) target_sources( obs-websocket - PRIVATE src/obs-websocket.cpp - src/obs-websocket.h + PRIVATE # cmake-format: sortable + lib/obs-websocket-api.h src/Config.cpp src/Config.h - lib/obs-websocket-api.h - src/forms/SettingsDialog.cpp - src/forms/SettingsDialog.h src/forms/ConnectInfo.cpp src/forms/ConnectInfo.h src/forms/resources.qrc + src/forms/SettingsDialog.cpp + src/forms/SettingsDialog.h + src/obs-websocket.cpp + src/obs-websocket.h src/WebSocketApi.cpp - src/WebSocketApi.h - src/websocketserver/WebSocketServer.cpp - src/websocketserver/WebSocketServer_Protocol.cpp - src/websocketserver/WebSocketServer.h - src/websocketserver/rpc/WebSocketSession.cpp + src/WebSocketApi.h) + +target_sources( + obs-websocket + PRIVATE # cmake-format: sortable src/websocketserver/rpc/WebSocketSession.h src/websocketserver/types/WebSocketCloseCode.h src/websocketserver/types/WebSocketOpCode.h + src/websocketserver/WebSocketServer.cpp + src/websocketserver/WebSocketServer.h + src/websocketserver/WebSocketServer_Protocol.cpp) + +target_sources( + obs-websocket + PRIVATE # cmake-format: sortable src/eventhandler/EventHandler.cpp - src/eventhandler/EventHandler_General.cpp + src/eventhandler/EventHandler.h src/eventhandler/EventHandler_Config.cpp - src/eventhandler/EventHandler_Scenes.cpp - src/eventhandler/EventHandler_Inputs.cpp - src/eventhandler/EventHandler_Transitions.cpp src/eventhandler/EventHandler_Filters.cpp + src/eventhandler/EventHandler_General.cpp + src/eventhandler/EventHandler_Inputs.cpp + src/eventhandler/EventHandler_MediaInputs.cpp src/eventhandler/EventHandler_Outputs.cpp src/eventhandler/EventHandler_SceneItems.cpp - src/eventhandler/EventHandler_MediaInputs.cpp + src/eventhandler/EventHandler_Scenes.cpp + src/eventhandler/EventHandler_Transitions.cpp src/eventhandler/EventHandler_Ui.cpp - src/eventhandler/EventHandler.h - src/eventhandler/types/EventSubscription.h + src/eventhandler/types/EventSubscription.h) + +target_sources( + obs-websocket + PRIVATE # cmake-format: sortable + src/requesthandler/RequestBatchHandler.cpp + src/requesthandler/RequestBatchHandler.h src/requesthandler/RequestHandler.cpp - src/requesthandler/RequestHandler_General.cpp + src/requesthandler/RequestHandler.h src/requesthandler/RequestHandler_Config.cpp - src/requesthandler/RequestHandler_Sources.cpp - src/requesthandler/RequestHandler_Scenes.cpp - src/requesthandler/RequestHandler_Inputs.cpp - src/requesthandler/RequestHandler_Transitions.cpp src/requesthandler/RequestHandler_Filters.cpp - src/requesthandler/RequestHandler_SceneItems.cpp + src/requesthandler/RequestHandler_General.cpp + src/requesthandler/RequestHandler_Inputs.cpp + src/requesthandler/RequestHandler_MediaInputs.cpp src/requesthandler/RequestHandler_Outputs.cpp - src/requesthandler/RequestHandler_Stream.cpp src/requesthandler/RequestHandler_Record.cpp - src/requesthandler/RequestHandler_MediaInputs.cpp + src/requesthandler/RequestHandler_SceneItems.cpp + src/requesthandler/RequestHandler_Scenes.cpp + src/requesthandler/RequestHandler_Sources.cpp + src/requesthandler/RequestHandler_Stream.cpp + src/requesthandler/RequestHandler_Transitions.cpp src/requesthandler/RequestHandler_Ui.cpp - src/requesthandler/RequestHandler.h - src/requesthandler/RequestBatchHandler.cpp - src/requesthandler/RequestBatchHandler.h src/requesthandler/rpc/Request.cpp src/requesthandler/rpc/Request.h src/requesthandler/rpc/RequestBatchRequest.cpp src/requesthandler/rpc/RequestBatchRequest.h src/requesthandler/rpc/RequestResult.cpp src/requesthandler/rpc/RequestResult.h - src/requesthandler/types/RequestStatus.h src/requesthandler/types/RequestBatchExecutionType.h + src/requesthandler/types/RequestStatus.h) + +target_sources( + obs-websocket + PRIVATE # cmake-format: sortable + src/utils/Compat.cpp + src/utils/Compat.h src/utils/Crypto.cpp src/utils/Crypto.h src/utils/Json.cpp src/utils/Json.h src/utils/Obs.cpp - src/utils/Obs_StringHelper.cpp - src/utils/Obs_NumberHelper.cpp + src/utils/Obs.h + src/utils/Obs_ActionHelper.cpp src/utils/Obs_ArrayHelper.cpp + src/utils/Obs_NumberHelper.cpp src/utils/Obs_ObjectHelper.cpp src/utils/Obs_SearchHelper.cpp - src/utils/Obs_ActionHelper.cpp - src/utils/Obs.h + src/utils/Obs_StringHelper.cpp src/utils/Obs_VolumeMeter.cpp src/utils/Obs_VolumeMeter.h src/utils/Obs_VolumeMeter_Helpers.h src/utils/Platform.cpp src/utils/Platform.h - src/utils/Compat.cpp - src/utils/Compat.h - src/utils/Utils.h - deps/qr/cpp/QrCode.cpp - deps/qr/cpp/QrCode.hpp) + src/utils/Utils.h) + +configure_file(src/plugin-macros.h.in plugin-macros.generated.h) +target_sources(obs-websocket PRIVATE plugin-macros.generated.h) + +target_compile_definitions( + obs-websocket PRIVATE ASIO_STANDALONE $<$:PLUGIN_TESTS> + $<$:_WEBSOCKETPP_CPP11_STL_> $<$:_WIN32_WINNT=0x0603>) -target_include_directories( +target_compile_options( obs-websocket - PRIVATE ${Qt5Core_INCLUDES} ${Qt5Widgets_INCLUDES} ${Qt5Svg_INCLUDES} - ${Qt5Network_INCLUDES} "deps/asio/asio/include" "deps/websocketpp") + PRIVATE $<$:/wd4267> + $<$:-Wall> + $<$:-Wno-error=float-conversion> + $<$:-Wno-error=shadow> + $<$:-Wno-error=format-overflow> + $<$:-Wno-error=int-conversion> + $<$:-Wno-error=comment> + $<$:-Wno-error=null-pointer-subtraction> + $<$:-Wno-error=deprecated-declarations> + $<$:-Wno-error=implicit-int-conversion> + $<$:-Wno-error=shorten-64-to-32> + $<$:-Wno-comma> + $<$:-Wno-quoted-include-in-framework-header>) target_link_libraries( obs-websocket @@ -142,33 +158,24 @@ target_link_libraries( Qt::Widgets Qt::Svg Qt::Network - nlohmann_json::nlohmann_json) - -target_compile_features(obs-websocket PRIVATE cxx_std_17) - -set_target_properties(obs-websocket PROPERTIES FOLDER "plugins/obs-websocket") + nlohmann_json::nlohmann_json + Websocketpp::Websocketpp + Asio::Asio + qrcodegencpp::qrcodegencpp) -if(PLUGIN_TESTS) - target_compile_definitions(obs-websocket PRIVATE PLUGIN_TESTS) -endif() - -# Random other things -if(WIN32) - add_definitions(-D_WEBSOCKETPP_CPP11_STL_) -endif() +target_link_options(obs-websocket PRIVATE $<$:/IGNORE:4099>) -if(MSVC) - target_compile_options(obs-websocket PRIVATE /wd4267 /wd4996) -else() - target_compile_options( - obs-websocket - PRIVATE - -Wall - "$<$:-Wno-error=format-overflow>" - "$<$:-Wno-error=null-pointer-subtraction;-Wno-error=deprecated-declarations>" - ) +set_target_properties_obs( + obs-websocket + PROPERTIES FOLDER plugins + PREFIX "" + AUTOMOC ON + AUTOUIC ON + AUTORCC ON) + +if(OS_WINDOWS) + set_property( + TARGET obs-websocket + APPEND + PROPERTY AUTORCC_OPTIONS --format-version 1) endif() - -# Final CMake helpers -setup_plugin_target(obs-websocket) -setup_target_resources(obs-websocket "obs-plugins/obs-websocket") diff --git a/README.md b/README.md index 5ce923928..cea393745 100644 --- a/README.md +++ b/README.md @@ -13,7 +13,7 @@ WebSocket API for OBS Studio. ## Downloads -obs-websocket is now included by default with OBS Studio 28.0.0 and above. As such, **there should be no need to download obs-websocket if you have OBS Studio > 28.0.0.** +**obs-websocket is now included by default with OBS Studio 28.0.0 and above. As such, there should be no need to download obs-websocket if you have OBS Studio > 28.0.0.** Binaries **for OBS Studio < 28.0.0** on Windows, MacOS, and Linux are available in the [Releases](https://github.com/obsproject/obs-websocket/releases) section. @@ -31,7 +31,7 @@ It is **highly recommended** to keep obs-websocket protected with a password aga ### Client software -- [Macro Deck](https://www.macrodeck.org/) +- [Macro Deck](https://macrodeck.org/) - [Touch Portal](https://www.touch-portal.com/) - [Twitchat](https://twitchat.fr/) - [OBS-web](https://github.com/Niek/obs-web) - hosted client at [obs-web.niek.tv/](http://obs-web.niek.tv/) @@ -41,6 +41,8 @@ It is **highly recommended** to keep obs-websocket protected with a password aga - [Aitum](https://aitum.tv/) - [Kruiz Control](https://github.com/Kruiser8/Kruiz-Control) - [Bitfocus Companion Module](https://bitfocus.io/companion/) +- [MacroGraph](https://github.com/Brendonovich/macrograph) - hosted client [here](https://macrograph.brendonovich.dev/) +- [MATRIC](https://matricapp.com/) - [OBS Notifier](https://github.com/DmitriySalnikov/OBSNotifier) ### Client libraries (for developers) @@ -50,7 +52,7 @@ Here's a list of available language APIs for obs-websocket: - Python 3.7+ (Asyncio): [simpleobsws](https://github.com/IRLToolkit/simpleobsws/tree/master) by IRLToolkit - Python 3.10+ (Non-Asyncio): [obsws-python](https://pypi.org/project/obsws-python) by aatikturk and onyx-and-iris - Rust: [obws](https://github.com/dnaka91/obws) by dnaka91 -- Godot 3.4.x: [obs-websocket-gd](https://github.com/you-win/obs-websocket-gd) by you-win +- Godot 4.0.x: [obs-websocket-gd](https://github.com/you-win/obs-websocket-gd) by you-win - Javascript (Node and web): [obs-websocket-js](https://github.com/obs-websocket-community-projects/obs-websocket-js) by OBS Websocket Community - C (uses obs-websocket-js): [v8-libwebsocket-obs-websocket](https://github.com/dgatwood/v8-libwebsocket-obs-websocket) - Go: [goobs](https://github.com/andreykaipov/goobs) by andreykaipov @@ -66,12 +68,11 @@ We'd like to know what you're building with obs-websocket! If you do something i ### Code Contributors -This project exists thanks to [all the people](graphs/contributors) who contribute. [Contribute](wiki/Contributing-Guidelines). - +This project exists thanks to [all the people](https://github.com/obsproject/obs-websocket/graphs/contributors) who contribute. [Contribute Code](https://github.com/obsproject/obs-websocket/wiki/Contributing-Guidelines). ### Financial Contributors -Become a financial contributor and help us sustain our community. [Contribute](https://opencollective.com/obs-websocket-dev/contribute) +Become a financial contributor and help us sustain our community. [Contribute Financially](https://opencollective.com/obs-websocket-dev/contribute) #### Individuals diff --git a/cmake/legacy.cmake b/cmake/legacy.cmake new file mode 100644 index 000000000..7e3226b25 --- /dev/null +++ b/cmake/legacy.cmake @@ -0,0 +1,173 @@ +project(obs-websocket VERSION 5.4.0) +set(OBS_WEBSOCKET_RPC_VERSION 1) + +option(ENABLE_WEBSOCKET "Enable building OBS with websocket plugin" ON) + +if(NOT ENABLE_WEBSOCKET OR NOT ENABLE_UI) + message(STATUS "OBS: DISABLED obs-websocket") + return() +endif() + +# Plugin tests flag +option(PLUGIN_TESTS "Enable plugin runtime tests" OFF) + +# Find Qt +find_qt(COMPONENTS Core Widgets Svg Network) + +# Find nlohmann JSON +find_package(nlohmann_json 3 REQUIRED) + +# Find qrcodegencpp +set(CMAKE_FIND_PACKAGE_PREFER_CONFIG ON) +find_package(qrcodegencpp REQUIRED) +set(CMAKE_FIND_PACKAGE_PREFER_CONFIG OFF) + +# Find WebSocket++ +find_package(Websocketpp 0.8 REQUIRED) + +# Find Asio +find_package(Asio 1.12.1 REQUIRED) + +# Tell websocketpp not to use system boost +add_definitions(-DASIO_STANDALONE) + +# Configure files +configure_file(src/plugin-macros.h.in plugin-macros.generated.h) + +# Setup target +add_library(obs-websocket MODULE) +add_library(OBS::websocket ALIAS obs-websocket) + +set_target_properties( + obs-websocket + PROPERTIES AUTOMOC ON + AUTOUIC ON + AUTORCC ON) + +if(_QT_VERSION EQUAL 6 AND OS_WINDOWS) + set_target_properties(obs-websocket PROPERTIES AUTORCC_OPTIONS "--format-version;1") +endif() + +target_include_directories(obs-websocket PRIVATE ${CMAKE_CURRENT_BINARY_DIR}) + +target_sources( + obs-websocket + PRIVATE src/obs-websocket.cpp + src/obs-websocket.h + src/Config.cpp + src/Config.h + lib/obs-websocket-api.h + src/forms/SettingsDialog.cpp + src/forms/SettingsDialog.h + src/forms/ConnectInfo.cpp + src/forms/ConnectInfo.h + src/forms/resources.qrc + src/WebSocketApi.cpp + src/WebSocketApi.h + src/websocketserver/WebSocketServer.cpp + src/websocketserver/WebSocketServer_Protocol.cpp + src/websocketserver/WebSocketServer.h + src/websocketserver/rpc/WebSocketSession.h + src/websocketserver/types/WebSocketCloseCode.h + src/websocketserver/types/WebSocketOpCode.h + src/eventhandler/EventHandler.cpp + src/eventhandler/EventHandler_General.cpp + src/eventhandler/EventHandler_Config.cpp + src/eventhandler/EventHandler_Scenes.cpp + src/eventhandler/EventHandler_Inputs.cpp + src/eventhandler/EventHandler_Transitions.cpp + src/eventhandler/EventHandler_Filters.cpp + src/eventhandler/EventHandler_Outputs.cpp + src/eventhandler/EventHandler_SceneItems.cpp + src/eventhandler/EventHandler_MediaInputs.cpp + src/eventhandler/EventHandler_Ui.cpp + src/eventhandler/EventHandler.h + src/eventhandler/types/EventSubscription.h + src/requesthandler/RequestHandler.cpp + src/requesthandler/RequestHandler_General.cpp + src/requesthandler/RequestHandler_Config.cpp + src/requesthandler/RequestHandler_Sources.cpp + src/requesthandler/RequestHandler_Scenes.cpp + src/requesthandler/RequestHandler_Inputs.cpp + src/requesthandler/RequestHandler_Transitions.cpp + src/requesthandler/RequestHandler_Filters.cpp + src/requesthandler/RequestHandler_SceneItems.cpp + src/requesthandler/RequestHandler_Outputs.cpp + src/requesthandler/RequestHandler_Stream.cpp + src/requesthandler/RequestHandler_Record.cpp + src/requesthandler/RequestHandler_MediaInputs.cpp + src/requesthandler/RequestHandler_Ui.cpp + src/requesthandler/RequestHandler.h + src/requesthandler/RequestBatchHandler.cpp + src/requesthandler/RequestBatchHandler.h + src/requesthandler/rpc/Request.cpp + src/requesthandler/rpc/Request.h + src/requesthandler/rpc/RequestBatchRequest.cpp + src/requesthandler/rpc/RequestBatchRequest.h + src/requesthandler/rpc/RequestResult.cpp + src/requesthandler/rpc/RequestResult.h + src/requesthandler/types/RequestStatus.h + src/requesthandler/types/RequestBatchExecutionType.h + src/utils/Crypto.cpp + src/utils/Crypto.h + src/utils/Json.cpp + src/utils/Json.h + src/utils/Obs.cpp + src/utils/Obs_StringHelper.cpp + src/utils/Obs_NumberHelper.cpp + src/utils/Obs_ArrayHelper.cpp + src/utils/Obs_ObjectHelper.cpp + src/utils/Obs_SearchHelper.cpp + src/utils/Obs_ActionHelper.cpp + src/utils/Obs.h + src/utils/Obs_VolumeMeter.cpp + src/utils/Obs_VolumeMeter.h + src/utils/Obs_VolumeMeter_Helpers.h + src/utils/Platform.cpp + src/utils/Platform.h + src/utils/Compat.cpp + src/utils/Compat.h + src/utils/Utils.h) + +target_link_libraries( + obs-websocket + PRIVATE OBS::libobs + OBS::frontend-api + Qt::Core + Qt::Widgets + Qt::Svg + Qt::Network + nlohmann_json::nlohmann_json + Websocketpp::Websocketpp + Asio::Asio + qrcodegencpp::qrcodegencpp) + +target_compile_features(obs-websocket PRIVATE cxx_std_17) + +set_target_properties(obs-websocket PROPERTIES FOLDER "plugins/obs-websocket") + +if(PLUGIN_TESTS) + target_compile_definitions(obs-websocket PRIVATE PLUGIN_TESTS) +endif() + +# Random other things +if(WIN32) + add_definitions(-D_WEBSOCKETPP_CPP11_STL_) +endif() + +if(MSVC) + target_compile_options(obs-websocket PRIVATE /wd4267 /wd4996) + target_link_options(obs-websocket PRIVATE "LINKER:/IGNORE:4099") +else() + target_compile_options( + obs-websocket + PRIVATE + -Wall + "$<$:-Wno-error=format-overflow>" + "$<$:-Wno-error=null-pointer-subtraction;-Wno-error=deprecated-declarations>" + ) +endif() + +# Final CMake helpers +setup_plugin_target(obs-websocket) +setup_target_resources(obs-websocket "obs-plugins/obs-websocket") diff --git a/cmake/macos/Info.plist.in b/cmake/macos/Info.plist.in new file mode 100644 index 000000000..398c3d9f2 --- /dev/null +++ b/cmake/macos/Info.plist.in @@ -0,0 +1,28 @@ + + + + + CFBundleName + obs-websocket + CFBundleIdentifier + com.obsproject.obs-websocket + CFBundleVersion + ${MACOSX_BUNDLE_BUNDLE_VERSION} + CFBundleShortVersionString + ${MACOSX_BUNDLE_SHORT_VERSION_STRING} + CFBundleInfoDictionaryVersion + 6.0 + CFBundleExecutable + obs-websocket + CFBundlePackageType + BNDL + CFBundleSupportedPlatforms + + MacOSX + + LSMinimumSystemVersion + ${CMAKE_OSX_DEPLOYMENT_TARGET} + NSHumanReadableCopyright + (c) 2016-${CURRENT_YEAR} Stéphane Lepin, Kyle Manning + + diff --git a/data/locale/af-ZA.ini b/data/locale/af-ZA.ini new file mode 100644 index 000000000..a93b4545c --- /dev/null +++ b/data/locale/af-ZA.ini @@ -0,0 +1,35 @@ +OBSWebSocket.Plugin.Description="Afstandbeheer van OBS deur WebSocket" +OBSWebSocket.Settings.DialogTitle="WebSocket-bedienerinstellings" +OBSWebSocket.Settings.PluginSettingsTitle="Inpropinstellings" +OBSWebSocket.Settings.ServerEnable="Aktiveer WebSocket-diens" +OBSWebSocket.Settings.ServerSettingsTitle="Bedienerinstellings" +OBSWebSocket.Settings.Password="Bedienerwagwoord" +OBSWebSocket.Settings.GeneratePassword="Genereer wagwoord" +OBSWebSocket.Settings.ServerPort="Bedienerpoort" +OBSWebSocket.Settings.ShowConnectInfoWarningTitle="Waarskuwing: Tans regstreeks" +OBSWebSocket.Settings.ShowConnectInfoWarningMessage="Dit lyk of ’n afvoer (stroom, opname, ens.) tans aktief is." +OBSWebSocket.Settings.ShowConnectInfoWarningInfoText="Is u seker u wil u verbindingsinligting laat sien?" +OBSWebSocket.Settings.Save.UserPasswordWarningTitle="Waarskuwing: potensiële beveiligingsprobleem" +OBSWebSocket.Settings.Save.UserPasswordWarningMessage="obs-websok bewaar die bedienerwagwoord as platteks. Dit word ten sterkste aanbeveel om ’n wagwoord wat deur obs-websok geskep is te gebruik." +OBSWebSocket.Settings.Save.UserPasswordWarningInfoText="Is u seker u wil u eie wagwoord gebruik?" +OBSWebSocket.Settings.Save.PasswordInvalidErrorTitle="Fout: Ongeldige opstalling" +OBSWebSocket.Settings.Save.PasswordInvalidErrorMessage="U moet ’n wagwoord van meet as 6 karakters gebruik." +OBSWebSocket.SessionTable.Title="Gekoppelde WebSocket-sessies" +OBSWebSocket.SessionTable.RemoteAddressColumnTitle="Afstandsadres" +OBSWebSocket.SessionTable.SessionDurationColumnTitle="Sessieduur" +OBSWebSocket.SessionTable.MessagesInOutColumnTitle="Boodskappe In/Uit" +OBSWebSocket.SessionTable.IdentifiedTitle="Geïdentifiseer" +OBSWebSocket.SessionTable.KickButtonColumnTitle="Verwyder?" +OBSWebSocket.SessionTable.KickButtonText="Verwyder" +OBSWebSocket.ConnectInfo.DialogTitle="WebSocket-verbindingsinligting" +OBSWebSocket.ConnectInfo.CopyText="Kopieer" +OBSWebSocket.ConnectInfo.ServerIp="Bediener-IP (beste skatting)" +OBSWebSocket.ConnectInfo.ServerPort="Bedienerpoort" +OBSWebSocket.ConnectInfo.ServerPassword="Bedienerwagwoord" +OBSWebSocket.ConnectInfo.QrTitle="Koppel QR" +OBSWebSocket.TrayNotification.Identified.Title="Nuwe WebSocket-koppeling" +OBSWebSocket.TrayNotification.Identified.Body="Kliënt %1 geïdentifiseer." +OBSWebSocket.TrayNotification.AuthenticationFailed.Title="WebSocket-waarmerkfout" +OBSWebSocket.TrayNotification.AuthenticationFailed.Body="Kliënt %1 kon nie waarmerk nie." +OBSWebSocket.TrayNotification.Disconnected.Title="WebSocket-kliënt is ontkoppel" +OBSWebSocket.TrayNotification.Disconnected.Body="Kliënt %1 is ontkoppel." diff --git a/data/locale/ar-SA.ini b/data/locale/ar-SA.ini index 02fa87b19..7c84837b9 100644 --- a/data/locale/ar-SA.ini +++ b/data/locale/ar-SA.ini @@ -1,5 +1,5 @@ OBSWebSocket.Plugin.Description="التحكم عن بعد في استوديو OBS من خلال WebSocket" -OBSWebSocket.Settings.DialogTitle="إعدادات obs-websocket" +OBSWebSocket.Settings.DialogTitle="إعدادات خادم WebSocket" OBSWebSocket.Settings.PluginSettingsTitle="إعدادات الإضافات" OBSWebSocket.Settings.ServerEnable="تمكين خادم WebSocket" OBSWebSocket.Settings.AlertsEnable="تمكين تنبيهات شريط النظام" @@ -39,5 +39,3 @@ OBSWebSocket.TrayNotification.AuthenticationFailed.Title="فشل مصادقة We OBSWebSocket.TrayNotification.AuthenticationFailed.Body="فشل العميل %1 في المصادقة." OBSWebSocket.TrayNotification.Disconnected.Title="تم قطع اتصال عميل WebSocket" OBSWebSocket.TrayNotification.Disconnected.Body="العميل %1 قطع الاتصال." -OBSWebSocket.Server.StartFailed.Title="فشل خادم WebSocket" -OBSWebSocket.Server.StartFailed.Message="فشل تشغيل خادم WebSocket. قد يكون منفذ TCP %1 قيد الاستخدام في تطبيق آخر على هذا النظام. حاول تعيين منفذ TCP مختلف في إعدادات خادم WebSocket، أو إيقاف أي تطبيق يمكن أن يستخدم هذا المنفذ.\n رسالة الخطأ: %2" diff --git a/data/locale/ca-ES.ini b/data/locale/ca-ES.ini index 3e8ceac81..ee83625f5 100644 --- a/data/locale/ca-ES.ini +++ b/data/locale/ca-ES.ini @@ -1,10 +1,10 @@ -OBSWebSocket.Plugin.Description="Control remot de l'OBS Studio mitjançant un servidor web" -OBSWebSocket.Settings.DialogTitle="Configuració del servidor web de l'OBS" +OBSWebSocket.Plugin.Description="Control remot de l'OBS Studio mitjançant WebSocket" +OBSWebSocket.Settings.DialogTitle="Configuració del servidor WebSocket" OBSWebSocket.Settings.PluginSettingsTitle="Configuració del complement" -OBSWebSocket.Settings.ServerEnable="Habilita el servidor web" +OBSWebSocket.Settings.ServerEnable="Habilita el servidor WebSocket" OBSWebSocket.Settings.AlertsEnable="Habilita les notificacions a la barra de tasques" OBSWebSocket.Settings.DebugEnable="Habilita l'informe de depuració" -OBSWebSocket.Settings.DebugEnableHoverText="Habilita l'informe de depuració només per a la instància actual de l'OBS i no queda resident en inicis posteriors.\nUtilitzeu --websocket_debug si us cal que el canvi sigui persistent." +OBSWebSocket.Settings.DebugEnableHoverText="Habilita l'informe de depuració només per a la instància actual de l'OBS. No persisteix en inicis posteriors.\nUtilitzeu --websocket_debug si us cal que el canvi sigui persistent." OBSWebSocket.Settings.ServerSettingsTitle="Configuració del servidor" OBSWebSocket.Settings.AuthRequired="Habilita l'autenticació" OBSWebSocket.Settings.Password="Contrasenya del servidor" @@ -15,29 +15,27 @@ OBSWebSocket.Settings.ShowConnectInfoWarningTitle="Atenció: Actualment en direc OBSWebSocket.Settings.ShowConnectInfoWarningMessage="Sembla que una sortida (retransmissió, gravació, etc.) està actualment activa." OBSWebSocket.Settings.ShowConnectInfoWarningInfoText="Segur que voleu mostrar la vostra informació de connexió?" OBSWebSocket.Settings.Save.UserPasswordWarningTitle="Atenció: Risc potencial de seguretat" -OBSWebSocket.Settings.Save.UserPasswordWarningMessage="El servidor web del l'OBS (obs-websocket) emmagatzema la contrasenya del servidor com a text pla. És altament recomanable l'ús d'una contrasenya generada automàticament." +OBSWebSocket.Settings.Save.UserPasswordWarningMessage="obs-websocket emmagatzema la contrasenya del servidor com a text pla. És altament recomanable l'ús d'una contrasenya generada automàticament." OBSWebSocket.Settings.Save.UserPasswordWarningInfoText="Segur que voleu utilitzar la vostra contrasenya?" OBSWebSocket.Settings.Save.PasswordInvalidErrorTitle="Error: Configuració no vàlida" OBSWebSocket.Settings.Save.PasswordInvalidErrorMessage="Utilitzeu una contrasenya de 6 o més caràcters." -OBSWebSocket.SessionTable.Title="Sessions de servidor connectades" +OBSWebSocket.SessionTable.Title="Sessions de WebSocket connectades" OBSWebSocket.SessionTable.RemoteAddressColumnTitle="Adreça remota" OBSWebSocket.SessionTable.SessionDurationColumnTitle="Durada de la sessió" OBSWebSocket.SessionTable.MessagesInOutColumnTitle="Missatges d'entrada/sortida" OBSWebSocket.SessionTable.IdentifiedTitle="Identificat" -OBSWebSocket.SessionTable.KickButtonColumnTitle="Expulsió?" +OBSWebSocket.SessionTable.KickButtonColumnTitle="Expulsar?" OBSWebSocket.SessionTable.KickButtonText="Expulsa" -OBSWebSocket.ConnectInfo.DialogTitle="Informació de connexió del servidor Web (WebSocket)" +OBSWebSocket.ConnectInfo.DialogTitle="Informació de connexió del servidor WebSocket" OBSWebSocket.ConnectInfo.CopyText="Copia" OBSWebSocket.ConnectInfo.ServerIp="Adreça IP (més acurada)" OBSWebSocket.ConnectInfo.ServerPort="Port" OBSWebSocket.ConnectInfo.ServerPassword="Contrasenya" OBSWebSocket.ConnectInfo.ServerPasswordPlaceholderText="[Autenticació inhabilitada]" OBSWebSocket.ConnectInfo.QrTitle="QR de la connexió" -OBSWebSocket.TrayNotification.Identified.Title="Connexió nova de servidor Web (WebSocket)" +OBSWebSocket.TrayNotification.Identified.Title="Connexió nova de WebSocket" OBSWebSocket.TrayNotification.Identified.Body="Client %1 identificat." -OBSWebSocket.TrayNotification.AuthenticationFailed.Title="Ha fallat l'autenticació del servidor Web" +OBSWebSocket.TrayNotification.AuthenticationFailed.Title="Ha fallat l'autenticació del servidor WebSocket" OBSWebSocket.TrayNotification.AuthenticationFailed.Body="Ha fallat l'autenticació del client %1." -OBSWebSocket.TrayNotification.Disconnected.Title="Client desconnectat del servidor Web" +OBSWebSocket.TrayNotification.Disconnected.Title="Client desconnectat del servidor WebSocket" OBSWebSocket.TrayNotification.Disconnected.Body="Client %1 desconnectat." -OBSWebSocket.Server.StartFailed.Title="Ha fallat el servidor Web (WebSocket)" -OBSWebSocket.Server.StartFailed.Message="El servidor Web ha fallat en iniciar. Potser el port TCP %1 ja està en ús per altre programa del sistema. Proveu un port diferent a la configuració del servidor Web (WebSocket), o atureu qualsevol altra aplicació que pugui utilitzar aquest port.\n Missatge d'error: %2" diff --git a/data/locale/cs-CZ.ini b/data/locale/cs-CZ.ini index 698c63c67..427bac89c 100644 --- a/data/locale/cs-CZ.ini +++ b/data/locale/cs-CZ.ini @@ -1,5 +1,5 @@ OBSWebSocket.Plugin.Description="Vzdálené ovládání OBS Studia přes WebSocket" -OBSWebSocket.Settings.DialogTitle="Nastavení obs-websocket" +OBSWebSocket.Settings.DialogTitle="Nastavení WebSocket serveru" OBSWebSocket.Settings.PluginSettingsTitle="Nastavení pluginu" OBSWebSocket.Settings.ServerEnable="Povolit WebSocketový server" OBSWebSocket.Settings.AlertsEnable="Povolit upozornění v systémové liště" @@ -39,5 +39,3 @@ OBSWebSocket.TrayNotification.AuthenticationFailed.Title="Chyba přihlášení k OBSWebSocket.TrayNotification.AuthenticationFailed.Body="Klient %1 nebyl přihlášen" OBSWebSocket.TrayNotification.Disconnected.Title="WebSocket klient se odpojil" OBSWebSocket.TrayNotification.Disconnected.Body="Klient %1 se odpojil." -OBSWebSocket.Server.StartFailed.Title="Chyba WebSocket serveru" -OBSWebSocket.Server.StartFailed.Message="WebSocket server se nepodařilo spustit. TCP port %1 může být používán jinou aplikací. Zkuste nastavit jiný TCP port v nastavení WebSocket serveru nebo zavřete aplikaci, která může používat tento port.\n Chybová zpráva: %2" diff --git a/data/locale/da-DK.ini b/data/locale/da-DK.ini index 67b0f4841..9dc54f247 100644 --- a/data/locale/da-DK.ini +++ b/data/locale/da-DK.ini @@ -1,5 +1,4 @@ OBSWebSocket.Plugin.Description="Fjernstyring af OBS Studio via WebSocket" -OBSWebSocket.Settings.DialogTitle="obs-websocket Indstillinger" OBSWebSocket.Settings.PluginSettingsTitle="Plugin-indstillinger" OBSWebSocket.Settings.ServerEnable="Aktivér WebSocket-server" OBSWebSocket.Settings.AlertsEnable="Aktivér Systembakke Alarmer" @@ -39,5 +38,3 @@ OBSWebSocket.TrayNotification.AuthenticationFailed.Title="WebSocket godkendelses OBSWebSocket.TrayNotification.AuthenticationFailed.Body="Klienten %1 kunne ikke godkendes." OBSWebSocket.TrayNotification.Disconnected.Title="WebSocket-klient frakoblet" OBSWebSocket.TrayNotification.Disconnected.Body="Klient %1 frakoblet." -OBSWebSocket.Server.StartFailed.Title="WebSocket-serverfejl" -OBSWebSocket.Server.StartFailed.Message="WebSocket-serveren started ikke. TCP-port %1 bruges måske allerede på dette system af et andet program. Prøv at angive en anden TCP-port i WebSocket-serverindstillingerne, eller stop ethvert program, der kan bruge denne port.\n Fejlmeddelelse: %2" diff --git a/data/locale/de-DE.ini b/data/locale/de-DE.ini index fa1544517..446745615 100644 --- a/data/locale/de-DE.ini +++ b/data/locale/de-DE.ini @@ -1,10 +1,10 @@ OBSWebSocket.Plugin.Description="OBS Studio per WebSocket fernsteuern" -OBSWebSocket.Settings.DialogTitle="obs-websocket-Einstellungen" +OBSWebSocket.Settings.DialogTitle="WebSocket-Servereinstellungen" OBSWebSocket.Settings.PluginSettingsTitle="Plugineinstellungen" OBSWebSocket.Settings.ServerEnable="WebSocket-Server aktivieren" OBSWebSocket.Settings.AlertsEnable="Warnungen im Infobereich aktivieren" OBSWebSocket.Settings.DebugEnable="Debug-Logging aktivieren" -OBSWebSocket.Settings.DebugEnableHoverText="Aktiviert Debug-Logging für die aktuelle OBS-Instanz.\nVerwenden Sie „--websocket_debug“, damit die Option beim Laden aktiviert wird." +OBSWebSocket.Settings.DebugEnableHoverText="Aktiviert Debug-Logging für die aktuelle OBS-Instanz.\nVerwenden Sie „--websocket_debug“, damit die Option beim Starten aktiviert wird." OBSWebSocket.Settings.ServerSettingsTitle="Servereinstellungen" OBSWebSocket.Settings.AuthRequired="Authentifizierung aktivieren" OBSWebSocket.Settings.Password="Serverpasswort" @@ -28,7 +28,7 @@ OBSWebSocket.SessionTable.KickButtonColumnTitle="Entfernen?" OBSWebSocket.SessionTable.KickButtonText="Entfernen" OBSWebSocket.ConnectInfo.DialogTitle="WebSocket-Verbindungsinformationen" OBSWebSocket.ConnectInfo.CopyText="Kopieren" -OBSWebSocket.ConnectInfo.ServerIp="Server-IP (geschätzt)" +OBSWebSocket.ConnectInfo.ServerIp="Server-IP (Geschätzt)" OBSWebSocket.ConnectInfo.ServerPort="Serverport" OBSWebSocket.ConnectInfo.ServerPassword="Serverpasswort" OBSWebSocket.ConnectInfo.ServerPasswordPlaceholderText="Authentifizierung deaktiviert" @@ -39,5 +39,3 @@ OBSWebSocket.TrayNotification.AuthenticationFailed.Title="WebSocket-Authentifizi OBSWebSocket.TrayNotification.AuthenticationFailed.Body="Client %1 konnte sich nicht authentifizieren." OBSWebSocket.TrayNotification.Disconnected.Title="WebSocket-Client getrennt" OBSWebSocket.TrayNotification.Disconnected.Body="Client %1 getrennt." -OBSWebSocket.Server.StartFailed.Title="WebSocket-Serverfehler" -OBSWebSocket.Server.StartFailed.Message="Der WebSocket-Server konnte nicht gestartet werden, da der TCP-Port %1 möglicherweise benutzt wird. Versuchen Sie, den Port in den WebSocket-Servereinstellungen zu ändern oder Anwendungen zu schließen, die diesen verwenden könnten.\nFehler: %2" diff --git a/data/locale/el-GR.ini b/data/locale/el-GR.ini new file mode 100644 index 000000000..f2d563e5c --- /dev/null +++ b/data/locale/el-GR.ini @@ -0,0 +1,41 @@ +OBSWebSocket.Plugin.Description="Απομακρυσμένος έλεγχος του OBS Studio μέσω WebSocket" +OBSWebSocket.Settings.DialogTitle="Ρυθμίσεις Διακομιστή WebSocket" +OBSWebSocket.Settings.PluginSettingsTitle="Ρυθμίσεις Προσθέτων" +OBSWebSocket.Settings.ServerEnable="Ενεργοποίηση διακομιστή WebSocket" +OBSWebSocket.Settings.AlertsEnable="Ενεργοποίηση Ειδοποιήσεων στο System Tray" +OBSWebSocket.Settings.DebugEnable="Ενεργοποίηση καταγραφής σφαλμάτων" +OBSWebSocket.Settings.DebugEnableHoverText="Ενεργοποιεί την καταγραφή σφαλμάτων για την τρέχουσα εικόνα του OBS. Δεν επιμένει κατά τη φόρτωση.\nΧρησιμοποίησε το --websocket_debug για να ενεργοποιηθεί κατά τη φόρτωση." +OBSWebSocket.Settings.ServerSettingsTitle="Ρυθμίσεις Διακομιστή" +OBSWebSocket.Settings.AuthRequired="Ενεργοποίηση Επαλήθευσης Στοιχείων" +OBSWebSocket.Settings.Password="Κωδικός Διακομιστή" +OBSWebSocket.Settings.GeneratePassword="Δημιουργία Κωδικού" +OBSWebSocket.Settings.ServerPort="Θύρα Διακομιστή" +OBSWebSocket.Settings.ShowConnectInfo="Εμφάνιση Πληροφοριών Σύνδεσης" +OBSWebSocket.Settings.ShowConnectInfoWarningTitle="Προειδοποίηση: Ενεργό επί του Παρόντος" +OBSWebSocket.Settings.ShowConnectInfoWarningMessage="Φαίνεται ότι μια έξοδος (ροή, εγγραφή, κλπ.) είναι ενεργή αυτή τη στιγμή." +OBSWebSocket.Settings.ShowConnectInfoWarningInfoText="Είστε βέβαιοι ότι θέλετε να εμφανιστούν οι πληροφορίες σύνδεσης σας?" +OBSWebSocket.Settings.Save.UserPasswordWarningTitle="Προειδοποίηση: Πιθανό Πρόβλημα Ασφαλείας" +OBSWebSocket.Settings.Save.UserPasswordWarningMessage="Το obs-websocket αποθηκεύει τον κωδικό πρόσβασης του διακομιστή ως απλό κείμενο. Χρησιμοποιώντας έναν κωδικό πρόσβασης που δημιουργείται από το obs-websocket συνιστάται ιδιαίτερα." +OBSWebSocket.Settings.Save.UserPasswordWarningInfoText="Είστε βέβαιοι ότι θέλετε να χρησιμοποιήσετε το δικό σας κωδικό πρόσβασης?" +OBSWebSocket.Settings.Save.PasswordInvalidErrorTitle="Σφάλμα: Μη Έγκυρη Ρύθμιση" +OBSWebSocket.Settings.Save.PasswordInvalidErrorMessage="Πρέπει να χρησιμοποιήσετε έναν κωδικό πρόσβασης με 6 ή περισσότερους χαρακτήρες." +OBSWebSocket.SessionTable.Title="Συνδεδεμένες Συνεδρίες WebSocket" +OBSWebSocket.SessionTable.RemoteAddressColumnTitle="Απομακρυσμένη Διεύθυνση" +OBSWebSocket.SessionTable.SessionDurationColumnTitle="Διάρκεια Συνεδρίας" +OBSWebSocket.SessionTable.MessagesInOutColumnTitle="Εισερχόμενα/Εξερχόμενα Μηνύματα" +OBSWebSocket.SessionTable.IdentifiedTitle="Ταυτοποιήθηκε" +OBSWebSocket.SessionTable.KickButtonColumnTitle="Διακοπή?" +OBSWebSocket.SessionTable.KickButtonText="Διακοπή" +OBSWebSocket.ConnectInfo.DialogTitle="Πληροφορίες Σύνδεσης WebSocket" +OBSWebSocket.ConnectInfo.CopyText="Αντιγραφή" +OBSWebSocket.ConnectInfo.ServerIp="IP Διακομιστή (Βέλτιστη Εκτίμηση)" +OBSWebSocket.ConnectInfo.ServerPort="Θύρα Διακομιστή" +OBSWebSocket.ConnectInfo.ServerPassword="Κωδικός Διακομιστή" +OBSWebSocket.ConnectInfo.ServerPasswordPlaceholderText="[Ταυτοποίηση Απενεργοποιημένη]" +OBSWebSocket.ConnectInfo.QrTitle="Σύνδεση με QR" +OBSWebSocket.TrayNotification.Identified.Title="Νέα Σύνδεση WebSocket" +OBSWebSocket.TrayNotification.Identified.Body="Ο πελάτης %1 ταυτοποιήθηκε." +OBSWebSocket.TrayNotification.AuthenticationFailed.Title="Αποτυχία Ταυτοποίησης WebSocket" +OBSWebSocket.TrayNotification.AuthenticationFailed.Body="Αποτυχία ταυτοποίησης του πελάτη %1." +OBSWebSocket.TrayNotification.Disconnected.Title="Αποσυνδέθηκε ο Πελάτης του WebSocket" +OBSWebSocket.TrayNotification.Disconnected.Body="Ο πελάτης %1 αποσυνδέθηκε." diff --git a/data/locale/en-GB.ini b/data/locale/en-GB.ini new file mode 100644 index 000000000..4287ca861 --- /dev/null +++ b/data/locale/en-GB.ini @@ -0,0 +1 @@ +# \ No newline at end of file diff --git a/data/locale/en-US.ini b/data/locale/en-US.ini index 4fa99a15d..ea566aa92 100644 --- a/data/locale/en-US.ini +++ b/data/locale/en-US.ini @@ -45,6 +45,3 @@ OBSWebSocket.TrayNotification.AuthenticationFailed.Title="WebSocket Authenticati OBSWebSocket.TrayNotification.AuthenticationFailed.Body="Client %1 failed to authenticate." OBSWebSocket.TrayNotification.Disconnected.Title="WebSocket Client Disconnected" OBSWebSocket.TrayNotification.Disconnected.Body="Client %1 disconnected." - -OBSWebSocket.Server.StartFailed.Title="WebSocket Server Failure" -OBSWebSocket.Server.StartFailed.Message="The WebSocket server failed to start. TCP port %1 may already be in use elsewhere on this system by another application. Try setting a different TCP port in the WebSocket server settings, or stop any application that could be using this port.\n Error message: %2" diff --git a/data/locale/es-ES.ini b/data/locale/es-ES.ini index d32cb1926..0a08ee8b6 100644 --- a/data/locale/es-ES.ini +++ b/data/locale/es-ES.ini @@ -1,5 +1,5 @@ OBSWebSocket.Plugin.Description="Control remoto de OBS Studio a través de WebSocket" -OBSWebSocket.Settings.DialogTitle="Ajustes de obs-websocket" +OBSWebSocket.Settings.DialogTitle="Ajustes del servidor WebSocket" OBSWebSocket.Settings.PluginSettingsTitle="Ajustes del plugin" OBSWebSocket.Settings.ServerEnable="Habilitar servidor WebSocket" OBSWebSocket.Settings.AlertsEnable="Habilitar alertas en la bandeja del sistema" @@ -39,5 +39,3 @@ OBSWebSocket.TrayNotification.AuthenticationFailed.Title="Fallo de autenticació OBSWebSocket.TrayNotification.AuthenticationFailed.Body="El cliente %1 no se pudo autenticar." OBSWebSocket.TrayNotification.Disconnected.Title="Cliente WebSocket desconectado" OBSWebSocket.TrayNotification.Disconnected.Body="Cliente %1 desconectado." -OBSWebSocket.Server.StartFailed.Title="Fallo del servidor WebSocket" -OBSWebSocket.Server.StartFailed.Message="El servidor WebSocket no pudo iniciarse. El puerto TCP %1 puede que ya esté en uso en otro lugar de este sistema por otra aplicación. Intente configurar un puerto TCP diferente en la configuración del servidor WebSocket o detenga cualquier aplicación que pueda estar usando este puerto.\n Mensaje de error: %2" diff --git a/data/locale/et-EE.ini b/data/locale/et-EE.ini index 4d629666b..90535633b 100644 --- a/data/locale/et-EE.ini +++ b/data/locale/et-EE.ini @@ -1,5 +1,5 @@ OBSWebSocket.Plugin.Description="OBS Studio kaugjuhtimine WebSocketi kaudu" -OBSWebSocket.Settings.DialogTitle="obs-websocket seaded" +OBSWebSocket.Settings.DialogTitle="WebSocket serveri seaded" OBSWebSocket.Settings.PluginSettingsTitle="Plugina seaded" OBSWebSocket.Settings.ServerEnable="Luba WebSocket server" OBSWebSocket.Settings.AlertsEnable="Luba hoiatused tegumireal" @@ -39,5 +39,3 @@ OBSWebSocket.TrayNotification.AuthenticationFailed.Title="WebSocket autentimise OBSWebSocket.TrayNotification.AuthenticationFailed.Body="Kliendi %1 autentimine ebaõnnestus." OBSWebSocket.TrayNotification.Disconnected.Title="WebSocket kliendi ühendus katkenud" OBSWebSocket.TrayNotification.Disconnected.Body="Kliendi %1 ühendus katkenud." -OBSWebSocket.Server.StartFailed.Title="WebSocket serveri tõrge" -OBSWebSocket.Server.StartFailed.Message="WebSocket'i serveri käivitamine ebaõnnestus. TCP-port %1 võib olla juba mujal selles süsteemis mõne teise rakenduse poolt kasutusel. Proovige määrata WebSocket'i serveri seadetes teine TCP-port või peatada rakendus, mis võib seda porti kasutada.\n Veateade: %2" diff --git a/data/locale/eu-ES.ini b/data/locale/eu-ES.ini new file mode 100644 index 000000000..fb51248ad --- /dev/null +++ b/data/locale/eu-ES.ini @@ -0,0 +1,40 @@ +OBSWebSocket.Plugin.Description="OBS Studioren urruneko kontrolatzailea WebSocket-en bidez" +OBSWebSocket.Settings.PluginSettingsTitle="Plugin Ezarpenak" +OBSWebSocket.Settings.ServerEnable="WebSocket zerbitzaria gaitu" +OBSWebSocket.Settings.AlertsEnable="Aktibatu sistema-erretiluko alertak" +OBSWebSocket.Settings.DebugEnable="Gaitu arazketa erregistroa" +OBSWebSocket.Settings.DebugEnableHoverText="OBSren uneko instantzian arazketa erregistroa gaitzen du. Berriro irekitzerakoan ez da mantenduko . \nErabili --websocket_debug kargatzerakoan gaitzeko." +OBSWebSocket.Settings.ServerSettingsTitle="Zerbitzariaren Ezarpenak" +OBSWebSocket.Settings.AuthRequired="Autentifikazioa aktibatu" +OBSWebSocket.Settings.Password="Zerbitzari pasahitza" +OBSWebSocket.Settings.GeneratePassword="Pasahitza sortu" +OBSWebSocket.Settings.ServerPort="Zerbitzari portua" +OBSWebSocket.Settings.ShowConnectInfo="Konexio-informazioa erakutsi" +OBSWebSocket.Settings.ShowConnectInfoWarningTitle="Adi: Zuzenean zaude" +OBSWebSocket.Settings.ShowConnectInfoWarningMessage="Irteera bat (stream, grabazioa, etab.) aktibo dagoela badirudi." +OBSWebSocket.Settings.ShowConnectInfoWarningInfoText="Ziur zaude konexio-informazioa erakutsi nahi duzula?" +OBSWebSocket.Settings.Save.UserPasswordWarningTitle="Adi: Segurtasun arazo potentziala" +OBSWebSocket.Settings.Save.UserPasswordWarningMessage="obs-websocket-ek zerbitzariaren pasahitza testu sinple gisa gordetzen du. obs-websocket bidez sortutako pasahitza erabiltzea gomendatzen da." +OBSWebSocket.Settings.Save.UserPasswordWarningInfoText="Ziur zaude zure pasahitza erabili nahi duzula?" +OBSWebSocket.Settings.Save.PasswordInvalidErrorTitle="Errorea: konfigurazio baliogabea" +OBSWebSocket.Settings.Save.PasswordInvalidErrorMessage="6 karaktere edo gehiagoko pasahitza erabili behar duzu." +OBSWebSocket.SessionTable.Title="Konektatutako WebSocket saioak" +OBSWebSocket.SessionTable.RemoteAddressColumnTitle="Urruneko helbidea" +OBSWebSocket.SessionTable.SessionDurationColumnTitle="Saioaren iraupena" +OBSWebSocket.SessionTable.MessagesInOutColumnTitle="Sarrera-/irteera-mezuak" +OBSWebSocket.SessionTable.IdentifiedTitle="Identifikatuta" +OBSWebSocket.SessionTable.KickButtonColumnTitle="Kanporatu?" +OBSWebSocket.SessionTable.KickButtonText="Kanporatu" +OBSWebSocket.ConnectInfo.DialogTitle="WebSocket konexio-informazioa" +OBSWebSocket.ConnectInfo.CopyText="Kopiatu" +OBSWebSocket.ConnectInfo.ServerIp="Zerbitzariaren IP-a (proposamen hoberena)" +OBSWebSocket.ConnectInfo.ServerPort="Zerbitzari portua" +OBSWebSocket.ConnectInfo.ServerPassword="Zerbitzari pasahitza" +OBSWebSocket.ConnectInfo.ServerPasswordPlaceholderText="[Autorizazioa desgaituta]" +OBSWebSocket.ConnectInfo.QrTitle="Konexioaren QR kodea" +OBSWebSocket.TrayNotification.Identified.Title="WebSocket konexio berria" +OBSWebSocket.TrayNotification.Identified.Body="%1 bezeroa identifikatuta." +OBSWebSocket.TrayNotification.AuthenticationFailed.Title="WebSocket Autentikazioan hutsegitea" +OBSWebSocket.TrayNotification.AuthenticationFailed.Body="%1 bezeroak autentifikatzen huts egin du." +OBSWebSocket.TrayNotification.Disconnected.Title="WebSocket Bezeroa deskonektatu da" +OBSWebSocket.TrayNotification.Disconnected.Body="%1 bezeroa deskonektatu da." diff --git a/data/locale/fa-IR.ini b/data/locale/fa-IR.ini index 645c55936..3612906b1 100644 --- a/data/locale/fa-IR.ini +++ b/data/locale/fa-IR.ini @@ -1,5 +1,5 @@ OBSWebSocket.Plugin.Description="کنترل از راه دور OBS Studio از طریق WebSocket" -OBSWebSocket.Settings.DialogTitle="تنظیمات obs-سوکت وب" +OBSWebSocket.Settings.DialogTitle="تنظیمات سرور سوکت وب" OBSWebSocket.Settings.PluginSettingsTitle="تنظیمات پلاگین" OBSWebSocket.Settings.ServerEnable="سرور سوکت وب را فعال کنید" OBSWebSocket.Settings.AlertsEnable="هشدارهای سینی سیستم را فعال کنید" @@ -39,5 +39,3 @@ OBSWebSocket.TrayNotification.AuthenticationFailed.Title="خرابی تأیید OBSWebSocket.TrayNotification.AuthenticationFailed.Body="سرویس گیرنده %1 احراز هویت نشد." OBSWebSocket.TrayNotification.Disconnected.Title="سرویس گیرنده سوکت وب قطع شد" OBSWebSocket.TrayNotification.Disconnected.Body="سرویس گیرنده %1 قطع شد." -OBSWebSocket.Server.StartFailed.Title="خرابی سرور سوکت وب" -OBSWebSocket.Server.StartFailed.Message="سرور WebSocket راه‌اندازی نشد. درگاه TCP % 1 ممکن است قبلاً در جای دیگری در این سیستم توسط برنامه دیگری استفاده شده باشد. یک پورت TCP دیگر را در تنظیمات سرور WebSocket تنظیم کنید، یا هر برنامه‌ای را که می‌تواند از این پورت استفاده کند متوقف کنید.\n پیام خطا: %2" diff --git a/data/locale/fi-FI.ini b/data/locale/fi-FI.ini index ecfaffc33..275f24120 100644 --- a/data/locale/fi-FI.ini +++ b/data/locale/fi-FI.ini @@ -1,5 +1,5 @@ OBSWebSocket.Plugin.Description="OBS Studion etähallinta WebSocketin kautta" -OBSWebSocket.Settings.DialogTitle="obs-websocketin asetukset" +OBSWebSocket.Settings.DialogTitle="WebSocket-palvelimen asetukset" OBSWebSocket.Settings.PluginSettingsTitle="Liitännäisen asetukset" OBSWebSocket.Settings.ServerEnable="Ota WebSocket-palvelin käyttöön" OBSWebSocket.Settings.AlertsEnable="Ota ilmoitusalueen ilmoitukset käyttöön" @@ -39,5 +39,3 @@ OBSWebSocket.TrayNotification.AuthenticationFailed.Title="WebSocket-tunnistusvir OBSWebSocket.TrayNotification.AuthenticationFailed.Body="Asiakas %1 todennus epäonnistui." OBSWebSocket.TrayNotification.Disconnected.Title="WebSocket-asiakas katkaisi yhteyden" OBSWebSocket.TrayNotification.Disconnected.Body="Asiakas %1 on katkaistu." -OBSWebSocket.Server.StartFailed.Title="WebSocket-palvelinvirhe" -OBSWebSocket.Server.StartFailed.Message="WebSocket-palvelin ei käynnistynyt. TCP-portti %1 saattaa olla jo toisen sovelluksen käytössä. Yritä määrittää toinen TCP-portti WebSocket-palvelimen asetuksissa tai lopeta kaikki sovellukset, jotka saattavat käyttää tätä porttia.\nVirheilmoitus: %2" diff --git a/data/locale/fil-PH.ini b/data/locale/fil-PH.ini new file mode 100644 index 000000000..5c6f087ce --- /dev/null +++ b/data/locale/fil-PH.ini @@ -0,0 +1,37 @@ +OBSWebSocket.Plugin.Description="Remote-control ng OBS Studio sa pamamagitan ng WebSocket" +OBSWebSocket.Settings.DialogTitle="Mga Setting Ng WebSocket Server" +OBSWebSocket.Settings.PluginSettingsTitle="Mga Setting ng Plugin" +OBSWebSocket.Settings.ServerEnable="Paganahin ang WebSocket server" +OBSWebSocket.Settings.AlertsEnable="Paganahin ang System Tray Alerto" +OBSWebSocket.Settings.DebugEnable="Paganahin ang Debug Log" +OBSWebSocket.Settings.DebugEnableHoverText="Paganahin ang debug log para sa kasalukuyang instance ng OBS. Hindi nagpapatuloy sa pag-load.\nGumamit ng --websocket_debug upang paganahin ang pag-load." +OBSWebSocket.Settings.ServerSettingsTitle="Mga setting ng Server" +OBSWebSocket.Settings.AuthRequired="Paggamit ng Pagpapatunay" +OBSWebSocket.Settings.Password="Password ng server" +OBSWebSocket.Settings.GeneratePassword="Mag-Generate ng Password" +OBSWebSocket.Settings.ShowConnectInfo="Ipakita ang Impormasyon sa Pagkonekta" +OBSWebSocket.Settings.ShowConnectInfoWarningTitle="Babala: Kasalukuyang nakalive" +OBSWebSocket.Settings.ShowConnectInfoWarningMessage="Lumalabas na kasalukuyang aktibo ang isang output (stream, recording, atbp.)." +OBSWebSocket.Settings.ShowConnectInfoWarningInfoText="Sigurado ka bang gusto mong ipakita ang iyong impormasyon sa pagkonekta?" +OBSWebSocket.Settings.Save.UserPasswordWarningTitle="Babala: Potensyal na Isyu sa Seguridad" +OBSWebSocket.Settings.Save.UserPasswordWarningMessage="Iniimbak ng obs-websocket ang password ng server bilang plain text. Ang paggamit ng password na nabuo ng obs-websocket ay lubos na inirerekomenda." +OBSWebSocket.Settings.Save.UserPasswordWarningInfoText="Sigurado ka bang gusto mong gamitin ang iyong sariling password?" +OBSWebSocket.Settings.Save.PasswordInvalidErrorTitle="Error: Di-wastong Configuration" +OBSWebSocket.Settings.Save.PasswordInvalidErrorMessage="Dapat kang gumamit ng password na 6 o higit pang mga character." +OBSWebSocket.SessionTable.Title="Nakakonektang WebSocket Session" +OBSWebSocket.SessionTable.SessionDurationColumnTitle="Tagal ng Session" +OBSWebSocket.SessionTable.MessagesInOutColumnTitle="Mga Mensahe In/Out" +OBSWebSocket.SessionTable.IdentifiedTitle="Kilalanin." +OBSWebSocket.SessionTable.KickButtonColumnTitle="Sipa?" +OBSWebSocket.SessionTable.KickButtonText="Sipa" +OBSWebSocket.ConnectInfo.DialogTitle="Impormasyon ng WebSocket Connect" +OBSWebSocket.ConnectInfo.CopyText="Kopyahin" +OBSWebSocket.ConnectInfo.ServerPassword="Password ng server" +OBSWebSocket.ConnectInfo.ServerPasswordPlaceholderText="[Naka-disable ang Auth]" +OBSWebSocket.ConnectInfo.QrTitle="Ikonekta ang QR" +OBSWebSocket.TrayNotification.Identified.Title="Bagong Koneksyon sa WebSocket" +OBSWebSocket.TrayNotification.Identified.Body="Natukoy ang %1 ng kliyente." +OBSWebSocket.TrayNotification.AuthenticationFailed.Title="Nabigo sa Pagpapatunay ang WebSocket" +OBSWebSocket.TrayNotification.AuthenticationFailed.Body="Nabigo ang kliyenteng %1 na patotohanan." +OBSWebSocket.TrayNotification.Disconnected.Title="Nadiskonekta ang WebSocket Client" +OBSWebSocket.TrayNotification.Disconnected.Body="Nadiskonekta ang kliyenteng %1." diff --git a/data/locale/fr-FR.ini b/data/locale/fr-FR.ini index 034274ea6..2bc4ce72d 100644 --- a/data/locale/fr-FR.ini +++ b/data/locale/fr-FR.ini @@ -1,5 +1,5 @@ OBSWebSocket.Plugin.Description="Contrôle à distance d'OBS Studio via WebSocket" -OBSWebSocket.Settings.DialogTitle="Paramètre du websocket obs" +OBSWebSocket.Settings.DialogTitle="Paramètres du serveur WebSocket" OBSWebSocket.Settings.PluginSettingsTitle="Paramètres du plugin" OBSWebSocket.Settings.ServerEnable="Activer le serveur WebSocket" OBSWebSocket.Settings.AlertsEnable="Activer les alertes de la zone de notification" @@ -16,9 +16,9 @@ OBSWebSocket.Settings.ShowConnectInfoWarningMessage="Il semble qu'une sortie (st OBSWebSocket.Settings.ShowConnectInfoWarningInfoText="Êtes-vous sûr de vouloir afficher vos informations de connexion ?" OBSWebSocket.Settings.Save.UserPasswordWarningTitle="Avertissement : Problème potentiel de sécurité" OBSWebSocket.Settings.Save.UserPasswordWarningMessage="obs-websocket enregistre le mot de passe du serveur en texte brut. L'utilisation d'un mot de passe généré par obs-websocket est fortement recommandée." -OBSWebSocket.Settings.Save.UserPasswordWarningInfoText="Êtes-vous sûr de vouloir utiliser votre propre mot de passe ?" +OBSWebSocket.Settings.Save.UserPasswordWarningInfoText="Êtes-vous sûr(e) de vouloir utiliser votre propre mot de passe ?" OBSWebSocket.Settings.Save.PasswordInvalidErrorTitle="Erreur : Configuration invalide" -OBSWebSocket.Settings.Save.PasswordInvalidErrorMessage="Vous devez utiliser un mot de passe d'au moins 6 caractères" +OBSWebSocket.Settings.Save.PasswordInvalidErrorMessage="Vous devez utiliser un mot de passe de 6 caractères ou plus." OBSWebSocket.SessionTable.Title="Sessions WebSocket connectées" OBSWebSocket.SessionTable.RemoteAddressColumnTitle="Adresse distante" OBSWebSocket.SessionTable.SessionDurationColumnTitle="Durée de session" @@ -30,7 +30,7 @@ OBSWebSocket.ConnectInfo.DialogTitle="Informations de connexion WebSocket" OBSWebSocket.ConnectInfo.CopyText="Copier" OBSWebSocket.ConnectInfo.ServerIp="IP du serveur (meilleure estimation)" OBSWebSocket.ConnectInfo.ServerPort="Port serveur" -OBSWebSocket.ConnectInfo.ServerPassword="Mot de passe serveur" +OBSWebSocket.ConnectInfo.ServerPassword="Mot de passe du serveur" OBSWebSocket.ConnectInfo.ServerPasswordPlaceholderText="[Authentification désactivée]" OBSWebSocket.ConnectInfo.QrTitle="QR code de connexion" OBSWebSocket.TrayNotification.Identified.Title="Nouvelle connexion WebSocket" @@ -39,5 +39,3 @@ OBSWebSocket.TrayNotification.AuthenticationFailed.Title="Échec de l'authentifi OBSWebSocket.TrayNotification.AuthenticationFailed.Body="Échec d'authentification du client %1." OBSWebSocket.TrayNotification.Disconnected.Title="Client WebSocket déconnecté" OBSWebSocket.TrayNotification.Disconnected.Body="Client %1 déconnecté." -OBSWebSocket.Server.StartFailed.Title="Échec du serveur WebSocket" -OBSWebSocket.Server.StartFailed.Message="Le serveur WebSocket n'a pas pu démarrer. Le port TCP %1 est peut être déjà utilisé par une autre application ailleurs sur ce système. Essayez de définir un port TCP différent dans les paramètres du serveur WebSocket, ou arrêtez toute application qui pourrait utiliser ce port.\n Message d'erreur : %2" diff --git a/data/locale/gl-ES.ini b/data/locale/gl-ES.ini new file mode 100644 index 000000000..8da4fac4b --- /dev/null +++ b/data/locale/gl-ES.ini @@ -0,0 +1,6 @@ +OBSWebSocket.Settings.ServerSettingsTitle="Configuración do servidor" +OBSWebSocket.ConnectInfo.CopyText="Copiar" +OBSWebSocket.ConnectInfo.ServerPort="Porto do Servidor" +OBSWebSocket.ConnectInfo.ServerPassword="Contrasinal do Servidor" +OBSWebSocket.TrayNotification.Identified.Body="Cliente %1 identificado." +OBSWebSocket.TrayNotification.Disconnected.Body="Cliente %1 desconectado." diff --git a/data/locale/he-IL.ini b/data/locale/he-IL.ini index c094b6818..21391971f 100644 --- a/data/locale/he-IL.ini +++ b/data/locale/he-IL.ini @@ -1,5 +1,5 @@ OBSWebSocket.Plugin.Description="שליטה מרחוק על OBS Studio באמצעות WebSocket" -OBSWebSocket.Settings.DialogTitle="הגדרות obs-websocket" +OBSWebSocket.Settings.DialogTitle="הגדרות שרת WebSocket" OBSWebSocket.Settings.PluginSettingsTitle="הגדרות תוסף" OBSWebSocket.Settings.ServerEnable="הפעלת שרת WebSocket" OBSWebSocket.Settings.AlertsEnable="הפעלת התראות במגש המערכת" @@ -39,5 +39,3 @@ OBSWebSocket.TrayNotification.AuthenticationFailed.Title="אימות WebSocket OBSWebSocket.TrayNotification.AuthenticationFailed.Body="לקוח %1 נכשל באימות" OBSWebSocket.TrayNotification.Disconnected.Title="לקוח WebSocket התנתק" OBSWebSocket.TrayNotification.Disconnected.Body="לקוח %1 התנתק." -OBSWebSocket.Server.StartFailed.Title="שגיאת שרת WebSocket" -OBSWebSocket.Server.StartFailed.Message="שרת ה-WebSocket נכשל בהפעלה. ייתכן שפורט TCP %1 כבר נמצא בשימוש במקום אחר במערכת זו על ידי יישום אחר. יש לנסות להגדיר פורט TCP אחר בהגדרות שרת WebSocket, או לעצור כל יישום שעשוי להשתמש בפורט זה.\nהודעת שגיאה: %2" diff --git a/data/locale/hi-IN.ini b/data/locale/hi-IN.ini index 97db030e7..5d46d1024 100644 --- a/data/locale/hi-IN.ini +++ b/data/locale/hi-IN.ini @@ -1,5 +1,5 @@ OBSWebSocket.Plugin.Description="WebSocket के माध्यम से OBS स्टूडियो का रिमोट-कंट्रोल" -OBSWebSocket.Settings.DialogTitle="obs-websocket सेटिंग्स" +OBSWebSocket.Settings.DialogTitle="वेबसॉकेट सर्वर सेटिंग्स" OBSWebSocket.Settings.PluginSettingsTitle="प्लगइन सेटिंग्स" OBSWebSocket.Settings.ServerEnable="WebSocket सर्वर सक्षम करें" OBSWebSocket.Settings.AlertsEnable="सिस्टम ट्रे अलर्ट सक्षम करें" @@ -39,5 +39,3 @@ OBSWebSocket.TrayNotification.AuthenticationFailed.Title="WebSocket सत्य OBSWebSocket.TrayNotification.AuthenticationFailed.Body="क्लाइंट %1प्रमाणित करने में विफल रहा." OBSWebSocket.TrayNotification.Disconnected.Title="वेबसॉकेट क्लाइंट डिस्कनेक्ट हो गया" OBSWebSocket.TrayNotification.Disconnected.Body="क्लाइंट %1 डिस्कनेक्ट हो गया." -OBSWebSocket.Server.StartFailed.Title="वेबसॉकेट सर्वर विफलता" -OBSWebSocket.Server.StartFailed.Message="WebSocket सर्वर प्रारंभ करने में विफल रहा. TCP पोर्ट %1 पहले से ही इस सिस्टम पर किसी अन्य एप्लिकेशन द्वारा कहीं और उपयोग में हो सकता है. वेबसॉकेट सर्वर सेटिंग्स में एक अलग TCP पोर्ट सेट करने का प्रयास करें, या इस पोर्ट का उपयोग करने वाले किसी भी एप्लिकेशन को रोकें.\n त्रुटि संदेश : %2" diff --git a/data/locale/hr-HR.ini b/data/locale/hr-HR.ini new file mode 100644 index 000000000..97319ec80 --- /dev/null +++ b/data/locale/hr-HR.ini @@ -0,0 +1,10 @@ +OBSWebSocket.Settings.DialogTitle="Postavke servera WebSocket" +OBSWebSocket.Settings.Save.PasswordInvalidErrorTitle="Pogreška: Neispravna konfiguracija" +OBSWebSocket.Settings.Save.PasswordInvalidErrorMessage="Lozinka mora sadržavati barem 6 znakova." +OBSWebSocket.SessionTable.Title="Spojene sesije WebSocketa" +OBSWebSocket.SessionTable.RemoteAddressColumnTitle="Udaljena adresa" +OBSWebSocket.SessionTable.SessionDurationColumnTitle="Trajanje sesije" +OBSWebSocket.SessionTable.MessagesInOutColumnTitle="Ulaz/izlaz poruka" +OBSWebSocket.ConnectInfo.CopyText="Kopiraj" +OBSWebSocket.ConnectInfo.ServerPort="Vrata servera" +OBSWebSocket.ConnectInfo.ServerPassword="Lozinka servera" diff --git a/data/locale/hu-HU.ini b/data/locale/hu-HU.ini index 738572e3a..d23c52263 100644 --- a/data/locale/hu-HU.ini +++ b/data/locale/hu-HU.ini @@ -1,5 +1,5 @@ OBSWebSocket.Plugin.Description="Az OBS Studio távvezérlése WebSocketen keresztül" -OBSWebSocket.Settings.DialogTitle="Az obs-websocket beállításai" +OBSWebSocket.Settings.DialogTitle="WebSocket-kiszolgáló beállításai" OBSWebSocket.Settings.PluginSettingsTitle="Bővítménybeállítások" OBSWebSocket.Settings.ServerEnable="WebSocket-kiszolgáló engedélyezése" OBSWebSocket.Settings.AlertsEnable="Rendszertálca-riasztások bekapcsolása" @@ -39,5 +39,3 @@ OBSWebSocket.TrayNotification.AuthenticationFailed.Title="WebSocket hitelesíté OBSWebSocket.TrayNotification.AuthenticationFailed.Body="A(z) %1 kliens hitelesítése sikertelen." OBSWebSocket.TrayNotification.Disconnected.Title="A WebSocket-kliens bontotta a kapcsolatot" OBSWebSocket.TrayNotification.Disconnected.Body="A(z) %1 kliens bontotta a kapcsolatot" -OBSWebSocket.Server.StartFailed.Title="WebSocket kiszolgálóhiba" -OBSWebSocket.Server.StartFailed.Message="A WebSocket-kiszolgáló nem tudott elindulni. A(z) %1 TCP-portot lehet, hogy már egy másik alkalmazás használja. Próbáljon eltérő TCP-portot beállítani a WebSocket-kiszolgáló beállítasaiban, vagy állítson le minden olyan alkalmazást, amely ezt a portot használhatja.\n Hibaüzenet: %2" diff --git a/data/locale/hy-AM.ini b/data/locale/hy-AM.ini index 55d577fef..ae58bf609 100644 --- a/data/locale/hy-AM.ini +++ b/data/locale/hy-AM.ini @@ -1,5 +1,5 @@ OBSWebSocket.Plugin.Description="OBS Studio-ի հեռակառավարումը WebSocket-ի միջոցով" -OBSWebSocket.Settings.DialogTitle="obs-websocket կարգավորումներ" +OBSWebSocket.Settings.DialogTitle="WebSocket Սպասարկչի Կարգավորումները" OBSWebSocket.Settings.PluginSettingsTitle="Միացնիչի կարգավորումներ" OBSWebSocket.Settings.ServerEnable="Միացնել WebSocket սերվերը" OBSWebSocket.Settings.AlertsEnable="Միացնել սկուտեղի ծանուցումները" @@ -39,5 +39,3 @@ OBSWebSocket.TrayNotification.AuthenticationFailed.Title="WebSocket վավերա OBSWebSocket.TrayNotification.AuthenticationFailed.Body="%1 հաճախորդը չհաջողվեց նույնականացնել:" OBSWebSocket.TrayNotification.Disconnected.Title="WebSocket հաճախորդն անջատված է" OBSWebSocket.TrayNotification.Disconnected.Body="%1 հաճախորդն անջատվել է:" -OBSWebSocket.Server.StartFailed.Title="WebSocket սերվերի սխալ" -OBSWebSocket.Server.StartFailed.Message="Չհաջողվեց գործարկել WebSockt սերվերը: Հնարավոր է, որ TCP %1 պորտն արդեն օգտագործվում է մեկ այլ հավելվածի կողմից: Փորձեք կարգավորել այլ TCP պորտ WebSocket սերվերի կարգավորումներում կամ դադարեցնել ցանկացած ծրագիր, որը կարող է օգտագործել այս պորտը:\n Սխալի հաղորդագրություն՝ %2։" diff --git a/data/locale/id-ID.ini b/data/locale/id-ID.ini index fc9727240..1c74f264e 100644 --- a/data/locale/id-ID.ini +++ b/data/locale/id-ID.ini @@ -1,5 +1,5 @@ OBSWebSocket.Plugin.Description="Kendali jarak jauh OBS Studio melalui WebSocket" -OBSWebSocket.Settings.DialogTitle="Pengaturan obs-websocket" +OBSWebSocket.Settings.DialogTitle="Pengaturan Server WebSocket" OBSWebSocket.Settings.PluginSettingsTitle="Pengaturan Plugin" OBSWebSocket.Settings.ServerEnable="Aktifkan server WebSocket" OBSWebSocket.Settings.AlertsEnable="Aktifkan Peringatan Baki Sistem" @@ -39,5 +39,3 @@ OBSWebSocket.TrayNotification.AuthenticationFailed.Title="Autentikasi WebSocket OBSWebSocket.TrayNotification.AuthenticationFailed.Body="Klien %1 gagal mengautentikasi." OBSWebSocket.TrayNotification.Disconnected.Title="Klien WebSocket Terputus" OBSWebSocket.TrayNotification.Disconnected.Body="Klien %1 terputus." -OBSWebSocket.Server.StartFailed.Title="Server WebSocket Gagal" -OBSWebSocket.Server.StartFailed.Message="Server WebSocket gagal untuk memulai. Port TCP %1 mungkin sudah digunakan siapa pun pada sistem ini oleh aplikasi lain. Coba atur port TCP yang berbeda di pengaturan server WebSocket, atau hentikan aplikasi apapun yang bisa menggunakan port ini.\n Pesan galat: %2" diff --git a/data/locale/it-IT.ini b/data/locale/it-IT.ini index 6b1177e08..9b88e2504 100644 --- a/data/locale/it-IT.ini +++ b/data/locale/it-IT.ini @@ -1,5 +1,5 @@ OBSWebSocket.Plugin.Description="Controllo remoto di OBS Studio tramite WebSocket" -OBSWebSocket.Settings.DialogTitle="Impostazioni obs-websocket" +OBSWebSocket.Settings.DialogTitle="Impostazioni server WebSocket" OBSWebSocket.Settings.PluginSettingsTitle="Impostazioni del plugin" OBSWebSocket.Settings.ServerEnable="Abilita il server WebSocket" OBSWebSocket.Settings.AlertsEnable="Abilita avvisi sulla barra delle applicazioni" @@ -39,5 +39,3 @@ OBSWebSocket.TrayNotification.AuthenticationFailed.Title="Errore di autenticazio OBSWebSocket.TrayNotification.AuthenticationFailed.Body="Il client %1 non è riuscito ad autenticarsi." OBSWebSocket.TrayNotification.Disconnected.Title="Client WebSocket disconnesso" OBSWebSocket.TrayNotification.Disconnected.Body="Client %1 disconnesso." -OBSWebSocket.Server.StartFailed.Title="Errore del server WebSocket" -OBSWebSocket.Server.StartFailed.Message="Impossibile avviare il server WebSocket.\nLa porta TCP %1 potrebbe essere già usata in questo sistema da un'altra applicazione.\nProva a impostare nelle impostazioni del server WebSocket una porta TCP diversa oppure interrompi qualsiasi applicazione che potrebbe usare questa porta.\nMessaggio di errore: %2." diff --git a/data/locale/ja-JP.ini b/data/locale/ja-JP.ini index a564b6a01..c646b0290 100644 --- a/data/locale/ja-JP.ini +++ b/data/locale/ja-JP.ini @@ -1,5 +1,5 @@ OBSWebSocket.Plugin.Description="WebSocketを介したOBS Studioのリモートコントロール" -OBSWebSocket.Settings.DialogTitle="obs-websocket設定" +OBSWebSocket.Settings.DialogTitle="WebSocket サーバー設定" OBSWebSocket.Settings.PluginSettingsTitle="プラグイン設定" OBSWebSocket.Settings.ServerEnable="WebSocketサーバーを有効にする" OBSWebSocket.Settings.AlertsEnable="システムトレイアラートを有効にする" @@ -39,5 +39,3 @@ OBSWebSocket.TrayNotification.AuthenticationFailed.Title="WebSocket認証失敗" OBSWebSocket.TrayNotification.AuthenticationFailed.Body="クライアント %1 の認証に失敗しました。" OBSWebSocket.TrayNotification.Disconnected.Title="WebSocketクライアントが切断されました" OBSWebSocket.TrayNotification.Disconnected.Body="クライアント %1 が切断されました。" -OBSWebSocket.Server.StartFailed.Title="WebSocketサーバー障害" -OBSWebSocket.Server.StartFailed.Message="WebSocketサーバーの起動に失敗しました。TCPポート %1 はこのシステム上の他の場所で別のアプリケーションによって既に使用されている可能性があります。 WebSocketサーバーの設定で別のTCPポートを設定するか、このポートを使用している可能性のあるアプリケーションを終了してください。\n エラーメッセージ: %2" diff --git a/data/locale/ka-GE.ini b/data/locale/ka-GE.ini index ce912e0f5..d862cb0be 100644 --- a/data/locale/ka-GE.ini +++ b/data/locale/ka-GE.ini @@ -1,5 +1,5 @@ OBSWebSocket.Plugin.Description="OBS Studio-ს დაშორებულად მართვა WebSocket-ით" -OBSWebSocket.Settings.DialogTitle="obs-websocket-პარამეტრები" +OBSWebSocket.Settings.DialogTitle="WebSocket-სერვერის პარამეტრები" OBSWebSocket.Settings.PluginSettingsTitle="მოდულის პარამეტრები" OBSWebSocket.Settings.ServerEnable="WebSocket-სერვერის ჩართვა" OBSWebSocket.Settings.AlertsEnable="სისტემური არეში ცნობების ჩართვა" @@ -14,7 +14,7 @@ OBSWebSocket.Settings.ShowConnectInfo="კავშირის შესახ OBSWebSocket.Settings.ShowConnectInfoWarningTitle="გაფრთხილება: პირდაპირ ეთერშია" OBSWebSocket.Settings.ShowConnectInfoWarningMessage="როგორც ჩანს, გამოტანა (ნაკადის, ჩანაწერის და სხვ.) ეთერში გადის." OBSWebSocket.Settings.ShowConnectInfoWarningInfoText="ნამდვილად გსურთ კავშირის მონაცემების გამოჩენა?" -OBSWebSocket.Settings.Save.UserPasswordWarningTitle="ყურადღება: უსაფრთხოების შესაძლო სისუსტე" +OBSWebSocket.Settings.Save.UserPasswordWarningTitle="ყურადღება: სავარაუდო საფრთხე" OBSWebSocket.Settings.Save.UserPasswordWarningMessage="obs-websocket სერვერის პაროლს ტექსტის სახით. დაჟინებით გირჩევთ, გამოიყენოთ obs-websocket-ით შედგენილი პაროლი." OBSWebSocket.Settings.Save.UserPasswordWarningInfoText="ნამდვილად გსურთ საკუთარი პაროლის გამოყენება?" OBSWebSocket.Settings.Save.PasswordInvalidErrorTitle="შეცდომა: არასწორი გამართვა" @@ -39,5 +39,3 @@ OBSWebSocket.TrayNotification.AuthenticationFailed.Title="WebSocket-შესვ OBSWebSocket.TrayNotification.AuthenticationFailed.Body="კლიენტი %1 ვერ დამოწმდა." OBSWebSocket.TrayNotification.Disconnected.Title="WebSocket-კლიენტი გამოითიშა" OBSWebSocket.TrayNotification.Disconnected.Body="კლიენტი %1 გამოთიშეულია." -OBSWebSocket.Server.StartFailed.Title="WebSocket-სერვერის ხარვეზი" -OBSWebSocket.Server.StartFailed.Message="WebSocket-სერვერი ვერ ამუშავდა. TCP-პორტი %1 შეიძლება უკვე გამოიყენება სისტემაში სხვა პროგამის მიერ. მოსინჯეთ განსხვავებული TCP-პორტი WebSocket-სერვერის პარამეტრებში ან გათიშეთ ყველა პროგრამა, რომელიც ამ პორტს უნდა იყენებდეს.\n შეცდომის აღწერა: %2" diff --git a/data/locale/kmr-TR.ini b/data/locale/kmr-TR.ini index 900ccf8c9..a545ed3ec 100644 --- a/data/locale/kmr-TR.ini +++ b/data/locale/kmr-TR.ini @@ -1,5 +1,5 @@ OBSWebSocket.Plugin.Description="Rêveberina ji dûr ve ya OBS Studio bi riya WebSocket" -OBSWebSocket.Settings.DialogTitle="Sazkariyên obs-websocket" +OBSWebSocket.Settings.DialogTitle="Sazkariyên rajekar a WebSocket" OBSWebSocket.Settings.PluginSettingsTitle="Sazkariyên pêvekê" OBSWebSocket.Settings.ServerEnable="Rajekarê WebSocket çalak bike" OBSWebSocket.Settings.AlertsEnable="Hişyariyên darika pergalê çalak bike" @@ -39,5 +39,3 @@ OBSWebSocket.TrayNotification.AuthenticationFailed.Title="Rastandina WebSocket t OBSWebSocket.TrayNotification.AuthenticationFailed.Body="Rastandina rajegir %1 têk çû." OBSWebSocket.TrayNotification.Disconnected.Title="Girêdana rajegira WebSocket qut bû" OBSWebSocket.TrayNotification.Disconnected.Body="Girêdana rajegir %1 qut bû." -OBSWebSocket.Server.StartFailed.Title="Rajekara WebSocket têk çû" -OBSWebSocket.Server.StartFailed.Message="Destpêkirina rajekara WebSocket têk çû. Dibe ku dergeha TCP %1 jixwe ji hêla sepaneke din ve li cîhek din li ser vê pergalê were bikaranîn. Kontrol bike ku di sazkariyên rajekara WebSocket de dergehek TCP a cuda saz bikî, an jî sepanek ku dikare vê dergehê bi kar bîne rawestîne.\n Peyama çewtiyê: %2" diff --git a/data/locale/ko-KR.ini b/data/locale/ko-KR.ini index 3f788f8ad..e7eec6914 100644 --- a/data/locale/ko-KR.ini +++ b/data/locale/ko-KR.ini @@ -1,5 +1,5 @@ OBSWebSocket.Plugin.Description="WebSocket으로 OBS Studio를 원격 제어" -OBSWebSocket.Settings.DialogTitle="obs-websocket 설정" +OBSWebSocket.Settings.DialogTitle="WebSocket 서버 설정" OBSWebSocket.Settings.PluginSettingsTitle="플러그인 설정" OBSWebSocket.Settings.ServerEnable="WebSocket 서버 사용" OBSWebSocket.Settings.AlertsEnable="시스템 트레이 알림 사용" @@ -39,5 +39,3 @@ OBSWebSocket.TrayNotification.AuthenticationFailed.Title="WebSocket 인증 실 OBSWebSocket.TrayNotification.AuthenticationFailed.Body="클라이언트 %1 인증 실패." OBSWebSocket.TrayNotification.Disconnected.Title="WebSocket 클라이언트 연결 해제됨" OBSWebSocket.TrayNotification.Disconnected.Body="클라이언트 %1 연결 해제됨." -OBSWebSocket.Server.StartFailed.Title="WebSocket 서버 기동 실패" -OBSWebSocket.Server.StartFailed.Message="WebSocket 서버를 시작하는 데 실패했습니다. %1 TCP 포트가 타 응용 프로그램에 의해 이 시스템에서 이미 사용 중일 수 있습니다. WebSocket 서버 설정에서 다른 TCP 포트로 변경하거나 이 포트를 사용하는 응용 프로그램을 종료하십시오.\n 오류 메시지: %2" diff --git a/data/locale/ms-MY.ini b/data/locale/ms-MY.ini index 4a608684a..288b11ff6 100644 --- a/data/locale/ms-MY.ini +++ b/data/locale/ms-MY.ini @@ -1,5 +1,5 @@ OBSWebSocket.Plugin.Description="Kawalan-jauh OBS Studio melalui WebSocket" -OBSWebSocket.Settings.DialogTitle="Tetapan obs-websocket" +OBSWebSocket.Settings.DialogTitle="Tetapan Pelayan WebSocket" OBSWebSocket.Settings.PluginSettingsTitle="Tetapan Pemalam" OBSWebSocket.Settings.ServerEnable="Benarkan pelayan WebSocket" OBSWebSocket.Settings.AlertsEnable="Benarkan Amaran Talam Sistem" @@ -39,5 +39,3 @@ OBSWebSocket.TrayNotification.AuthenticationFailed.Title="Kegagalan Pengesahihan OBSWebSocket.TrayNotification.AuthenticationFailed.Body="Klien %1 gagal disahihkan." OBSWebSocket.TrayNotification.Disconnected.Title="Klien WebSocket Terputus" OBSWebSocket.TrayNotification.Disconnected.Body="Klien %1 terputus." -OBSWebSocket.Server.StartFailed.Title="Kegagalan Pelayan WebSocket" -OBSWebSocket.Server.StartFailed.Message="Pelayan WebSocket gagal dimulakan. Port TCP %1 mungkin telah digunakan di tempat lain dalam sistem ini oleh aplikasi lain. Cuba tetapkan port TCP lain dalam tetapan pelayan WebSocket, atau hentikan mana-mana aplikasi yang guna port tersebut.\n Mesej ralat: %2" diff --git a/data/locale/nb-NO.ini b/data/locale/nb-NO.ini new file mode 100644 index 000000000..c624773e3 --- /dev/null +++ b/data/locale/nb-NO.ini @@ -0,0 +1,25 @@ +OBSWebSocket.Settings.DialogTitle="WebSocket-tjenerinnstillinger" +OBSWebSocket.Settings.PluginSettingsTitle="Utvidelsesinnstillinger" +OBSWebSocket.Settings.ServerSettingsTitle="Tjenerinnstillinger" +OBSWebSocket.Settings.AuthRequired="Skru på autentisering" +OBSWebSocket.Settings.Password="Server Passord" +OBSWebSocket.Settings.GeneratePassword="Generer Passord" +OBSWebSocket.Settings.ShowConnectInfo="Vis tilkoblingsinfo" +OBSWebSocket.Settings.ShowConnectInfoWarningTitle="Advarsel: For øyeblikket på direktesending" +OBSWebSocket.Settings.Save.UserPasswordWarningTitle="Advarsel: Potensielt sikkerhetsproblem" +OBSWebSocket.Settings.Save.PasswordInvalidErrorTitle="Feil: Ugyldig konfigurasjon" +OBSWebSocket.Settings.Save.PasswordInvalidErrorMessage="Du må bruke et passord på minst 6 tegn." +OBSWebSocket.SessionTable.RemoteAddressColumnTitle="Ekstern adresse" +OBSWebSocket.SessionTable.SessionDurationColumnTitle="Øktens varighet" +OBSWebSocket.SessionTable.MessagesInOutColumnTitle="Innboks/Utboks" +OBSWebSocket.SessionTable.IdentifiedTitle="Identifisert" +OBSWebSocket.ConnectInfo.DialogTitle="WebSocket-tilkoblingsinfo" +OBSWebSocket.ConnectInfo.CopyText="Kopier" +OBSWebSocket.ConnectInfo.ServerIp="Tjenerens IP (beste gjetning)" +OBSWebSocket.ConnectInfo.ServerPort="Tjenerport" +OBSWebSocket.ConnectInfo.ServerPassword="Tjenerpassord" +OBSWebSocket.ConnectInfo.QrTitle="QR-tilkobling" +OBSWebSocket.TrayNotification.Identified.Title="Ny WebSocket-tilkobling" +OBSWebSocket.TrayNotification.Identified.Body="Klient %1 er identifisert." +OBSWebSocket.TrayNotification.Disconnected.Title="WebSocket-klient koblet fra" +OBSWebSocket.TrayNotification.Disconnected.Body="Klient %1 koblet fra." diff --git a/data/locale/nl-NL.ini b/data/locale/nl-NL.ini index 99cd330db..e6e998485 100644 --- a/data/locale/nl-NL.ini +++ b/data/locale/nl-NL.ini @@ -1,5 +1,5 @@ OBSWebSocket.Plugin.Description="Op afstand bediening van OBS Studio via WebSocket" -OBSWebSocket.Settings.DialogTitle="obs-websocket Instellingen" +OBSWebSocket.Settings.DialogTitle="WebSocket Server Instellingen" OBSWebSocket.Settings.PluginSettingsTitle="Plugin instellingen" OBSWebSocket.Settings.ServerEnable="WebSocket server inschakelen" OBSWebSocket.Settings.AlertsEnable="Systeemtray meldingen inschakelen" @@ -30,6 +30,7 @@ OBSWebSocket.ConnectInfo.DialogTitle="WebSocket verbindingsinformatie" OBSWebSocket.ConnectInfo.CopyText="Kopiëren" OBSWebSocket.ConnectInfo.ServerIp="Server IP (Beste inschatting)" OBSWebSocket.ConnectInfo.ServerPort="Serverpoort" +OBSWebSocket.ConnectInfo.ServerPassword="Serverwachtwoord" OBSWebSocket.ConnectInfo.ServerPasswordPlaceholderText="[Authenticatie Uitgeschakeld]" OBSWebSocket.ConnectInfo.QrTitle="QR koppelen" OBSWebSocket.TrayNotification.Identified.Title="Nieuwe WebSocket verbinding" @@ -38,5 +39,3 @@ OBSWebSocket.TrayNotification.AuthenticationFailed.Title="WebSocket Authenticati OBSWebSocket.TrayNotification.AuthenticationFailed.Body="Authenticatie van client %1 mislukt." OBSWebSocket.TrayNotification.Disconnected.Title="WebSocket Client losgekoppeld" OBSWebSocket.TrayNotification.Disconnected.Body="Client %1 ontkoppeld." -OBSWebSocket.Server.StartFailed.Title="WebSocket Server fout" -OBSWebSocket.Server.StartFailed.Message="De WebSocket server kon niet worden gestart. TCP-poort %1 is mogelijk al in gebruik op dit systeem door een andere toepassing. Probeer een andere TCP-poort in te stellen in de WebSocket server-instellingen, of stop elke toepassing die deze poort zou kunnen gebruiken.\n Foutmelding: %2" diff --git a/data/locale/pl-PL.ini b/data/locale/pl-PL.ini index 41405334a..985b578ea 100644 --- a/data/locale/pl-PL.ini +++ b/data/locale/pl-PL.ini @@ -1,5 +1,5 @@ OBSWebSocket.Plugin.Description="Zdalna kontrola OBS Studio przez WebSocket" -OBSWebSocket.Settings.DialogTitle="Ustawienia obs-websocket" +OBSWebSocket.Settings.DialogTitle="Ustawienia serwera WebSocket" OBSWebSocket.Settings.PluginSettingsTitle="Ustawienia wtyczki" OBSWebSocket.Settings.ServerEnable="Włącz serwer WebSocket" OBSWebSocket.Settings.AlertsEnable="Włącz powiadomienia w zasobniku systemowym" @@ -39,5 +39,3 @@ OBSWebSocket.TrayNotification.AuthenticationFailed.Title="Błąd uwierzytelniani OBSWebSocket.TrayNotification.AuthenticationFailed.Body="Klient %1 nie został uwierzytelniony." OBSWebSocket.TrayNotification.Disconnected.Title="Klient WebSocket odłączony" OBSWebSocket.TrayNotification.Disconnected.Body="Klient %1 odłączony." -OBSWebSocket.Server.StartFailed.Title="Błąd serwera WebSocket" -OBSWebSocket.Server.StartFailed.Message="Nie udało się uruchomić serwera WebSocket. Port TCP %1 może być już używany w innym miejscu tego systemu przez inną aplikację. Spróbuj ustawić inny port TCP w ustawieniach serwera WebSocket lub zatrzymaj aplikację, która może korzystać z tego portu.\n Komunikat błędu: %2" diff --git a/data/locale/pt-BR.ini b/data/locale/pt-BR.ini index 85caf38e4..dd0cd3154 100644 --- a/data/locale/pt-BR.ini +++ b/data/locale/pt-BR.ini @@ -1,5 +1,5 @@ OBSWebSocket.Plugin.Description="Controle remoto do OBS Studio através de WebSocket" -OBSWebSocket.Settings.DialogTitle="Configurações OBS-WebSocket" +OBSWebSocket.Settings.DialogTitle="Configurações do servidor WebSocket" OBSWebSocket.Settings.PluginSettingsTitle="Configurações de Plugin" OBSWebSocket.Settings.ServerEnable="Ativar servidor WebSocket" OBSWebSocket.Settings.AlertsEnable="Ativar Alertas da Bandeja do Sistema" @@ -39,5 +39,3 @@ OBSWebSocket.TrayNotification.AuthenticationFailed.Title="Falha na Autenticaçã OBSWebSocket.TrayNotification.AuthenticationFailed.Body="Cliente %1 falhou na autenticação." OBSWebSocket.TrayNotification.Disconnected.Title="Cliente WebSocket Desconectado" OBSWebSocket.TrayNotification.Disconnected.Body="Cliente %1 desconectado." -OBSWebSocket.Server.StartFailed.Title="Falha no Servidor WebSocket" -OBSWebSocket.Server.StartFailed.Message="O servidor de WebSocket falhou ao iniciar. A porta TCP %1 já pode estar em uso em outro lugar neste sistema por outro aplicativo. Tente definir uma porta TCP diferente nas configurações do servidor de WebSocket, ou pare qualquer aplicativo que possa estar usando essa porta.\n Mensagem de erro: %2" diff --git a/data/locale/pt-PT.ini b/data/locale/pt-PT.ini index 0a6568068..3c32447dd 100644 --- a/data/locale/pt-PT.ini +++ b/data/locale/pt-PT.ini @@ -1,5 +1,5 @@ OBSWebSocket.Plugin.Description="Controlo remoto do OBS Studio através de WebSocket" -OBSWebSocket.Settings.DialogTitle="Configurações obs-websocket" +OBSWebSocket.Settings.DialogTitle="Definições do servidor WebSocket" OBSWebSocket.Settings.PluginSettingsTitle="Configurações do plugin" OBSWebSocket.Settings.ServerEnable="Ativar servidor WebSocket" OBSWebSocket.Settings.AlertsEnable="Ativar alertas da bandeja do sistema" @@ -39,5 +39,3 @@ OBSWebSocket.TrayNotification.AuthenticationFailed.Title="Falha na autenticaçã OBSWebSocket.TrayNotification.AuthenticationFailed.Body="Cliente %1 falhou na autenticação." OBSWebSocket.TrayNotification.Disconnected.Title="Cliente WebSocket desligado" OBSWebSocket.TrayNotification.Disconnected.Body="Cliente %1 desligado." -OBSWebSocket.Server.StartFailed.Title="Falha no servidor WebSocket" -OBSWebSocket.Server.StartFailed.Message="O servidor de WebSocket falhou ao iniciar. A porta TCP %1 pode já estar em uso noutro local deste sistema por outra aplicação. Tente definir uma porta TCP diferente nas configurações do servidor de WebSocket, ou pare qualquer aplicação que possa estar a usar essa porta.\n Mensagem de erro: %2" diff --git a/data/locale/ro-RO.ini b/data/locale/ro-RO.ini index d3015a342..c5a7a69f4 100644 --- a/data/locale/ro-RO.ini +++ b/data/locale/ro-RO.ini @@ -1,16 +1,16 @@ OBSWebSocket.Plugin.Description="Control de la distanță pentru OBS Studio prin WebSocket" -OBSWebSocket.Settings.DialogTitle="Setări obs-websocket" -OBSWebSocket.Settings.PluginSettingsTitle="Setări ale plugin-ului" +OBSWebSocket.Settings.DialogTitle="Setări pentru serverul WebSocket" +OBSWebSocket.Settings.PluginSettingsTitle="Setări pentru plugin" OBSWebSocket.Settings.ServerEnable="Activează serverul WebSocket" -OBSWebSocket.Settings.AlertsEnable="Activați alertele din bara de sistem" -OBSWebSocket.Settings.DebugEnable="Activează jurnalizarea de depanare" -OBSWebSocket.Settings.DebugEnableHoverText="Activează jurnalizarea de depanare pentru instanța curentă de OBS. Nu persistă la încărcare.\nUtilizați --websocket_debug pentru a activa la încărcare." -OBSWebSocket.Settings.ServerSettingsTitle="Setări server" +OBSWebSocket.Settings.AlertsEnable="Activează alertele din bara de sistem" +OBSWebSocket.Settings.DebugEnable="Activează jurnalizarea pentru depanare" +OBSWebSocket.Settings.DebugEnableHoverText="Activează jurnalizarea pentru depanare în cazul instanței actuale de OBS. Nu persistă la încărcare.\nFolosește --websocket_debug pentru a activa la încărcare." +OBSWebSocket.Settings.ServerSettingsTitle="Setări pentru server" OBSWebSocket.Settings.AuthRequired="Activează autentificarea" OBSWebSocket.Settings.Password="Parola serverului" OBSWebSocket.Settings.GeneratePassword="Generează parola" OBSWebSocket.Settings.ServerPort="Portul serverului" -OBSWebSocket.Settings.ShowConnectInfo="Afișează informațiile de conectare" +OBSWebSocket.Settings.ShowConnectInfo="Afișează informațiile conexiunii" OBSWebSocket.Settings.ShowConnectInfoWarningTitle="Avertisment: În prezent în direct" OBSWebSocket.Settings.ShowConnectInfoWarningMessage="Se pare că un output (transmisiune, înregistrare etc.) este activ în prezent." OBSWebSocket.Settings.ShowConnectInfoWarningInfoText="Sigur vrei să afișezi informațiile de conectare?" @@ -24,20 +24,18 @@ OBSWebSocket.SessionTable.RemoteAddressColumnTitle="Adresă la distanță" OBSWebSocket.SessionTable.SessionDurationColumnTitle="Durata sesiunii" OBSWebSocket.SessionTable.MessagesInOutColumnTitle="Mesaje de intrare/ieșire" OBSWebSocket.SessionTable.IdentifiedTitle="Identificat" -OBSWebSocket.SessionTable.KickButtonColumnTitle="Înlătură?" +OBSWebSocket.SessionTable.KickButtonColumnTitle="Înlături?" OBSWebSocket.SessionTable.KickButtonText="Înlătură" -OBSWebSocket.ConnectInfo.DialogTitle="Informații de conectare WebSocket" +OBSWebSocket.ConnectInfo.DialogTitle="Informațiile conexiunii WebSocket" OBSWebSocket.ConnectInfo.CopyText="Copiază" OBSWebSocket.ConnectInfo.ServerIp="IP-ul serverului (cea mai bună presupunere)" OBSWebSocket.ConnectInfo.ServerPort="Portul serverului" OBSWebSocket.ConnectInfo.ServerPassword="Parola serverului" OBSWebSocket.ConnectInfo.ServerPasswordPlaceholderText="[Autentificare dezactivată]" -OBSWebSocket.ConnectInfo.QrTitle="Conectare QR" +OBSWebSocket.ConnectInfo.QrTitle="QR de conectare" OBSWebSocket.TrayNotification.Identified.Title="O nouă conexiune WebSocket" -OBSWebSocket.TrayNotification.Identified.Body="Client %1 identificat." +OBSWebSocket.TrayNotification.Identified.Body="Clientul %1 identificat." OBSWebSocket.TrayNotification.AuthenticationFailed.Title="Eroare de autentificare WebSocket" OBSWebSocket.TrayNotification.AuthenticationFailed.Body="Client %1 nu a reușit să se autentifice." OBSWebSocket.TrayNotification.Disconnected.Title="Client WebSocket deconectat" OBSWebSocket.TrayNotification.Disconnected.Body="Clientul %1 s-a deconectat." -OBSWebSocket.Server.StartFailed.Title="Eroare de server WebSocket" -OBSWebSocket.Server.StartFailed.Message="Serverul WebSocket nu a reușit să pornească. Este posibil ca portul TCP %1 să fie deja utilizat în altă parte pe acest sistem de o altă aplicație. Încearcă să setezi un alt port TCP în setările serverului WebSocket sau oprește orice aplicație care ar putea utiliza acest port.\n Mesaj de eroare: %2" diff --git a/data/locale/ru-RU.ini b/data/locale/ru-RU.ini index aa8fb1444..3978a38e5 100644 --- a/data/locale/ru-RU.ini +++ b/data/locale/ru-RU.ini @@ -1,18 +1,18 @@ OBSWebSocket.Plugin.Description="Удалённое управление OBS Studio по WebSocket" -OBSWebSocket.Settings.DialogTitle="Настройки obs-websocket" +OBSWebSocket.Settings.DialogTitle="Настройки сервера WebSocket" OBSWebSocket.Settings.PluginSettingsTitle="Настройки плагина" OBSWebSocket.Settings.ServerEnable="Включить сервер WebSocket" OBSWebSocket.Settings.AlertsEnable="Включить оповещения в трее" OBSWebSocket.Settings.DebugEnable="Включить отладочный журнал" OBSWebSocket.Settings.DebugEnableHoverText="Включает ведение журнала отладки для текущего экземпляра OBS. Не сохраняется при запуске.\nИспользуйте --websocket_debug для включения при запуске." OBSWebSocket.Settings.ServerSettingsTitle="Настройки сервера" -OBSWebSocket.Settings.AuthRequired="Включить аутентификацию" +OBSWebSocket.Settings.AuthRequired="Включить вход в аккаунт" OBSWebSocket.Settings.Password="Пароль сервера" -OBSWebSocket.Settings.GeneratePassword="Сгенерировать пароль" +OBSWebSocket.Settings.GeneratePassword="Создать пароль" OBSWebSocket.Settings.ServerPort="Порт сервера" OBSWebSocket.Settings.ShowConnectInfo="Показать сведения о подключении" OBSWebSocket.Settings.ShowConnectInfoWarningTitle="Предупреждение: Сейчас в эфире" -OBSWebSocket.Settings.ShowConnectInfoWarningMessage="Похоже, что вывод (поток, запись и т. д.) в настоящее время активен." +OBSWebSocket.Settings.ShowConnectInfoWarningMessage="Похоже, что вывод (поток, запись и т. д.) в настоящее время уже выбран." OBSWebSocket.Settings.ShowConnectInfoWarningInfoText="Уверены, что хотите показать ваши сведения о подключении?" OBSWebSocket.Settings.Save.UserPasswordWarningTitle="Предупреждение: Потенциальная проблема безопасности" OBSWebSocket.Settings.Save.UserPasswordWarningMessage="obs-websocket хранит пароль сервера в виде обычного текста. Настоятельно рекомендуется использовать пароль, сгенерированный obs-websock." @@ -31,13 +31,11 @@ OBSWebSocket.ConnectInfo.CopyText="Копировать" OBSWebSocket.ConnectInfo.ServerIp="IP сервера (лучшая догадка)" OBSWebSocket.ConnectInfo.ServerPort="Порт сервера" OBSWebSocket.ConnectInfo.ServerPassword="Пароль сервера" -OBSWebSocket.ConnectInfo.ServerPasswordPlaceholderText="[Авторизация отключена]" +OBSWebSocket.ConnectInfo.ServerPasswordPlaceholderText="[Вход отключён]" OBSWebSocket.ConnectInfo.QrTitle="QR-код подключения" OBSWebSocket.TrayNotification.Identified.Title="Новое подключение WebSocket" OBSWebSocket.TrayNotification.Identified.Body="Клиент %1 распознан." -OBSWebSocket.TrayNotification.AuthenticationFailed.Title="Ошибка аутентификации WebSocket" -OBSWebSocket.TrayNotification.AuthenticationFailed.Body="Клиент %1 не смог аутентифицироваться." +OBSWebSocket.TrayNotification.AuthenticationFailed.Title="Ошибка входа WebSocket" +OBSWebSocket.TrayNotification.AuthenticationFailed.Body="Клиент %1 не смог войти." OBSWebSocket.TrayNotification.Disconnected.Title="Клиент WebSocket отключился" OBSWebSocket.TrayNotification.Disconnected.Body="Клиент %1 отключился." -OBSWebSocket.Server.StartFailed.Title="Ошибка сервера WebSocket" -OBSWebSocket.Server.StartFailed.Message="Не удалось запустить сервер WebSockt. Возможно, порт TCP %1 уже используется другим приложением. Попробуйте установить другой TCP-порт в настройках сервера WebSocket или остановите любое приложение, которое может использовать этот порт.\n Сообщение ошибки: %2" diff --git a/data/locale/si-LK.ini b/data/locale/si-LK.ini index fcd2f2177..ca8c0ee21 100644 --- a/data/locale/si-LK.ini +++ b/data/locale/si-LK.ini @@ -1,4 +1,5 @@ OBSWebSocket.Settings.PluginSettingsTitle="පේනුවේ සැකසුම්" +OBSWebSocket.Settings.DebugEnable="නිදොස්කරණ සටහන් තැබීම සබල කරන්න" OBSWebSocket.Settings.ServerSettingsTitle="සේවාදායකයේ සැකසුම්" OBSWebSocket.Settings.AuthRequired="සත්‍යාපනය සබල කරන්න" OBSWebSocket.Settings.Password="සේවාදායකයේ මුරපදය" @@ -11,6 +12,7 @@ OBSWebSocket.SessionTable.SessionDurationColumnTitle="වාරයේ පරා OBSWebSocket.SessionTable.MessagesInOutColumnTitle="පණිවිඩ එන/යන" OBSWebSocket.SessionTable.IdentifiedTitle="හඳුනා ගැනිණි" OBSWebSocket.ConnectInfo.CopyText="පිටපතක්" +OBSWebSocket.ConnectInfo.ServerIp="සේවාදායකයේ අ.ජා.කෙ. (අනුමානය)" OBSWebSocket.ConnectInfo.ServerPort="සේවාදායකයේ තොට" OBSWebSocket.ConnectInfo.ServerPassword="සේවාදායකයේ මුරපදය" OBSWebSocket.ConnectInfo.ServerPasswordPlaceholderText="[සත්‍යාපනය අබලයි]" diff --git a/data/locale/sk-SK.ini b/data/locale/sk-SK.ini index 5768b4fe6..f79fd7448 100644 --- a/data/locale/sk-SK.ini +++ b/data/locale/sk-SK.ini @@ -1,5 +1,5 @@ OBSWebSocket.Plugin.Description="Vzdialené ovládanie OBS Štúdia cez WebSocket" -OBSWebSocket.Settings.DialogTitle="Nastavenia obs-websocket" +OBSWebSocket.Settings.DialogTitle="Serverové nastavenia WebSocket" OBSWebSocket.Settings.PluginSettingsTitle="Nastavenia pluginu" OBSWebSocket.Settings.ServerEnable="Zapnúť WebSocket server" OBSWebSocket.Settings.AlertsEnable="Zapnúť notifikácie zo systémovej lišty" @@ -39,5 +39,3 @@ OBSWebSocket.TrayNotification.AuthenticationFailed.Title="Zlyhanie WebSocket aut OBSWebSocket.TrayNotification.AuthenticationFailed.Body="Klientovi %1 sa nepodarilo autentifikovať." OBSWebSocket.TrayNotification.Disconnected.Title="WebSocket klient odpojený" OBSWebSocket.TrayNotification.Disconnected.Body="Klient %1 odpojený." -OBSWebSocket.Server.StartFailed.Title="Zlyhanie WebSocket servera" -OBSWebSocket.Server.StartFailed.Message="WebSocket server zlyhal pri spustení. TCP port %1 sa môže používať na inom mieste, na tomto systéme, inou aplikáciou. Skúste nastaviť iný TCP port v nastaveniach WebSocket servera, alebo zastavte iné aplikácie, ktoré by mohli používať tento port.\n Chybová správa: %2" diff --git a/data/locale/sl-SI.ini b/data/locale/sl-SI.ini index 21e40ea7d..b379bca0c 100644 --- a/data/locale/sl-SI.ini +++ b/data/locale/sl-SI.ini @@ -1,5 +1,5 @@ OBSWebSocket.Plugin.Description="Oddaljeni nadzor OBS Studia prek WebSocketa" -OBSWebSocket.Settings.DialogTitle="Nastavitve obs-websocket" +OBSWebSocket.Settings.DialogTitle="Nastavitve strežnika WebSocket" OBSWebSocket.Settings.PluginSettingsTitle="Nastavitve vtičnika" OBSWebSocket.Settings.ServerEnable="Omogoči strežnik WebSocket" OBSWebSocket.Settings.AlertsEnable="Omogoči opozorila v sistemskem pladnju" @@ -39,5 +39,3 @@ OBSWebSocket.TrayNotification.AuthenticationFailed.Title="Spodletelo ovetjanje W OBSWebSocket.TrayNotification.AuthenticationFailed.Body="Odjemalec %1 ni prestal overjanja." OBSWebSocket.TrayNotification.Disconnected.Title="Odjemalec WebSocket je prekinil povezavo" OBSWebSocket.TrayNotification.Disconnected.Body="Odjemalec %1 ni več povezan." -OBSWebSocket.Server.StartFailed.Title="Odpoved strežnika WebSocket" -OBSWebSocket.Server.StartFailed.Message="Strežnik WebSocket se ni uspel zagnati. Vrata TCP %1 morda že uporablja drug program na tem sistemu. Poskusite določiti druga vrata TCP v nastavitvah strežnika WebSocket ali pa ustaviti program, ki bi lahko uporabljal želena vrata.\nSporočilo o napaki: %2" diff --git a/data/locale/sv-SE.ini b/data/locale/sv-SE.ini index fff8bd958..48ad3beae 100644 --- a/data/locale/sv-SE.ini +++ b/data/locale/sv-SE.ini @@ -1,5 +1,5 @@ OBSWebSocket.Plugin.Description="Fjärrkontroll av OBS Studio via WebSocket" -OBSWebSocket.Settings.DialogTitle="Inställningar för obs-websocket" +OBSWebSocket.Settings.DialogTitle="WebSocket-serverinställningar" OBSWebSocket.Settings.PluginSettingsTitle="Insticksmodulsinställningar" OBSWebSocket.Settings.ServerEnable="Aktivera WebSocket-server" OBSWebSocket.Settings.AlertsEnable="Aktivera systemfältsmeddelanden" @@ -39,5 +39,3 @@ OBSWebSocket.TrayNotification.AuthenticationFailed.Title="Autentisering av WebSo OBSWebSocket.TrayNotification.AuthenticationFailed.Body="Klient %1 misslyckades att autentiseras." OBSWebSocket.TrayNotification.Disconnected.Title="WebSocket-klient frånkopplades" OBSWebSocket.TrayNotification.Disconnected.Body="Klient %1 frånkopplades." -OBSWebSocket.Server.StartFailed.Title="WebSocket-serverfel" -OBSWebSocket.Server.StartFailed.Message="WebSocket-servern kunde inte startaw. TCP-porten %1 kanske redan används någon annanstans på detta system av ett annat program. Prova att ange en annan TCP-port i WebSocket-serverinställningarna eller stoppa alla program som kan använda denna port.\n Felmeddelande: %2" diff --git a/data/locale/tr-TR.ini b/data/locale/tr-TR.ini index 76209a5f6..3936c570d 100644 --- a/data/locale/tr-TR.ini +++ b/data/locale/tr-TR.ini @@ -1,5 +1,5 @@ OBSWebSocket.Plugin.Description="WebSocket aracılığıyla uzaktan OBS Studio" -OBSWebSocket.Settings.DialogTitle="obs-websocket Ayarları" +OBSWebSocket.Settings.DialogTitle="WebSocket Suncusu Ayarları" OBSWebSocket.Settings.PluginSettingsTitle="Eklenti Ayarları" OBSWebSocket.Settings.ServerEnable="WebSocket sunucuyu etkinleştir" OBSWebSocket.Settings.AlertsEnable="Sistem Tepsi Uyarılarını Etkinleştir" @@ -29,7 +29,7 @@ OBSWebSocket.SessionTable.KickButtonText="Çıkar" OBSWebSocket.ConnectInfo.DialogTitle="WebSocket Bağlanma Bilgileri" OBSWebSocket.ConnectInfo.CopyText="Kopyala" OBSWebSocket.ConnectInfo.ServerIp="Sunucu IP (En İyi Tahmin)" -OBSWebSocket.ConnectInfo.ServerPort="Sunucu Kapısı" +OBSWebSocket.ConnectInfo.ServerPort="Sunucu Portu" OBSWebSocket.ConnectInfo.ServerPassword="Sunucu Parolası" OBSWebSocket.ConnectInfo.ServerPasswordPlaceholderText="[Doğrulama Devre Dışı]" OBSWebSocket.ConnectInfo.QrTitle="Kare Kod ile Bağlan" @@ -39,5 +39,3 @@ OBSWebSocket.TrayNotification.AuthenticationFailed.Title="WebSocket Kimlik Doğr OBSWebSocket.TrayNotification.AuthenticationFailed.Body="%1 istemcisinin kimlik doğrulaması başarısız oldu." OBSWebSocket.TrayNotification.Disconnected.Title="WebSocket İstemcisinin Bağlantısı Kesildi" OBSWebSocket.TrayNotification.Disconnected.Body="%1 istemcisinin bağlantısı kesildi." -OBSWebSocket.Server.StartFailed.Title="WebSocket Sunucu Hatası" -OBSWebSocket.Server.StartFailed.Message="WebSocket sunucusu başlatılamadı. %1 TCP kapısı bu sistemde başka bir yerde başka bir uygulama tarafından zaten kullanılıyor olabilir. WebSocket sunucu ayarlarında farklı bir TCP kapısı ayarlamayı deneyin, veya bu kapıyı kullanıyor olabilecek herhangi bir uygulamayı durdurun.\n Hata mesajı: %2" diff --git a/data/locale/uk-UA.ini b/data/locale/uk-UA.ini index 7b7fedc13..a2ec4be9f 100644 --- a/data/locale/uk-UA.ini +++ b/data/locale/uk-UA.ini @@ -1,5 +1,5 @@ OBSWebSocket.Plugin.Description="Віддалене керування OBS Studio через WebSocket" -OBSWebSocket.Settings.DialogTitle="Налаштування obs-websocket" +OBSWebSocket.Settings.DialogTitle="Налаштування WebSocket сервера" OBSWebSocket.Settings.PluginSettingsTitle="Налаштування плагіна" OBSWebSocket.Settings.ServerEnable="Увімкнути сервер WebSocket" OBSWebSocket.Settings.AlertsEnable="Увімкнути сповіщення у системному лотку" @@ -39,5 +39,3 @@ OBSWebSocket.TrayNotification.AuthenticationFailed.Title="Помилка авт OBSWebSocket.TrayNotification.AuthenticationFailed.Body="Клієнт %1 не зміг автентифікуватися." OBSWebSocket.TrayNotification.Disconnected.Title="Клієнт WebSocket від'єднаний" OBSWebSocket.TrayNotification.Disconnected.Body="Клієнт %1 від'єднаний." -OBSWebSocket.Server.StartFailed.Title="Помилка сервера WebSocket" -OBSWebSocket.Server.StartFailed.Message="Не вдалося запустити сервер WebSocket. Порт TCP %1 може вже використовуватися в іншому місці цим системним інтерфейсом. Спробуйте встановити інший TCP порт в налаштуваннях WebSocket сервера або зупинити будь-які застосунки, які можуть використовувати цей порт.\n Повідомлення про помилку: %2" diff --git a/data/locale/vi-VN.ini b/data/locale/vi-VN.ini index 799843f14..a1105583c 100644 --- a/data/locale/vi-VN.ini +++ b/data/locale/vi-VN.ini @@ -1,7 +1,37 @@ +OBSWebSocket.Plugin.Description="Điều khiển từ xa OBS Studio thông qua WebSocket" +OBSWebSocket.Settings.DialogTitle="Cài đặt máy chủ WebSocket" OBSWebSocket.Settings.PluginSettingsTitle="Thiết đặt trình cắm" OBSWebSocket.Settings.ServerEnable="Bật máy chủ WebSocket" +OBSWebSocket.Settings.AlertsEnable="Bật cảnh báo khay hệ thống" +OBSWebSocket.Settings.DebugEnable="Bật ghi nhật ký gỡ lỗi" +OBSWebSocket.Settings.DebugEnableHoverText="Cho phép ghi nhật ký gỡ lỗi cho phiên bản OBS hiện tại. Không tồn tại khi tải.\nUde --websocket gỡ lỗi để bật khi tải." OBSWebSocket.Settings.ServerSettingsTitle="Thiết đặt máy chủ" +OBSWebSocket.Settings.AuthRequired="Bật xác thực" OBSWebSocket.Settings.Password="Mật khẩu máy chủ" OBSWebSocket.Settings.GeneratePassword="Tạo mật khẩu" OBSWebSocket.Settings.ServerPort="Cổng máy chủ" OBSWebSocket.Settings.ShowConnectInfo="Hiện thông tin kết nối" +OBSWebSocket.Settings.ShowConnectInfoWarningTitle="Cảnh báo: Hiện đang chạy" +OBSWebSocket.Settings.ShowConnectInfoWarningMessage="Có vẻ như một đầu ra (luồng, bản ghi, v.v.) hiện đang hoạt động." +OBSWebSocket.Settings.ShowConnectInfoWarningInfoText="Bạn có chắc chắn muốn hiển thị thông tin kết nối của mình không?" +OBSWebSocket.Settings.Save.UserPasswordWarningTitle="Cảnh báo: Vấn đề bảo mật tiềm ẩn" +OBSWebSocket.Settings.Save.UserPasswordWarningMessage="obs-websocket lưu trữ mật khẩu máy chủ dưới dạng văn bản thuần túy. Bạn nên sử dụng mật khẩu được tạo bởi obs-websocket." +OBSWebSocket.Settings.Save.UserPasswordWarningInfoText="Bạn có chắc bạn muốn sử dụng mật khẩu của mình?" +OBSWebSocket.Settings.Save.PasswordInvalidErrorTitle="Lỗi: Thiết lập không hợp lệ" +OBSWebSocket.Settings.Save.PasswordInvalidErrorMessage="Bạn phải sử dụng mật khẩu có 6 ký tự trở lên." +OBSWebSocket.SessionTable.Title="Các phiên WebSocket được kết nối" +OBSWebSocket.SessionTable.RemoteAddressColumnTitle="Địa chỉ từ xa" +OBSWebSocket.SessionTable.SessionDurationColumnTitle="Thời lượng phiên" +OBSWebSocket.SessionTable.MessagesInOutColumnTitle="Tin nhắn vào/ra" +OBSWebSocket.SessionTable.IdentifiedTitle="Định dạng" +OBSWebSocket.ConnectInfo.DialogTitle="Thông tin kết nối WebSocket" +OBSWebSocket.ConnectInfo.ServerIp="IP Máy chủ (Gợi ý tốt nhất)" +OBSWebSocket.ConnectInfo.ServerPort="Cổng máy chủ" +OBSWebSocket.ConnectInfo.ServerPassword="Mật khẩu máy chủ" +OBSWebSocket.ConnectInfo.QrTitle="Kết nối bằng mã QR" +OBSWebSocket.TrayNotification.Identified.Title="Tạo cổng kết nối WebSocket mới" +OBSWebSocket.TrayNotification.Identified.Body="Máy khách %1 được xác định." +OBSWebSocket.TrayNotification.AuthenticationFailed.Title="Lỗi xác thực WebSocket" +OBSWebSocket.TrayNotification.AuthenticationFailed.Body="Máy khách %1 không xác thực được." +OBSWebSocket.TrayNotification.Disconnected.Title="Máy khách WebSocket bị ngắt kết nối" +OBSWebSocket.TrayNotification.Disconnected.Body="Máy khách %1 bị ngắt kết nối." diff --git a/data/locale/zh-CN.ini b/data/locale/zh-CN.ini index e353073c7..e781be238 100644 --- a/data/locale/zh-CN.ini +++ b/data/locale/zh-CN.ini @@ -1,28 +1,28 @@ OBSWebSocket.Plugin.Description="通过 WebSocket 远程控制 OBS Studio" -OBSWebSocket.Settings.DialogTitle="obs-websocket 设置" +OBSWebSocket.Settings.DialogTitle="WebSocket 服务器设置" OBSWebSocket.Settings.PluginSettingsTitle="插件设置" OBSWebSocket.Settings.ServerEnable="开启 WebSocket 服务器" OBSWebSocket.Settings.AlertsEnable="开启系统托盘提醒" OBSWebSocket.Settings.DebugEnable="开启调试日志" -OBSWebSocket.Settings.DebugEnableHoverText="启用当前 OBS 实例的调试日志。下次启动时需重新设置。\n使用 --websocket_debug 在启动 OBS 时启用日志。" +OBSWebSocket.Settings.DebugEnableHoverText="开启当前 OBS 实例的调试日志。下次启动时需重新设置。\n使用 --websocket_debug 在启动 OBS 时开启日志。" OBSWebSocket.Settings.ServerSettingsTitle="服务器设置" -OBSWebSocket.Settings.AuthRequired="开启鉴权" +OBSWebSocket.Settings.AuthRequired="开启身份认证" OBSWebSocket.Settings.Password="服务器密码" OBSWebSocket.Settings.GeneratePassword="生成密码" OBSWebSocket.Settings.ServerPort="服务器端口" OBSWebSocket.Settings.ShowConnectInfo="显示连接信息" OBSWebSocket.Settings.ShowConnectInfoWarningTitle="警告:正在直播" -OBSWebSocket.Settings.ShowConnectInfoWarningMessage="似乎正在输出(串流、录像等)。" +OBSWebSocket.Settings.ShowConnectInfoWarningMessage="似乎输出(串流、录像等)正在进行。" OBSWebSocket.Settings.ShowConnectInfoWarningInfoText="您确定要显示您的连接信息吗?" OBSWebSocket.Settings.Save.UserPasswordWarningTitle="警告:潜在安全问题" OBSWebSocket.Settings.Save.UserPasswordWarningMessage="obs-websocket 会以明文形式储存服务器密码。强烈建议使用 obs-websocket 生成的密码。" OBSWebSocket.Settings.Save.UserPasswordWarningInfoText="您确定要使用自定义密码吗?" -OBSWebSocket.Settings.Save.PasswordInvalidErrorTitle="错误:配置无效" +OBSWebSocket.Settings.Save.PasswordInvalidErrorTitle="错误:无效的配置" OBSWebSocket.Settings.Save.PasswordInvalidErrorMessage="您的密码必须包含 6 个或以上的字符。" OBSWebSocket.SessionTable.Title="已连接的 WebSocket 会话" OBSWebSocket.SessionTable.RemoteAddressColumnTitle="远程地址" OBSWebSocket.SessionTable.SessionDurationColumnTitle="会话持续时间" -OBSWebSocket.SessionTable.MessagesInOutColumnTitle="消息传入/出" +OBSWebSocket.SessionTable.MessagesInOutColumnTitle="消息传入/传出" OBSWebSocket.SessionTable.IdentifiedTitle="已识别" OBSWebSocket.SessionTable.KickButtonColumnTitle="踢出?" OBSWebSocket.SessionTable.KickButtonText="踢出" @@ -31,13 +31,11 @@ OBSWebSocket.ConnectInfo.CopyText="复制" OBSWebSocket.ConnectInfo.ServerIp="服务器 IP(最佳猜测)" OBSWebSocket.ConnectInfo.ServerPort="服务器端口" OBSWebSocket.ConnectInfo.ServerPassword="服务器密码" -OBSWebSocket.ConnectInfo.ServerPasswordPlaceholderText="[鉴权已停用]" +OBSWebSocket.ConnectInfo.ServerPasswordPlaceholderText="[身份认证已停用]" OBSWebSocket.ConnectInfo.QrTitle="连接 QR 码" OBSWebSocket.TrayNotification.Identified.Title="新 WebSocket 连接" -OBSWebSocket.TrayNotification.Identified.Body="已识别 %1 客户端。" -OBSWebSocket.TrayNotification.AuthenticationFailed.Title="WebSocket 鉴权失败" +OBSWebSocket.TrayNotification.Identified.Body="客户端%1已识别 。" +OBSWebSocket.TrayNotification.AuthenticationFailed.Title="WebSocket 认证失败" OBSWebSocket.TrayNotification.AuthenticationFailed.Body="%1 客户端认证失败。" OBSWebSocket.TrayNotification.Disconnected.Title="WebSocket 客户端已断开" OBSWebSocket.TrayNotification.Disconnected.Body="%1 客户端已断开。" -OBSWebSocket.Server.StartFailed.Title="WebSocket 服务器启动失败" -OBSWebSocket.Server.StartFailed.Message="WebSocket 服务器启动失败。TCP 端口 %1 可能已被其它程序占用。请尝试在 WebSocket 服务器设置中更改不同的 TCP 端口号,或者结束其它任何可能占用此端口的程序。\n错误信息:%2" diff --git a/data/locale/zh-TW.ini b/data/locale/zh-TW.ini index 9beace3b5..02e3439d8 100644 --- a/data/locale/zh-TW.ini +++ b/data/locale/zh-TW.ini @@ -1,5 +1,5 @@ OBSWebSocket.Plugin.Description="透過 WebSocket 遠端控制 OBS Studio" -OBSWebSocket.Settings.DialogTitle="obs-websocket 設定" +OBSWebSocket.Settings.DialogTitle="WebSocket 伺服器設定" OBSWebSocket.Settings.PluginSettingsTitle="外掛程式設定" OBSWebSocket.Settings.ServerEnable="啟用 WebSocket 伺服器" OBSWebSocket.Settings.AlertsEnable="啟用系統匣通知" @@ -39,5 +39,3 @@ OBSWebSocket.TrayNotification.AuthenticationFailed.Title="WebSocket 認證失敗 OBSWebSocket.TrayNotification.AuthenticationFailed.Body="%1 用戶端無法進行認證。" OBSWebSocket.TrayNotification.Disconnected.Title="WebSocket 用戶端已斷線" OBSWebSocket.TrayNotification.Disconnected.Body="%1 用戶端已斷線。" -OBSWebSocket.Server.StartFailed.Title="WebSocket 伺服器錯誤" -OBSWebSocket.Server.StartFailed.Message="無法啟動 WebSocket 伺服器。可能 TCP 連線埠 %1 已經被系統中的某個應用程式佔用。請嘗試在 WebSocket 伺服器設定更改不同的 TCP 連線埠,或停止任何可能正在使用這個連線埠的應用程式。\n錯誤訊息:%2" diff --git a/deps/asio b/deps/asio deleted file mode 160000 index b73dc1d2c..000000000 --- a/deps/asio +++ /dev/null @@ -1 +0,0 @@ -Subproject commit b73dc1d2c0ecb9452a87c26544d7f71e24342df6 diff --git a/deps/json b/deps/json deleted file mode 160000 index a34e011e2..000000000 --- a/deps/json +++ /dev/null @@ -1 +0,0 @@ -Subproject commit a34e011e24beece3b69397a03fdc650546f052c3 diff --git a/deps/qr b/deps/qr deleted file mode 160000 index 8518684c0..000000000 --- a/deps/qr +++ /dev/null @@ -1 +0,0 @@ -Subproject commit 8518684c0f33d004fa93971be2c6a8eca3167d1e diff --git a/deps/websocketpp b/deps/websocketpp deleted file mode 160000 index 56123c875..000000000 --- a/deps/websocketpp +++ /dev/null @@ -1 +0,0 @@ -Subproject commit 56123c87598f8b1dd471be83ca841ceae07f95ba diff --git a/docs/README.md b/docs/README.md index 536769adb..d3640b5f7 100644 --- a/docs/README.md +++ b/docs/README.md @@ -1,5 +1,7 @@ # obs-websocket documentation +## If you're looking for the documentation page, it's [here](generated/protocol.md) + This is the documentation for obs-websocket. Run `build_docs.sh` to auto generate the latest docs from the `src` directory. There are 3 components to the docs generation: - `comments/comments.js`: Generates the `work/comments.json` file from the code comments in the src directory. diff --git a/docs/docs/partials/introduction.md b/docs/docs/partials/introduction.md index 59a29de35..f252024c7 100644 --- a/docs/docs/partials/introduction.md +++ b/docs/docs/partials/introduction.md @@ -1,5 +1,5 @@ -# obs-websocket 5.1.0 Protocol +# obs-websocket 5.x.x Protocol ## Main Table of Contents @@ -61,7 +61,7 @@ These steps should be followed precisely. Failure to connect to the server as in - The server receives and processes the `Identify` sent by the client. - If authentication is required and the `Identify` message data does not contain an `authentication` string, or the string is not correct, the connection is closed with `WebSocketCloseCode::AuthenticationFailed` - - If the client has requested an `rpcVersion` which the server cannot use, the connection is closed with `WebSocketCloseCode::UnsupportedRpcVersion`. This system allows both the server and client to have seamless backwards compatability. + - If the client has requested an `rpcVersion` which the server cannot use, the connection is closed with `WebSocketCloseCode::UnsupportedRpcVersion`. This system allows both the server and client to have seamless backwards compatibility. - If any other parameters are malformed (invalid type, etc), the connection is closed with an appropriate close code. - Once identification is processed on the server, the server responds to the client with an [OpCode 2 `Identified`](#identified-opcode-2). diff --git a/docs/generated/protocol.json b/docs/generated/protocol.json index ce84caa91..aacbe235a 100644 --- a/docs/generated/protocol.json +++ b/docs/generated/protocol.json @@ -237,6 +237,14 @@ "initialVersion": "5.0.0", "enumValue": 206 }, + { + "description": "The server is not ready to handle the request.\n\nNote: This usually occurs during OBS scene collection change or exit. Requests may be tried again after a delay if this code is given.", + "enumIdentifier": "NotReady", + "rpcVersion": "1", + "deprecated": false, + "initialVersion": "5.3.0", + "enumValue": 207 + }, { "description": "A required request field is missing.", "enumIdentifier": "MissingRequestField", @@ -1217,7 +1225,7 @@ { "description": "Gets the current directory that the record output is set to.", "requestType": "GetRecordDirectory", - "complexity": 1, + "complexity": 2, "rpcVersion": "1", "deprecated": false, "initialVersion": "5.0.0", @@ -1231,6 +1239,43 @@ } ] }, + { + "description": "Sets the current directory that the record output writes files to.", + "requestType": "SetRecordDirectory", + "complexity": 2, + "rpcVersion": "1", + "deprecated": false, + "initialVersion": "5.3.0", + "category": "config", + "requestFields": [ + { + "valueName": "recordDirectory", + "valueType": "String", + "valueDescription": "Output directory", + "valueRestrictions": null, + "valueOptional": false, + "valueOptionalBehavior": null + } + ], + "responseFields": [] + }, + { + "description": "Gets an array of all available source filter kinds.\n\nSimilar to `GetInputKindList`", + "requestType": "GetSourceFilterKindList", + "complexity": 2, + "rpcVersion": "1", + "deprecated": false, + "initialVersion": "5.4.0", + "category": "filters", + "requestFields": [], + "responseFields": [ + { + "valueName": "sourceFilterKinds", + "valueType": "Array", + "valueDescription": "Array of source filter kinds" + } + ] + }, { "description": "Gets an array of all of a source's filters.", "requestType": "GetSourceFilterList", @@ -1245,8 +1290,16 @@ "valueType": "String", "valueDescription": "Name of the source", "valueRestrictions": null, - "valueOptional": false, - "valueOptionalBehavior": null + "valueOptional": true, + "valueOptionalBehavior": "Unknown" + }, + { + "valueName": "sourceUuid", + "valueType": "String", + "valueDescription": "UUID of the source", + "valueRestrictions": null, + "valueOptional": true, + "valueOptionalBehavior": "Unknown" } ], "responseFields": [ @@ -1297,8 +1350,16 @@ "valueType": "String", "valueDescription": "Name of the source to add the filter to", "valueRestrictions": null, - "valueOptional": false, - "valueOptionalBehavior": null + "valueOptional": true, + "valueOptionalBehavior": "Unknown" + }, + { + "valueName": "sourceUuid", + "valueType": "String", + "valueDescription": "UUID of the source to add the filter to", + "valueRestrictions": null, + "valueOptional": true, + "valueOptionalBehavior": "Unknown" }, { "valueName": "filterName", @@ -1341,8 +1402,16 @@ "valueType": "String", "valueDescription": "Name of the source the filter is on", "valueRestrictions": null, - "valueOptional": false, - "valueOptionalBehavior": null + "valueOptional": true, + "valueOptionalBehavior": "Unknown" + }, + { + "valueName": "sourceUuid", + "valueType": "String", + "valueDescription": "UUID of the source the filter is on", + "valueRestrictions": null, + "valueOptional": true, + "valueOptionalBehavior": "Unknown" }, { "valueName": "filterName", @@ -1369,8 +1438,16 @@ "valueType": "String", "valueDescription": "Name of the source the filter is on", "valueRestrictions": null, - "valueOptional": false, - "valueOptionalBehavior": null + "valueOptional": true, + "valueOptionalBehavior": "Unknown" + }, + { + "valueName": "sourceUuid", + "valueType": "String", + "valueDescription": "UUID of the source the filter is on", + "valueRestrictions": null, + "valueOptional": true, + "valueOptionalBehavior": "Unknown" }, { "valueName": "filterName", @@ -1405,8 +1482,16 @@ "valueType": "String", "valueDescription": "Name of the source", "valueRestrictions": null, - "valueOptional": false, - "valueOptionalBehavior": null + "valueOptional": true, + "valueOptionalBehavior": "Unknown" + }, + { + "valueName": "sourceUuid", + "valueType": "String", + "valueDescription": "UUID of the source", + "valueRestrictions": null, + "valueOptional": true, + "valueOptionalBehavior": "Unknown" }, { "valueName": "filterName", @@ -1454,8 +1539,16 @@ "valueType": "String", "valueDescription": "Name of the source the filter is on", "valueRestrictions": null, - "valueOptional": false, - "valueOptionalBehavior": null + "valueOptional": true, + "valueOptionalBehavior": "Unknown" + }, + { + "valueName": "sourceUuid", + "valueType": "String", + "valueDescription": "UUID of the source the filter is on", + "valueRestrictions": null, + "valueOptional": true, + "valueOptionalBehavior": "Unknown" }, { "valueName": "filterName", @@ -1490,8 +1583,16 @@ "valueType": "String", "valueDescription": "Name of the source the filter is on", "valueRestrictions": null, - "valueOptional": false, - "valueOptionalBehavior": null + "valueOptional": true, + "valueOptionalBehavior": "Unknown" + }, + { + "valueName": "sourceUuid", + "valueType": "String", + "valueDescription": "UUID of the source the filter is on", + "valueRestrictions": null, + "valueOptional": true, + "valueOptionalBehavior": "Unknown" }, { "valueName": "filterName", @@ -1534,8 +1635,16 @@ "valueType": "String", "valueDescription": "Name of the source the filter is on", "valueRestrictions": null, - "valueOptional": false, - "valueOptionalBehavior": null + "valueOptional": true, + "valueOptionalBehavior": "Unknown" + }, + { + "valueName": "sourceUuid", + "valueType": "String", + "valueDescription": "UUID of the source the filter is on", + "valueRestrictions": null, + "valueOptional": true, + "valueOptionalBehavior": "Unknown" }, { "valueName": "filterName", @@ -1743,9 +1852,9 @@ ] }, { - "description": "Gets an array of all hotkey names in OBS", + "description": "Gets an array of all hotkey names in OBS.\n\nNote: Hotkey functionality in obs-websocket comes as-is, and we do not guarantee support if things are broken. In 9/10 usages of hotkey requests, there exists a better, more reliable method via other requests.", "requestType": "GetHotkeyList", - "complexity": 3, + "complexity": 4, "rpcVersion": "1", "deprecated": false, "initialVersion": "5.0.0", @@ -1760,9 +1869,9 @@ ] }, { - "description": "Triggers a hotkey using its name. See `GetHotkeyList`", + "description": "Triggers a hotkey using its name. See `GetHotkeyList`.\n\nNote: Hotkey functionality in obs-websocket comes as-is, and we do not guarantee support if things are broken. In 9/10 usages of hotkey requests, there exists a better, more reliable method via other requests.", "requestType": "TriggerHotkeyByName", - "complexity": 3, + "complexity": 4, "rpcVersion": "1", "deprecated": false, "initialVersion": "5.0.0", @@ -1775,12 +1884,20 @@ "valueRestrictions": null, "valueOptional": false, "valueOptionalBehavior": null + }, + { + "valueName": "contextName", + "valueType": "String", + "valueDescription": "Name of context of the hotkey to trigger", + "valueRestrictions": null, + "valueOptional": true, + "valueOptionalBehavior": "Unknown" } ], "responseFields": [] }, { - "description": "Triggers a hotkey using a sequence of keys.", + "description": "Triggers a hotkey using a sequence of keys.\n\nNote: Hotkey functionality in obs-websocket comes as-is, and we do not guarantee support if things are broken. In 9/10 usages of hotkey requests, there exists a better, more reliable method via other requests.", "requestType": "TriggerHotkeyByKeySequence", "complexity": 4, "rpcVersion": "1", @@ -1975,8 +2092,16 @@ "valueType": "String", "valueDescription": "Name of the scene to add the input to as a scene item", "valueRestrictions": null, - "valueOptional": false, - "valueOptionalBehavior": null + "valueOptional": true, + "valueOptionalBehavior": "Unknown" + }, + { + "valueName": "sceneUuid", + "valueType": "String", + "valueDescription": "UUID of the scene to add the input to as a scene item", + "valueRestrictions": null, + "valueOptional": true, + "valueOptionalBehavior": "Unknown" }, { "valueName": "inputName", @@ -2012,6 +2137,11 @@ } ], "responseFields": [ + { + "valueName": "inputUuid", + "valueType": "String", + "valueDescription": "UUID of the newly created input" + }, { "valueName": "sceneItemId", "valueType": "Number", @@ -2033,8 +2163,16 @@ "valueType": "String", "valueDescription": "Name of the input to remove", "valueRestrictions": null, - "valueOptional": false, - "valueOptionalBehavior": null + "valueOptional": true, + "valueOptionalBehavior": "Unknown" + }, + { + "valueName": "inputUuid", + "valueType": "String", + "valueDescription": "UUID of the input to remove", + "valueRestrictions": null, + "valueOptional": true, + "valueOptionalBehavior": "Unknown" } ], "responseFields": [] @@ -2053,8 +2191,16 @@ "valueType": "String", "valueDescription": "Current input name", "valueRestrictions": null, - "valueOptional": false, - "valueOptionalBehavior": null + "valueOptional": true, + "valueOptionalBehavior": "Unknown" + }, + { + "valueName": "inputUuid", + "valueType": "String", + "valueDescription": "Current input UUID", + "valueRestrictions": null, + "valueOptional": true, + "valueOptionalBehavior": "Unknown" }, { "valueName": "newInputName", @@ -2107,8 +2253,16 @@ "valueType": "String", "valueDescription": "Name of the input to get the settings of", "valueRestrictions": null, - "valueOptional": false, - "valueOptionalBehavior": null + "valueOptional": true, + "valueOptionalBehavior": "Unknown" + }, + { + "valueName": "inputUuid", + "valueType": "String", + "valueDescription": "UUID of the input to get the settings of", + "valueRestrictions": null, + "valueOptional": true, + "valueOptionalBehavior": "Unknown" } ], "responseFields": [ @@ -2138,8 +2292,16 @@ "valueType": "String", "valueDescription": "Name of the input to set the settings of", "valueRestrictions": null, - "valueOptional": false, - "valueOptionalBehavior": null + "valueOptional": true, + "valueOptionalBehavior": "Unknown" + }, + { + "valueName": "inputUuid", + "valueType": "String", + "valueDescription": "UUID of the input to set the settings of", + "valueRestrictions": null, + "valueOptional": true, + "valueOptionalBehavior": "Unknown" }, { "valueName": "inputSettings", @@ -2174,8 +2336,16 @@ "valueType": "String", "valueDescription": "Name of input to get the mute state of", "valueRestrictions": null, - "valueOptional": false, - "valueOptionalBehavior": null + "valueOptional": true, + "valueOptionalBehavior": "Unknown" + }, + { + "valueName": "inputUuid", + "valueType": "String", + "valueDescription": "UUID of input to get the mute state of", + "valueRestrictions": null, + "valueOptional": true, + "valueOptionalBehavior": "Unknown" } ], "responseFields": [ @@ -2200,8 +2370,16 @@ "valueType": "String", "valueDescription": "Name of the input to set the mute state of", "valueRestrictions": null, - "valueOptional": false, - "valueOptionalBehavior": null + "valueOptional": true, + "valueOptionalBehavior": "Unknown" + }, + { + "valueName": "inputUuid", + "valueType": "String", + "valueDescription": "UUID of the input to set the mute state of", + "valueRestrictions": null, + "valueOptional": true, + "valueOptionalBehavior": "Unknown" }, { "valueName": "inputMuted", @@ -2228,8 +2406,16 @@ "valueType": "String", "valueDescription": "Name of the input to toggle the mute state of", "valueRestrictions": null, - "valueOptional": false, - "valueOptionalBehavior": null + "valueOptional": true, + "valueOptionalBehavior": "Unknown" + }, + { + "valueName": "inputUuid", + "valueType": "String", + "valueDescription": "UUID of the input to toggle the mute state of", + "valueRestrictions": null, + "valueOptional": true, + "valueOptionalBehavior": "Unknown" } ], "responseFields": [ @@ -2254,8 +2440,16 @@ "valueType": "String", "valueDescription": "Name of the input to get the volume of", "valueRestrictions": null, - "valueOptional": false, - "valueOptionalBehavior": null + "valueOptional": true, + "valueOptionalBehavior": "Unknown" + }, + { + "valueName": "inputUuid", + "valueType": "String", + "valueDescription": "UUID of the input to get the volume of", + "valueRestrictions": null, + "valueOptional": true, + "valueOptionalBehavior": "Unknown" } ], "responseFields": [ @@ -2285,8 +2479,16 @@ "valueType": "String", "valueDescription": "Name of the input to set the volume of", "valueRestrictions": null, - "valueOptional": false, - "valueOptionalBehavior": null + "valueOptional": true, + "valueOptionalBehavior": "Unknown" + }, + { + "valueName": "inputUuid", + "valueType": "String", + "valueDescription": "UUID of the input to set the volume of", + "valueRestrictions": null, + "valueOptional": true, + "valueOptionalBehavior": "Unknown" }, { "valueName": "inputVolumeMul", @@ -2321,8 +2523,16 @@ "valueType": "String", "valueDescription": "Name of the input to get the audio balance of", "valueRestrictions": null, - "valueOptional": false, - "valueOptionalBehavior": null + "valueOptional": true, + "valueOptionalBehavior": "Unknown" + }, + { + "valueName": "inputUuid", + "valueType": "String", + "valueDescription": "UUID of the input to get the audio balance of", + "valueRestrictions": null, + "valueOptional": true, + "valueOptionalBehavior": "Unknown" } ], "responseFields": [ @@ -2347,8 +2557,16 @@ "valueType": "String", "valueDescription": "Name of the input to set the audio balance of", "valueRestrictions": null, - "valueOptional": false, - "valueOptionalBehavior": null + "valueOptional": true, + "valueOptionalBehavior": "Unknown" + }, + { + "valueName": "inputUuid", + "valueType": "String", + "valueDescription": "UUID of the input to set the audio balance of", + "valueRestrictions": null, + "valueOptional": true, + "valueOptionalBehavior": "Unknown" }, { "valueName": "inputAudioBalance", @@ -2375,13 +2593,21 @@ "valueType": "String", "valueDescription": "Name of the input to get the audio sync offset of", "valueRestrictions": null, - "valueOptional": false, - "valueOptionalBehavior": null - } - ], - "responseFields": [ + "valueOptional": true, + "valueOptionalBehavior": "Unknown" + }, { - "valueName": "inputAudioSyncOffset", + "valueName": "inputUuid", + "valueType": "String", + "valueDescription": "UUID of the input to get the audio sync offset of", + "valueRestrictions": null, + "valueOptional": true, + "valueOptionalBehavior": "Unknown" + } + ], + "responseFields": [ + { + "valueName": "inputAudioSyncOffset", "valueType": "Number", "valueDescription": "Audio sync offset in milliseconds" } @@ -2401,8 +2627,16 @@ "valueType": "String", "valueDescription": "Name of the input to set the audio sync offset of", "valueRestrictions": null, - "valueOptional": false, - "valueOptionalBehavior": null + "valueOptional": true, + "valueOptionalBehavior": "Unknown" + }, + { + "valueName": "inputUuid", + "valueType": "String", + "valueDescription": "UUID of the input to set the audio sync offset of", + "valueRestrictions": null, + "valueOptional": true, + "valueOptionalBehavior": "Unknown" }, { "valueName": "inputAudioSyncOffset", @@ -2429,8 +2663,16 @@ "valueType": "String", "valueDescription": "Name of the input to get the audio monitor type of", "valueRestrictions": null, - "valueOptional": false, - "valueOptionalBehavior": null + "valueOptional": true, + "valueOptionalBehavior": "Unknown" + }, + { + "valueName": "inputUuid", + "valueType": "String", + "valueDescription": "UUID of the input to get the audio monitor type of", + "valueRestrictions": null, + "valueOptional": true, + "valueOptionalBehavior": "Unknown" } ], "responseFields": [ @@ -2455,8 +2697,16 @@ "valueType": "String", "valueDescription": "Name of the input to set the audio monitor type of", "valueRestrictions": null, - "valueOptional": false, - "valueOptionalBehavior": null + "valueOptional": true, + "valueOptionalBehavior": "Unknown" + }, + { + "valueName": "inputUuid", + "valueType": "String", + "valueDescription": "UUID of the input to set the audio monitor type of", + "valueRestrictions": null, + "valueOptional": true, + "valueOptionalBehavior": "Unknown" }, { "valueName": "monitorType", @@ -2483,8 +2733,16 @@ "valueType": "String", "valueDescription": "Name of the input", "valueRestrictions": null, - "valueOptional": false, - "valueOptionalBehavior": null + "valueOptional": true, + "valueOptionalBehavior": "Unknown" + }, + { + "valueName": "inputUuid", + "valueType": "String", + "valueDescription": "UUID of the input", + "valueRestrictions": null, + "valueOptional": true, + "valueOptionalBehavior": "Unknown" } ], "responseFields": [ @@ -2509,8 +2767,16 @@ "valueType": "String", "valueDescription": "Name of the input", "valueRestrictions": null, - "valueOptional": false, - "valueOptionalBehavior": null + "valueOptional": true, + "valueOptionalBehavior": "Unknown" + }, + { + "valueName": "inputUuid", + "valueType": "String", + "valueDescription": "UUID of the input", + "valueRestrictions": null, + "valueOptional": true, + "valueOptionalBehavior": "Unknown" }, { "valueName": "inputAudioTracks", @@ -2537,8 +2803,16 @@ "valueType": "String", "valueDescription": "Name of the input", "valueRestrictions": null, - "valueOptional": false, - "valueOptionalBehavior": null + "valueOptional": true, + "valueOptionalBehavior": "Unknown" + }, + { + "valueName": "inputUuid", + "valueType": "String", + "valueDescription": "UUID of the input", + "valueRestrictions": null, + "valueOptional": true, + "valueOptionalBehavior": "Unknown" }, { "valueName": "propertyName", @@ -2571,8 +2845,16 @@ "valueType": "String", "valueDescription": "Name of the input", "valueRestrictions": null, - "valueOptional": false, - "valueOptionalBehavior": null + "valueOptional": true, + "valueOptionalBehavior": "Unknown" + }, + { + "valueName": "inputUuid", + "valueType": "String", + "valueDescription": "UUID of the input", + "valueRestrictions": null, + "valueOptional": true, + "valueOptionalBehavior": "Unknown" }, { "valueName": "propertyName", @@ -2599,8 +2881,16 @@ "valueType": "String", "valueDescription": "Name of the media input", "valueRestrictions": null, - "valueOptional": false, - "valueOptionalBehavior": null + "valueOptional": true, + "valueOptionalBehavior": "Unknown" + }, + { + "valueName": "inputUuid", + "valueType": "String", + "valueDescription": "UUID of the media input", + "valueRestrictions": null, + "valueOptional": true, + "valueOptionalBehavior": "Unknown" } ], "responseFields": [ @@ -2635,8 +2925,16 @@ "valueType": "String", "valueDescription": "Name of the media input", "valueRestrictions": null, - "valueOptional": false, - "valueOptionalBehavior": null + "valueOptional": true, + "valueOptionalBehavior": "Unknown" + }, + { + "valueName": "inputUuid", + "valueType": "String", + "valueDescription": "UUID of the media input", + "valueRestrictions": null, + "valueOptional": true, + "valueOptionalBehavior": "Unknown" }, { "valueName": "mediaCursor", @@ -2663,8 +2961,16 @@ "valueType": "String", "valueDescription": "Name of the media input", "valueRestrictions": null, - "valueOptional": false, - "valueOptionalBehavior": null + "valueOptional": true, + "valueOptionalBehavior": "Unknown" + }, + { + "valueName": "inputUuid", + "valueType": "String", + "valueDescription": "UUID of the media input", + "valueRestrictions": null, + "valueOptional": true, + "valueOptionalBehavior": "Unknown" }, { "valueName": "mediaCursorOffset", @@ -2691,8 +2997,16 @@ "valueType": "String", "valueDescription": "Name of the media input", "valueRestrictions": null, - "valueOptional": false, - "valueOptionalBehavior": null + "valueOptional": true, + "valueOptionalBehavior": "Unknown" + }, + { + "valueName": "inputUuid", + "valueType": "String", + "valueDescription": "UUID of the media input", + "valueRestrictions": null, + "valueOptional": true, + "valueOptionalBehavior": "Unknown" }, { "valueName": "mediaAction", @@ -3089,7 +3403,13 @@ "initialVersion": "5.0.0", "category": "record", "requestFields": [], - "responseFields": [] + "responseFields": [ + { + "valueName": "outputActive", + "valueType": "Boolean", + "valueDescription": "The new active state of the output" + } + ] }, { "description": "Starts the record output.", @@ -3166,8 +3486,16 @@ "valueType": "String", "valueDescription": "Name of the scene to get the items of", "valueRestrictions": null, - "valueOptional": false, - "valueOptionalBehavior": null + "valueOptional": true, + "valueOptionalBehavior": "Unknown" + }, + { + "valueName": "sceneUuid", + "valueType": "String", + "valueDescription": "UUID of the scene to get the items of", + "valueRestrictions": null, + "valueOptional": true, + "valueOptionalBehavior": "Unknown" } ], "responseFields": [ @@ -3192,8 +3520,16 @@ "valueType": "String", "valueDescription": "Name of the group to get the items of", "valueRestrictions": null, - "valueOptional": false, - "valueOptionalBehavior": null + "valueOptional": true, + "valueOptionalBehavior": "Unknown" + }, + { + "valueName": "sceneUuid", + "valueType": "String", + "valueDescription": "UUID of the group to get the items of", + "valueRestrictions": null, + "valueOptional": true, + "valueOptionalBehavior": "Unknown" } ], "responseFields": [ @@ -3218,8 +3554,16 @@ "valueType": "String", "valueDescription": "Name of the scene or group to search in", "valueRestrictions": null, - "valueOptional": false, - "valueOptionalBehavior": null + "valueOptional": true, + "valueOptionalBehavior": "Unknown" + }, + { + "valueName": "sceneUuid", + "valueType": "String", + "valueDescription": "UUID of the scene or group to search in", + "valueRestrictions": null, + "valueOptional": true, + "valueOptionalBehavior": "Unknown" }, { "valueName": "sourceName", @@ -3246,6 +3590,53 @@ } ] }, + { + "description": "Gets the source associated with a scene item.", + "requestType": "GetSceneItemSource", + "complexity": 3, + "rpcVersion": "1", + "deprecated": false, + "initialVersion": "5.4.0", + "category": "scene items", + "requestFields": [ + { + "valueName": "sceneName", + "valueType": "String", + "valueDescription": "Name of the scene the item is in", + "valueRestrictions": null, + "valueOptional": true, + "valueOptionalBehavior": "Unknown" + }, + { + "valueName": "sceneUuid", + "valueType": "String", + "valueDescription": "UUID of the scene the item is in", + "valueRestrictions": null, + "valueOptional": true, + "valueOptionalBehavior": "Unknown" + }, + { + "valueName": "sceneItemId", + "valueType": "Number", + "valueDescription": "Numeric ID of the scene item", + "valueRestrictions": ">= 0", + "valueOptional": false, + "valueOptionalBehavior": null + } + ], + "responseFields": [ + { + "valueName": "sourceName", + "valueType": "String", + "valueDescription": "Name of the source associated with the scene item" + }, + { + "valueName": "sourceUuid", + "valueType": "String", + "valueDescription": "UUID of the source associated with the scene item" + } + ] + }, { "description": "Creates a new scene item using a source.\n\nScenes only", "requestType": "CreateSceneItem", @@ -3260,16 +3651,32 @@ "valueType": "String", "valueDescription": "Name of the scene to create the new item in", "valueRestrictions": null, - "valueOptional": false, - "valueOptionalBehavior": null + "valueOptional": true, + "valueOptionalBehavior": "Unknown" + }, + { + "valueName": "sceneUuid", + "valueType": "String", + "valueDescription": "UUID of the scene to create the new item in", + "valueRestrictions": null, + "valueOptional": true, + "valueOptionalBehavior": "Unknown" }, { "valueName": "sourceName", "valueType": "String", "valueDescription": "Name of the source to add to the scene", "valueRestrictions": null, - "valueOptional": false, - "valueOptionalBehavior": null + "valueOptional": true, + "valueOptionalBehavior": "Unknown" + }, + { + "valueName": "sourceUuid", + "valueType": "String", + "valueDescription": "UUID of the source to add to the scene", + "valueRestrictions": null, + "valueOptional": true, + "valueOptionalBehavior": "Unknown" }, { "valueName": "sceneItemEnabled", @@ -3302,8 +3709,16 @@ "valueType": "String", "valueDescription": "Name of the scene the item is in", "valueRestrictions": null, - "valueOptional": false, - "valueOptionalBehavior": null + "valueOptional": true, + "valueOptionalBehavior": "Unknown" + }, + { + "valueName": "sceneUuid", + "valueType": "String", + "valueDescription": "UUID of the scene the item is in", + "valueRestrictions": null, + "valueOptional": true, + "valueOptionalBehavior": "Unknown" }, { "valueName": "sceneItemId", @@ -3330,8 +3745,16 @@ "valueType": "String", "valueDescription": "Name of the scene the item is in", "valueRestrictions": null, - "valueOptional": false, - "valueOptionalBehavior": null + "valueOptional": true, + "valueOptionalBehavior": "Unknown" + }, + { + "valueName": "sceneUuid", + "valueType": "String", + "valueDescription": "UUID of the scene the item is in", + "valueRestrictions": null, + "valueOptional": true, + "valueOptionalBehavior": "Unknown" }, { "valueName": "sceneItemId", @@ -3347,7 +3770,15 @@ "valueDescription": "Name of the scene to create the duplicated item in", "valueRestrictions": null, "valueOptional": true, - "valueOptionalBehavior": "`sceneName` is assumed" + "valueOptionalBehavior": "From scene is assumed" + }, + { + "valueName": "destinationSceneUuid", + "valueType": "String", + "valueDescription": "UUID of the scene to create the duplicated item in", + "valueRestrictions": null, + "valueOptional": true, + "valueOptionalBehavior": "From scene is assumed" } ], "responseFields": [ @@ -3372,8 +3803,16 @@ "valueType": "String", "valueDescription": "Name of the scene the item is in", "valueRestrictions": null, - "valueOptional": false, - "valueOptionalBehavior": null + "valueOptional": true, + "valueOptionalBehavior": "Unknown" + }, + { + "valueName": "sceneUuid", + "valueType": "String", + "valueDescription": "UUID of the scene the item is in", + "valueRestrictions": null, + "valueOptional": true, + "valueOptionalBehavior": "Unknown" }, { "valueName": "sceneItemId", @@ -3406,8 +3845,16 @@ "valueType": "String", "valueDescription": "Name of the scene the item is in", "valueRestrictions": null, - "valueOptional": false, - "valueOptionalBehavior": null + "valueOptional": true, + "valueOptionalBehavior": "Unknown" + }, + { + "valueName": "sceneUuid", + "valueType": "String", + "valueDescription": "UUID of the scene the item is in", + "valueRestrictions": null, + "valueOptional": true, + "valueOptionalBehavior": "Unknown" }, { "valueName": "sceneItemId", @@ -3442,8 +3889,16 @@ "valueType": "String", "valueDescription": "Name of the scene the item is in", "valueRestrictions": null, - "valueOptional": false, - "valueOptionalBehavior": null + "valueOptional": true, + "valueOptionalBehavior": "Unknown" + }, + { + "valueName": "sceneUuid", + "valueType": "String", + "valueDescription": "UUID of the scene the item is in", + "valueRestrictions": null, + "valueOptional": true, + "valueOptionalBehavior": "Unknown" }, { "valueName": "sceneItemId", @@ -3476,8 +3931,16 @@ "valueType": "String", "valueDescription": "Name of the scene the item is in", "valueRestrictions": null, - "valueOptional": false, - "valueOptionalBehavior": null + "valueOptional": true, + "valueOptionalBehavior": "Unknown" + }, + { + "valueName": "sceneUuid", + "valueType": "String", + "valueDescription": "UUID of the scene the item is in", + "valueRestrictions": null, + "valueOptional": true, + "valueOptionalBehavior": "Unknown" }, { "valueName": "sceneItemId", @@ -3512,8 +3975,16 @@ "valueType": "String", "valueDescription": "Name of the scene the item is in", "valueRestrictions": null, - "valueOptional": false, - "valueOptionalBehavior": null + "valueOptional": true, + "valueOptionalBehavior": "Unknown" + }, + { + "valueName": "sceneUuid", + "valueType": "String", + "valueDescription": "UUID of the scene the item is in", + "valueRestrictions": null, + "valueOptional": true, + "valueOptionalBehavior": "Unknown" }, { "valueName": "sceneItemId", @@ -3546,8 +4017,16 @@ "valueType": "String", "valueDescription": "Name of the scene the item is in", "valueRestrictions": null, - "valueOptional": false, - "valueOptionalBehavior": null + "valueOptional": true, + "valueOptionalBehavior": "Unknown" + }, + { + "valueName": "sceneUuid", + "valueType": "String", + "valueDescription": "UUID of the scene the item is in", + "valueRestrictions": null, + "valueOptional": true, + "valueOptionalBehavior": "Unknown" }, { "valueName": "sceneItemId", @@ -3582,8 +4061,16 @@ "valueType": "String", "valueDescription": "Name of the scene the item is in", "valueRestrictions": null, - "valueOptional": false, - "valueOptionalBehavior": null + "valueOptional": true, + "valueOptionalBehavior": "Unknown" + }, + { + "valueName": "sceneUuid", + "valueType": "String", + "valueDescription": "UUID of the scene the item is in", + "valueRestrictions": null, + "valueOptional": true, + "valueOptionalBehavior": "Unknown" }, { "valueName": "sceneItemId", @@ -3616,8 +4103,16 @@ "valueType": "String", "valueDescription": "Name of the scene the item is in", "valueRestrictions": null, - "valueOptional": false, - "valueOptionalBehavior": null + "valueOptional": true, + "valueOptionalBehavior": "Unknown" + }, + { + "valueName": "sceneUuid", + "valueType": "String", + "valueDescription": "UUID of the scene the item is in", + "valueRestrictions": null, + "valueOptional": true, + "valueOptionalBehavior": "Unknown" }, { "valueName": "sceneItemId", @@ -3652,8 +4147,16 @@ "valueType": "String", "valueDescription": "Name of the scene the item is in", "valueRestrictions": null, - "valueOptional": false, - "valueOptionalBehavior": null + "valueOptional": true, + "valueOptionalBehavior": "Unknown" + }, + { + "valueName": "sceneUuid", + "valueType": "String", + "valueDescription": "UUID of the scene the item is in", + "valueRestrictions": null, + "valueOptional": true, + "valueOptionalBehavior": "Unknown" }, { "valueName": "sceneItemId", @@ -3686,8 +4189,16 @@ "valueType": "String", "valueDescription": "Name of the scene the item is in", "valueRestrictions": null, - "valueOptional": false, - "valueOptionalBehavior": null + "valueOptional": true, + "valueOptionalBehavior": "Unknown" + }, + { + "valueName": "sceneUuid", + "valueType": "String", + "valueDescription": "UUID of the scene the item is in", + "valueRestrictions": null, + "valueOptional": true, + "valueOptionalBehavior": "Unknown" }, { "valueName": "sceneItemId", @@ -3721,12 +4232,22 @@ { "valueName": "currentProgramSceneName", "valueType": "String", - "valueDescription": "Current program scene" + "valueDescription": "Current program scene name. Can be `null` if internal state desync" + }, + { + "valueName": "currentProgramSceneUuid", + "valueType": "String", + "valueDescription": "Current program scene UUID. Can be `null` if internal state desync" }, { "valueName": "currentPreviewSceneName", "valueType": "String", - "valueDescription": "Current preview scene. `null` if not in studio mode" + "valueDescription": "Current preview scene name. `null` if not in studio mode" + }, + { + "valueName": "currentPreviewSceneUuid", + "valueType": "String", + "valueDescription": "Current preview scene UUID. `null` if not in studio mode" }, { "valueName": "scenes", @@ -3753,7 +4274,7 @@ ] }, { - "description": "Gets the current program scene.", + "description": "Gets the current program scene.\n\nNote: This request is slated to have the `currentProgram`-prefixed fields removed from in an upcoming RPC version.", "requestType": "GetCurrentProgramScene", "complexity": 1, "rpcVersion": "1", @@ -3762,10 +4283,25 @@ "category": "scenes", "requestFields": [], "responseFields": [ + { + "valueName": "sceneName", + "valueType": "String", + "valueDescription": "Current program scene name" + }, + { + "valueName": "sceneUuid", + "valueType": "String", + "valueDescription": "Current program scene UUID" + }, { "valueName": "currentProgramSceneName", "valueType": "String", - "valueDescription": "Current program scene" + "valueDescription": "Current program scene name (Deprecated)" + }, + { + "valueName": "currentProgramSceneUuid", + "valueType": "String", + "valueDescription": "Current program scene UUID (Deprecated)" } ] }, @@ -3781,16 +4317,24 @@ { "valueName": "sceneName", "valueType": "String", - "valueDescription": "Scene to set as the current program scene", + "valueDescription": "Scene name to set as the current program scene", "valueRestrictions": null, - "valueOptional": false, - "valueOptionalBehavior": null + "valueOptional": true, + "valueOptionalBehavior": "Unknown" + }, + { + "valueName": "sceneUuid", + "valueType": "String", + "valueDescription": "Scene UUID to set as the current program scene", + "valueRestrictions": null, + "valueOptional": true, + "valueOptionalBehavior": "Unknown" } ], "responseFields": [] }, { - "description": "Gets the current preview scene.\n\nOnly available when studio mode is enabled.", + "description": "Gets the current preview scene.\n\nOnly available when studio mode is enabled.\n\nNote: This request is slated to have the `currentPreview`-prefixed fields removed from in an upcoming RPC version.", "requestType": "GetCurrentPreviewScene", "complexity": 1, "rpcVersion": "1", @@ -3799,10 +4343,25 @@ "category": "scenes", "requestFields": [], "responseFields": [ + { + "valueName": "sceneName", + "valueType": "String", + "valueDescription": "Current preview scene name" + }, + { + "valueName": "sceneUuid", + "valueType": "String", + "valueDescription": "Current preview scene UUID" + }, { "valueName": "currentPreviewSceneName", "valueType": "String", - "valueDescription": "Current preview scene" + "valueDescription": "Current preview scene name" + }, + { + "valueName": "currentPreviewSceneUuid", + "valueType": "String", + "valueDescription": "Current preview scene UUID" } ] }, @@ -3818,10 +4377,18 @@ { "valueName": "sceneName", "valueType": "String", - "valueDescription": "Scene to set as the current preview scene", + "valueDescription": "Scene name to set as the current preview scene", "valueRestrictions": null, - "valueOptional": false, - "valueOptionalBehavior": null + "valueOptional": true, + "valueOptionalBehavior": "Unknown" + }, + { + "valueName": "sceneUuid", + "valueType": "String", + "valueDescription": "Scene UUID to set as the current preview scene", + "valueRestrictions": null, + "valueOptional": true, + "valueOptionalBehavior": "Unknown" } ], "responseFields": [] @@ -3844,7 +4411,13 @@ "valueOptionalBehavior": null } ], - "responseFields": [] + "responseFields": [ + { + "valueName": "sceneUuid", + "valueType": "String", + "valueDescription": "UUID of the created scene" + } + ] }, { "description": "Removes a scene from OBS.", @@ -3860,8 +4433,16 @@ "valueType": "String", "valueDescription": "Name of the scene to remove", "valueRestrictions": null, - "valueOptional": false, - "valueOptionalBehavior": null + "valueOptional": true, + "valueOptionalBehavior": "Unknown" + }, + { + "valueName": "sceneUuid", + "valueType": "String", + "valueDescription": "UUID of the scene to remove", + "valueRestrictions": null, + "valueOptional": true, + "valueOptionalBehavior": "Unknown" } ], "responseFields": [] @@ -3880,8 +4461,16 @@ "valueType": "String", "valueDescription": "Name of the scene to be renamed", "valueRestrictions": null, - "valueOptional": false, - "valueOptionalBehavior": null + "valueOptional": true, + "valueOptionalBehavior": "Unknown" + }, + { + "valueName": "sceneUuid", + "valueType": "String", + "valueDescription": "UUID of the scene to be renamed", + "valueRestrictions": null, + "valueOptional": true, + "valueOptionalBehavior": "Unknown" }, { "valueName": "newSceneName", @@ -3895,7 +4484,7 @@ "responseFields": [] }, { - "description": "Gets the scene transition overridden for a scene.", + "description": "Gets the scene transition overridden for a scene.\n\nNote: A transition UUID response field is not currently able to be implemented as of 2024-1-18.", "requestType": "GetSceneSceneTransitionOverride", "complexity": 2, "rpcVersion": "1", @@ -3908,8 +4497,16 @@ "valueType": "String", "valueDescription": "Name of the scene", "valueRestrictions": null, - "valueOptional": false, - "valueOptionalBehavior": null + "valueOptional": true, + "valueOptionalBehavior": "Unknown" + }, + { + "valueName": "sceneUuid", + "valueType": "String", + "valueDescription": "UUID of the scene", + "valueRestrictions": null, + "valueOptional": true, + "valueOptionalBehavior": "Unknown" } ], "responseFields": [ @@ -3926,7 +4523,7 @@ ] }, { - "description": "Gets the scene transition overridden for a scene.", + "description": "Sets the scene transition overridden for a scene.", "requestType": "SetSceneSceneTransitionOverride", "complexity": 2, "rpcVersion": "1", @@ -3939,8 +4536,16 @@ "valueType": "String", "valueDescription": "Name of the scene", "valueRestrictions": null, - "valueOptional": false, - "valueOptionalBehavior": null + "valueOptional": true, + "valueOptionalBehavior": "Unknown" + }, + { + "valueName": "sceneUuid", + "valueType": "String", + "valueDescription": "UUID of the scene", + "valueRestrictions": null, + "valueOptional": true, + "valueOptionalBehavior": "Unknown" }, { "valueName": "transitionName", @@ -3975,8 +4580,16 @@ "valueType": "String", "valueDescription": "Name of the source to get the active state of", "valueRestrictions": null, - "valueOptional": false, - "valueOptionalBehavior": null + "valueOptional": true, + "valueOptionalBehavior": "Unknown" + }, + { + "valueName": "sourceUuid", + "valueType": "String", + "valueDescription": "UUID of the source to get the active state of", + "valueRestrictions": null, + "valueOptional": true, + "valueOptionalBehavior": "Unknown" } ], "responseFields": [ @@ -4006,8 +4619,16 @@ "valueType": "String", "valueDescription": "Name of the source to take a screenshot of", "valueRestrictions": null, - "valueOptional": false, - "valueOptionalBehavior": null + "valueOptional": true, + "valueOptionalBehavior": "Unknown" + }, + { + "valueName": "sourceUuid", + "valueType": "String", + "valueDescription": "UUID of the source to take a screenshot of", + "valueRestrictions": null, + "valueOptional": true, + "valueOptionalBehavior": "Unknown" }, { "valueName": "imageFormat", @@ -4064,8 +4685,16 @@ "valueType": "String", "valueDescription": "Name of the source to take a screenshot of", "valueRestrictions": null, - "valueOptional": false, - "valueOptionalBehavior": null + "valueOptional": true, + "valueOptionalBehavior": "Unknown" + }, + { + "valueName": "sourceUuid", + "valueType": "String", + "valueDescription": "UUID of the source to take a screenshot of", + "valueRestrictions": null, + "valueOptional": true, + "valueOptionalBehavior": "Unknown" }, { "valueName": "imageFormat", @@ -4108,13 +4737,7 @@ "valueOptionalBehavior": "-1" } ], - "responseFields": [ - { - "valueName": "imageData", - "valueType": "String", - "valueDescription": "Base64-encoded screenshot" - } - ] + "responseFields": [] }, { "description": "Gets the status of the stream output.", @@ -4259,6 +4882,11 @@ "valueType": "String", "valueDescription": "Name of the current scene transition. Can be null" }, + { + "valueName": "currentSceneTransitionUuid", + "valueType": "String", + "valueDescription": "UUID of the current scene transition. Can be null" + }, { "valueName": "currentSceneTransitionKind", "valueType": "String", @@ -4286,6 +4914,11 @@ "valueType": "String", "valueDescription": "Name of the transition" }, + { + "valueName": "transitionUuid", + "valueType": "String", + "valueDescription": "UUID of the transition" + }, { "valueName": "transitionKind", "valueType": "String", @@ -4488,8 +5121,16 @@ "valueType": "String", "valueDescription": "Name of the input to open the dialog of", "valueRestrictions": null, - "valueOptional": false, - "valueOptionalBehavior": null + "valueOptional": true, + "valueOptionalBehavior": "Unknown" + }, + { + "valueName": "inputUuid", + "valueType": "String", + "valueDescription": "UUID of the input to open the dialog of", + "valueRestrictions": null, + "valueOptional": true, + "valueOptionalBehavior": "Unknown" } ], "responseFields": [] @@ -4508,8 +5149,16 @@ "valueType": "String", "valueDescription": "Name of the input to open the dialog of", "valueRestrictions": null, - "valueOptional": false, - "valueOptionalBehavior": null + "valueOptional": true, + "valueOptionalBehavior": "Unknown" + }, + { + "valueName": "inputUuid", + "valueType": "String", + "valueDescription": "UUID of the input to open the dialog of", + "valueRestrictions": null, + "valueOptional": true, + "valueOptionalBehavior": "Unknown" } ], "responseFields": [] @@ -4528,8 +5177,16 @@ "valueType": "String", "valueDescription": "Name of the input to open the dialog of", "valueRestrictions": null, - "valueOptional": false, - "valueOptionalBehavior": null + "valueOptional": true, + "valueOptionalBehavior": "Unknown" + }, + { + "valueName": "inputUuid", + "valueType": "String", + "valueDescription": "UUID of the input to open the dialog of", + "valueRestrictions": null, + "valueOptional": true, + "valueOptionalBehavior": "Unknown" } ], "responseFields": [] @@ -4601,8 +5258,16 @@ "valueType": "String", "valueDescription": "Name of the source to open a projector for", "valueRestrictions": null, - "valueOptional": false, - "valueOptionalBehavior": null + "valueOptional": true, + "valueOptionalBehavior": "Unknown" + }, + { + "valueName": "sourceUuid", + "valueType": "String", + "valueDescription": "UUID of the source to open a projector for", + "valueRestrictions": null, + "valueOptional": true, + "valueOptionalBehavior": "Unknown" }, { "valueName": "monitorIndex", @@ -4840,6 +5505,33 @@ } ] }, + { + "description": "An source filter's settings have changed (been updated).", + "eventType": "SourceFilterSettingsChanged", + "eventSubscription": "Filters", + "complexity": 3, + "rpcVersion": "1", + "deprecated": false, + "initialVersion": "5.4.0", + "category": "filters", + "dataFields": [ + { + "valueName": "sourceName", + "valueType": "String", + "valueDescription": "Name of the source the filter is on" + }, + { + "valueName": "filterName", + "valueType": "String", + "valueDescription": "Name of the filter" + }, + { + "valueName": "filterSettings", + "valueType": "Object", + "valueDescription": "New settings object of the filter" + } + ] + }, { "description": "A source filter's enable state has changed.", "eventType": "SourceFilterEnableStateChanged", @@ -4893,6 +5585,11 @@ "valueType": "String", "valueDescription": "Name of the input" }, + { + "valueName": "inputUuid", + "valueType": "String", + "valueDescription": "UUID of the input" + }, { "valueName": "inputKind", "valueType": "String", @@ -4929,6 +5626,11 @@ "valueName": "inputName", "valueType": "String", "valueDescription": "Name of the input" + }, + { + "valueName": "inputUuid", + "valueType": "String", + "valueDescription": "UUID of the input" } ] }, @@ -4942,6 +5644,11 @@ "initialVersion": "5.0.0", "category": "inputs", "dataFields": [ + { + "valueName": "inputUuid", + "valueType": "String", + "valueDescription": "UUID of the input" + }, { "valueName": "oldInputName", "valueType": "String", @@ -4954,6 +5661,33 @@ } ] }, + { + "description": "An input's settings have changed (been updated).\n\nNote: On some inputs, changing values in the properties dialog will cause an immediate update. Pressing the \"Cancel\" button will revert the settings, resulting in another event being fired.", + "eventType": "InputSettingsChanged", + "eventSubscription": "Inputs", + "complexity": 3, + "rpcVersion": "1", + "deprecated": false, + "initialVersion": "5.4.0", + "category": "inputs", + "dataFields": [ + { + "valueName": "inputName", + "valueType": "String", + "valueDescription": "Name of the input" + }, + { + "valueName": "inputUuid", + "valueType": "String", + "valueDescription": "UUID of the input" + }, + { + "valueName": "inputSettings", + "valueType": "Object", + "valueDescription": "New settings object of the input" + } + ] + }, { "description": "An input's active state has changed.\n\nWhen an input is active, it means it's being shown by the program feed.", "eventType": "InputActiveStateChanged", @@ -4969,6 +5703,11 @@ "valueType": "String", "valueDescription": "Name of the input" }, + { + "valueName": "inputUuid", + "valueType": "String", + "valueDescription": "UUID of the input" + }, { "valueName": "videoActive", "valueType": "Boolean", @@ -4991,6 +5730,11 @@ "valueType": "String", "valueDescription": "Name of the input" }, + { + "valueName": "inputUuid", + "valueType": "String", + "valueDescription": "UUID of the input" + }, { "valueName": "videoShowing", "valueType": "Boolean", @@ -5013,6 +5757,11 @@ "valueType": "String", "valueDescription": "Name of the input" }, + { + "valueName": "inputUuid", + "valueType": "String", + "valueDescription": "UUID of the input" + }, { "valueName": "inputMuted", "valueType": "Boolean", @@ -5035,6 +5784,11 @@ "valueType": "String", "valueDescription": "Name of the input" }, + { + "valueName": "inputUuid", + "valueType": "String", + "valueDescription": "UUID of the input" + }, { "valueName": "inputVolumeMul", "valueType": "Number", @@ -5060,7 +5814,12 @@ { "valueName": "inputName", "valueType": "String", - "valueDescription": "Name of the affected input" + "valueDescription": "Name of the input" + }, + { + "valueName": "inputUuid", + "valueType": "String", + "valueDescription": "UUID of the input" }, { "valueName": "inputAudioBalance", @@ -5084,6 +5843,11 @@ "valueType": "String", "valueDescription": "Name of the input" }, + { + "valueName": "inputUuid", + "valueType": "String", + "valueDescription": "UUID of the input" + }, { "valueName": "inputAudioSyncOffset", "valueType": "Number", @@ -5106,6 +5870,11 @@ "valueType": "String", "valueDescription": "Name of the input" }, + { + "valueName": "inputUuid", + "valueType": "String", + "valueDescription": "UUID of the input" + }, { "valueName": "inputAudioTracks", "valueType": "Object", @@ -5128,6 +5897,11 @@ "valueType": "String", "valueDescription": "Name of the input" }, + { + "valueName": "inputUuid", + "valueType": "String", + "valueDescription": "UUID of the input" + }, { "valueName": "monitorType", "valueType": "String", @@ -5166,6 +5940,11 @@ "valueName": "inputName", "valueType": "String", "valueDescription": "Name of the input" + }, + { + "valueName": "inputUuid", + "valueType": "String", + "valueDescription": "UUID of the input" } ] }, @@ -5183,6 +5962,11 @@ "valueName": "inputName", "valueType": "String", "valueDescription": "Name of the input" + }, + { + "valueName": "inputUuid", + "valueType": "String", + "valueDescription": "UUID of the input" } ] }, @@ -5201,6 +5985,11 @@ "valueType": "String", "valueDescription": "Name of the input" }, + { + "valueName": "inputUuid", + "valueType": "String", + "valueDescription": "UUID of the input" + }, { "valueName": "mediaAction", "valueType": "String", @@ -5333,11 +6122,21 @@ "valueType": "String", "valueDescription": "Name of the scene the item was added to" }, + { + "valueName": "sceneUuid", + "valueType": "String", + "valueDescription": "UUID of the scene the item was added to" + }, { "valueName": "sourceName", "valueType": "String", "valueDescription": "Name of the underlying source (input/scene)" }, + { + "valueName": "sourceUuid", + "valueType": "String", + "valueDescription": "UUID of the underlying source (input/scene)" + }, { "valueName": "sceneItemId", "valueType": "Number", @@ -5365,11 +6164,21 @@ "valueType": "String", "valueDescription": "Name of the scene the item was removed from" }, + { + "valueName": "sceneUuid", + "valueType": "String", + "valueDescription": "UUID of the scene the item was removed from" + }, { "valueName": "sourceName", "valueType": "String", "valueDescription": "Name of the underlying source (input/scene)" }, + { + "valueName": "sourceUuid", + "valueType": "String", + "valueDescription": "UUID of the underlying source (input/scene)" + }, { "valueName": "sceneItemId", "valueType": "Number", @@ -5392,6 +6201,11 @@ "valueType": "String", "valueDescription": "Name of the scene" }, + { + "valueName": "sceneUuid", + "valueType": "String", + "valueDescription": "UUID of the scene" + }, { "valueName": "sceneItems", "valueType": "Array", @@ -5414,6 +6228,11 @@ "valueType": "String", "valueDescription": "Name of the scene the item is in" }, + { + "valueName": "sceneUuid", + "valueType": "String", + "valueDescription": "UUID of the scene the item is in" + }, { "valueName": "sceneItemId", "valueType": "Number", @@ -5441,6 +6260,11 @@ "valueType": "String", "valueDescription": "Name of the scene the item is in" }, + { + "valueName": "sceneUuid", + "valueType": "String", + "valueDescription": "UUID of the scene the item is in" + }, { "valueName": "sceneItemId", "valueType": "Number", @@ -5468,6 +6292,11 @@ "valueType": "String", "valueDescription": "Name of the scene the item is in" }, + { + "valueName": "sceneUuid", + "valueType": "String", + "valueDescription": "UUID of the scene the item is in" + }, { "valueName": "sceneItemId", "valueType": "Number", @@ -5490,6 +6319,11 @@ "valueType": "String", "valueDescription": "The name of the scene the item is in" }, + { + "valueName": "sceneUuid", + "valueType": "String", + "valueDescription": "The UUID of the scene the item is in" + }, { "valueName": "sceneItemId", "valueType": "Number", @@ -5517,6 +6351,11 @@ "valueType": "String", "valueDescription": "Name of the new scene" }, + { + "valueName": "sceneUuid", + "valueType": "String", + "valueDescription": "UUID of the new scene" + }, { "valueName": "isGroup", "valueType": "Boolean", @@ -5539,6 +6378,11 @@ "valueType": "String", "valueDescription": "Name of the removed scene" }, + { + "valueName": "sceneUuid", + "valueType": "String", + "valueDescription": "UUID of the removed scene" + }, { "valueName": "isGroup", "valueType": "Boolean", @@ -5556,6 +6400,11 @@ "initialVersion": "5.0.0", "category": "scenes", "dataFields": [ + { + "valueName": "sceneUuid", + "valueType": "String", + "valueDescription": "UUID of the scene" + }, { "valueName": "oldSceneName", "valueType": "String", @@ -5582,6 +6431,11 @@ "valueName": "sceneName", "valueType": "String", "valueDescription": "Name of the scene that was switched to" + }, + { + "valueName": "sceneUuid", + "valueType": "String", + "valueDescription": "UUID of the scene that was switched to" } ] }, @@ -5599,6 +6453,11 @@ "valueName": "sceneName", "valueType": "String", "valueDescription": "Name of the scene that was switched to" + }, + { + "valueName": "sceneUuid", + "valueType": "String", + "valueDescription": "UUID of the scene that was switched to" } ] }, @@ -5633,6 +6492,11 @@ "valueName": "transitionName", "valueType": "String", "valueDescription": "Name of the new transition" + }, + { + "valueName": "transitionUuid", + "valueType": "String", + "valueDescription": "UUID of the new transition" } ] }, @@ -5667,6 +6531,11 @@ "valueName": "transitionName", "valueType": "String", "valueDescription": "Scene transition name" + }, + { + "valueName": "transitionUuid", + "valueType": "String", + "valueDescription": "Scene transition UUID" } ] }, @@ -5684,6 +6553,11 @@ "valueName": "transitionName", "valueType": "String", "valueDescription": "Scene transition name" + }, + { + "valueName": "transitionUuid", + "valueType": "String", + "valueDescription": "Scene transition UUID" } ] }, @@ -5701,6 +6575,11 @@ "valueName": "transitionName", "valueType": "String", "valueDescription": "Scene transition name" + }, + { + "valueName": "transitionUuid", + "valueType": "String", + "valueDescription": "Scene transition UUID" } ] }, diff --git a/docs/generated/protocol.md b/docs/generated/protocol.md index e6a206332..06f8a929f 100644 --- a/docs/generated/protocol.md +++ b/docs/generated/protocol.md @@ -1,7 +1,7 @@ -# obs-websocket 5.1.0 Protocol +# obs-websocket 5.x.x Protocol ## Main Table of Contents @@ -63,7 +63,7 @@ These steps should be followed precisely. Failure to connect to the server as in - The server receives and processes the `Identify` sent by the client. - If authentication is required and the `Identify` message data does not contain an `authentication` string, or the string is not correct, the connection is closed with `WebSocketCloseCode::AuthenticationFailed` - - If the client has requested an `rpcVersion` which the server cannot use, the connection is closed with `WebSocketCloseCode::UnsupportedRpcVersion`. This system allows both the server and client to have seamless backwards compatability. + - If the client has requested an `rpcVersion` which the server cannot use, the connection is closed with `WebSocketCloseCode::UnsupportedRpcVersion`. This system allows both the server and client to have seamless backwards compatibility. - If any other parameters are malformed (invalid type, etc), the connection is closed with an appropriate close code. - Once identification is processed on the server, the server responds to the client with an [OpCode 2 `Identified`](#identified-opcode-2). @@ -471,6 +471,7 @@ These are enumeration declarations, which are referenced throughout obs-websocke - [RequestStatus::UnknownRequestType](#requeststatusunknownrequesttype) - [RequestStatus::GenericError](#requeststatusgenericerror) - [RequestStatus::UnsupportedRequestBatchExecutionType](#requeststatusunsupportedrequestbatchexecutiontype) + - [RequestStatus::NotReady](#requeststatusnotready) - [RequestStatus::MissingRequestField](#requeststatusmissingrequestfield) - [RequestStatus::MissingRequestData](#requeststatusmissingrequestdata) - [RequestStatus::InvalidRequestField](#requeststatusinvalidrequestfield) @@ -879,6 +880,18 @@ The request batch execution type is not supported. --- +### RequestStatus::NotReady + +The server is not ready to handle the request. + +Note: This usually occurs during OBS scene collection change or exit. Requests may be tried again after a delay if this code is given. + +- Identifier Value: `207` +- Latest Supported RPC Version: `1` +- Added in v5.3.0 + +--- + ### RequestStatus::MissingRequestField A required request field is missing. @@ -1517,6 +1530,7 @@ The output has been resumed (unpaused). - [InputCreated](#inputcreated) - [InputRemoved](#inputremoved) - [InputNameChanged](#inputnamechanged) + - [InputSettingsChanged](#inputsettingschanged) - [InputActiveStateChanged](#inputactivestatechanged) - [InputShowStateChanged](#inputshowstatechanged) - [InputMuteStateChanged](#inputmutestatechanged) @@ -1537,6 +1551,7 @@ The output has been resumed (unpaused). - [SourceFilterCreated](#sourcefiltercreated) - [SourceFilterRemoved](#sourcefilterremoved) - [SourceFilterNameChanged](#sourcefilternamechanged) + - [SourceFilterSettingsChanged](#sourcefiltersettingschanged) - [SourceFilterEnableStateChanged](#sourcefilterenablestatechanged) - [Scene Items Events](#scene-items-events) - [SceneItemCreated](#sceneitemcreated) @@ -1723,6 +1738,7 @@ A new scene has been created. | Name | Type | Description | | ---- | :---: | ----------- | | sceneName | String | Name of the new scene | +| sceneUuid | String | UUID of the new scene | | isGroup | Boolean | Whether the new scene is a group | --- @@ -1740,6 +1756,7 @@ A scene has been removed. | Name | Type | Description | | ---- | :---: | ----------- | | sceneName | String | Name of the removed scene | +| sceneUuid | String | UUID of the removed scene | | isGroup | Boolean | Whether the scene was a group | --- @@ -1756,6 +1773,7 @@ The name of a scene has changed. | Name | Type | Description | | ---- | :---: | ----------- | +| sceneUuid | String | UUID of the scene | | oldSceneName | String | Old name of the scene | | sceneName | String | New name of the scene | @@ -1774,6 +1792,7 @@ The current program scene has changed. | Name | Type | Description | | ---- | :---: | ----------- | | sceneName | String | Name of the scene that was switched to | +| sceneUuid | String | UUID of the scene that was switched to | --- @@ -1790,6 +1809,7 @@ The current preview scene has changed. | Name | Type | Description | | ---- | :---: | ----------- | | sceneName | String | Name of the scene that was switched to | +| sceneUuid | String | UUID of the scene that was switched to | --- @@ -1824,6 +1844,7 @@ An input has been created. | Name | Type | Description | | ---- | :---: | ----------- | | inputName | String | Name of the input | +| inputUuid | String | UUID of the input | | inputKind | String | The kind of the input | | unversionedInputKind | String | The unversioned kind of input (aka no `_v2` stuff) | | inputSettings | Object | The settings configured to the input when it was created | @@ -1844,6 +1865,7 @@ An input has been removed. | Name | Type | Description | | ---- | :---: | ----------- | | inputName | String | Name of the input | +| inputUuid | String | UUID of the input | --- @@ -1859,11 +1881,32 @@ The name of an input has changed. | Name | Type | Description | | ---- | :---: | ----------- | +| inputUuid | String | UUID of the input | | oldInputName | String | Old name of the input | | inputName | String | New name of the input | --- +### InputSettingsChanged + +An input's settings have changed (been updated). + +Note: On some inputs, changing values in the properties dialog will cause an immediate update. Pressing the "Cancel" button will revert the settings, resulting in another event being fired. + +- Complexity Rating: `3/5` +- Latest Supported RPC Version: `1` +- Added in v5.4.0 + +**Data Fields:** + +| Name | Type | Description | +| ---- | :---: | ----------- | +| inputName | String | Name of the input | +| inputUuid | String | UUID of the input | +| inputSettings | Object | New settings object of the input | + +--- + ### InputActiveStateChanged An input's active state has changed. @@ -1879,6 +1922,7 @@ When an input is active, it means it's being shown by the program feed. | Name | Type | Description | | ---- | :---: | ----------- | | inputName | String | Name of the input | +| inputUuid | String | UUID of the input | | videoActive | Boolean | Whether the input is active | --- @@ -1898,6 +1942,7 @@ When an input is showing, it means it's being shown by the preview or a dialog. | Name | Type | Description | | ---- | :---: | ----------- | | inputName | String | Name of the input | +| inputUuid | String | UUID of the input | | videoShowing | Boolean | Whether the input is showing | --- @@ -1915,6 +1960,7 @@ An input's mute state has changed. | Name | Type | Description | | ---- | :---: | ----------- | | inputName | String | Name of the input | +| inputUuid | String | UUID of the input | | inputMuted | Boolean | Whether the input is muted | --- @@ -1932,6 +1978,7 @@ An input's volume level has changed. | Name | Type | Description | | ---- | :---: | ----------- | | inputName | String | Name of the input | +| inputUuid | String | UUID of the input | | inputVolumeMul | Number | New volume level multiplier | | inputVolumeDb | Number | New volume level in dB | @@ -1949,7 +1996,8 @@ The audio balance value of an input has changed. | Name | Type | Description | | ---- | :---: | ----------- | -| inputName | String | Name of the affected input | +| inputName | String | Name of the input | +| inputUuid | String | UUID of the input | | inputAudioBalance | Number | New audio balance value of the input | --- @@ -1967,6 +2015,7 @@ The sync offset of an input has changed. | Name | Type | Description | | ---- | :---: | ----------- | | inputName | String | Name of the input | +| inputUuid | String | UUID of the input | | inputAudioSyncOffset | Number | New sync offset in milliseconds | --- @@ -1984,6 +2033,7 @@ The audio tracks of an input have changed. | Name | Type | Description | | ---- | :---: | ----------- | | inputName | String | Name of the input | +| inputUuid | String | UUID of the input | | inputAudioTracks | Object | Object of audio tracks along with their associated enable states | --- @@ -2007,6 +2057,7 @@ Available types are: | Name | Type | Description | | ---- | :---: | ----------- | | inputName | String | Name of the input | +| inputUuid | String | UUID of the input | | monitorType | String | New monitor type of the input | --- @@ -2040,6 +2091,7 @@ The current scene transition has changed. | Name | Type | Description | | ---- | :---: | ----------- | | transitionName | String | Name of the new transition | +| transitionUuid | String | UUID of the new transition | --- @@ -2072,6 +2124,7 @@ A scene transition has started. | Name | Type | Description | | ---- | :---: | ----------- | | transitionName | String | Scene transition name | +| transitionUuid | String | Scene transition UUID | --- @@ -2090,6 +2143,7 @@ Note: Does not appear to trigger when the transition is interrupted by the user. | Name | Type | Description | | ---- | :---: | ----------- | | transitionName | String | Scene transition name | +| transitionUuid | String | Scene transition UUID | --- @@ -2111,6 +2165,7 @@ Note: Appears to be called by every transition, regardless of relevance. | Name | Type | Description | | ---- | :---: | ----------- | | transitionName | String | Scene transition name | +| transitionUuid | String | Scene transition UUID | ## Filters Events @@ -2187,6 +2242,24 @@ The name of a source filter has changed. --- +### SourceFilterSettingsChanged + +An source filter's settings have changed (been updated). + +- Complexity Rating: `3/5` +- Latest Supported RPC Version: `1` +- Added in v5.4.0 + +**Data Fields:** + +| Name | Type | Description | +| ---- | :---: | ----------- | +| sourceName | String | Name of the source the filter is on | +| filterName | String | Name of the filter | +| filterSettings | Object | New settings object of the filter | + +--- + ### SourceFilterEnableStateChanged A source filter's enable state has changed. @@ -2218,7 +2291,9 @@ A scene item has been created. | Name | Type | Description | | ---- | :---: | ----------- | | sceneName | String | Name of the scene the item was added to | +| sceneUuid | String | UUID of the scene the item was added to | | sourceName | String | Name of the underlying source (input/scene) | +| sourceUuid | String | UUID of the underlying source (input/scene) | | sceneItemId | Number | Numeric ID of the scene item | | sceneItemIndex | Number | Index position of the item | @@ -2239,7 +2314,9 @@ This event is not emitted when the scene the item is in is removed. | Name | Type | Description | | ---- | :---: | ----------- | | sceneName | String | Name of the scene the item was removed from | +| sceneUuid | String | UUID of the scene the item was removed from | | sourceName | String | Name of the underlying source (input/scene) | +| sourceUuid | String | UUID of the underlying source (input/scene) | | sceneItemId | Number | Numeric ID of the scene item | --- @@ -2257,6 +2334,7 @@ A scene's item list has been reindexed. | Name | Type | Description | | ---- | :---: | ----------- | | sceneName | String | Name of the scene | +| sceneUuid | String | UUID of the scene | | sceneItems | Array<Object> | Array of scene item objects | --- @@ -2274,6 +2352,7 @@ A scene item's enable state has changed. | Name | Type | Description | | ---- | :---: | ----------- | | sceneName | String | Name of the scene the item is in | +| sceneUuid | String | UUID of the scene the item is in | | sceneItemId | Number | Numeric ID of the scene item | | sceneItemEnabled | Boolean | Whether the scene item is enabled (visible) | @@ -2292,6 +2371,7 @@ A scene item's lock state has changed. | Name | Type | Description | | ---- | :---: | ----------- | | sceneName | String | Name of the scene the item is in | +| sceneUuid | String | UUID of the scene the item is in | | sceneItemId | Number | Numeric ID of the scene item | | sceneItemLocked | Boolean | Whether the scene item is locked | @@ -2310,6 +2390,7 @@ A scene item has been selected in the Ui. | Name | Type | Description | | ---- | :---: | ----------- | | sceneName | String | Name of the scene the item is in | +| sceneUuid | String | UUID of the scene the item is in | | sceneItemId | Number | Numeric ID of the scene item | --- @@ -2327,6 +2408,7 @@ The transform/crop of a scene item has changed. | Name | Type | Description | | ---- | :---: | ----------- | | sceneName | String | The name of the scene the item is in | +| sceneUuid | String | The UUID of the scene the item is in | | sceneItemId | Number | Numeric ID of the scene item | | sceneItemTransform | Object | New transform/crop info of the scene item | @@ -2430,6 +2512,7 @@ A media input has started playing. | Name | Type | Description | | ---- | :---: | ----------- | | inputName | String | Name of the input | +| inputUuid | String | UUID of the input | --- @@ -2446,6 +2529,7 @@ A media input has finished playing. | Name | Type | Description | | ---- | :---: | ----------- | | inputName | String | Name of the input | +| inputUuid | String | UUID of the input | --- @@ -2462,6 +2546,7 @@ An action has been performed on an input. | Name | Type | Description | | ---- | :---: | ----------- | | inputName | String | Name of the input | +| inputUuid | String | UUID of the input | | mediaAction | String | Action performed on the input. See `ObsMediaInputAction` enum | ## Ui Events @@ -2530,6 +2615,7 @@ communication is desired. - [GetStreamServiceSettings](#getstreamservicesettings) - [SetStreamServiceSettings](#setstreamservicesettings) - [GetRecordDirectory](#getrecorddirectory) + - [SetRecordDirectory](#setrecorddirectory) - [Sources Requests](#sources-requests) - [GetSourceActive](#getsourceactive) - [GetSourceScreenshot](#getsourcescreenshot) @@ -2582,6 +2668,7 @@ communication is desired. - [TriggerStudioModeTransition](#triggerstudiomodetransition) - [SetTBarPosition](#settbarposition) - [Filters Requests](#filters-1-requests) + - [GetSourceFilterKindList](#getsourcefilterkindlist) - [GetSourceFilterList](#getsourcefilterlist) - [GetSourceFilterDefaultSettings](#getsourcefilterdefaultsettings) - [CreateSourceFilter](#createsourcefilter) @@ -2595,6 +2682,7 @@ communication is desired. - [GetSceneItemList](#getsceneitemlist) - [GetGroupSceneItemList](#getgroupsceneitemlist) - [GetSceneItemId](#getsceneitemid) + - [GetSceneItemSource](#getsceneitemsource) - [CreateSceneItem](#createsceneitem) - [RemoveSceneItem](#removesceneitem) - [DuplicateSceneItem](#duplicatesceneitem) @@ -2752,9 +2840,11 @@ If a plugin or script implements vendor requests or events, documentation is exp ### GetHotkeyList -Gets an array of all hotkey names in OBS +Gets an array of all hotkey names in OBS. -- Complexity Rating: `3/5` +Note: Hotkey functionality in obs-websocket comes as-is, and we do not guarantee support if things are broken. In 9/10 usages of hotkey requests, there exists a better, more reliable method via other requests. + +- Complexity Rating: `4/5` - Latest Supported RPC Version: `1` - Added in v5.0.0 @@ -2768,9 +2858,11 @@ Gets an array of all hotkey names in OBS ### TriggerHotkeyByName -Triggers a hotkey using its name. See `GetHotkeyList` +Triggers a hotkey using its name. See `GetHotkeyList`. -- Complexity Rating: `3/5` +Note: Hotkey functionality in obs-websocket comes as-is, and we do not guarantee support if things are broken. In 9/10 usages of hotkey requests, there exists a better, more reliable method via other requests. + +- Complexity Rating: `4/5` - Latest Supported RPC Version: `1` - Added in v5.0.0 @@ -2779,6 +2871,7 @@ Triggers a hotkey using its name. See `GetHotkeyList` | Name | Type | Description | Value Restrictions | ?Default Behavior | | ---- | :---: | ----------- | :----------------: | ----------------- | | hotkeyName | String | Name of the hotkey to trigger | None | N/A | +| ?contextName | String | Name of context of the hotkey to trigger | None | Unknown | --- @@ -2786,6 +2879,8 @@ Triggers a hotkey using its name. See `GetHotkeyList` Triggers a hotkey using a sequence of keys. +Note: Hotkey functionality in obs-websocket comes as-is, and we do not guarantee support if things are broken. In 9/10 usages of hotkey requests, there exists a better, more reliable method via other requests. + - Complexity Rating: `4/5` - Latest Supported RPC Version: `1` - Added in v5.0.0 @@ -3107,7 +3202,7 @@ Note: Simple RTMP settings can be set with type `rtmp_custom` and the settings f Gets the current directory that the record output is set to. -- Complexity Rating: `1/5` +- Complexity Rating: `2/5` - Latest Supported RPC Version: `1` - Added in v5.0.0 @@ -3117,6 +3212,22 @@ Gets the current directory that the record output is set to. | ---- | :---: | ----------- | | recordDirectory | String | Output directory | +--- + +### SetRecordDirectory + +Sets the current directory that the record output writes files to. + +- Complexity Rating: `2/5` +- Latest Supported RPC Version: `1` +- Added in v5.3.0 + +**Request Fields:** + +| Name | Type | Description | Value Restrictions | ?Default Behavior | +| ---- | :---: | ----------- | :----------------: | ----------------- | +| recordDirectory | String | Output directory | None | N/A | + ## Sources Requests ### GetSourceActive @@ -3133,7 +3244,8 @@ Gets the active and show state of a source. | Name | Type | Description | Value Restrictions | ?Default Behavior | | ---- | :---: | ----------- | :----------------: | ----------------- | -| sourceName | String | Name of the source to get the active state of | None | N/A | +| ?sourceName | String | Name of the source to get the active state of | None | Unknown | +| ?sourceUuid | String | UUID of the source to get the active state of | None | Unknown | **Response Fields:** @@ -3161,7 +3273,8 @@ If `imageWidth` and `imageHeight` are not specified, the compressed image will u | Name | Type | Description | Value Restrictions | ?Default Behavior | | ---- | :---: | ----------- | :----------------: | ----------------- | -| sourceName | String | Name of the source to take a screenshot of | None | N/A | +| ?sourceName | String | Name of the source to take a screenshot of | None | Unknown | +| ?sourceUuid | String | UUID of the source to take a screenshot of | None | Unknown | | imageFormat | String | Image compression format to use. Use `GetVersion` to get compatible image formats | None | N/A | | ?imageWidth | Number | Width to scale the screenshot to | >= 8, <= 4096 | Source value is used | | ?imageHeight | Number | Height to scale the screenshot to | >= 8, <= 4096 | Source value is used | @@ -3192,19 +3305,14 @@ If `imageWidth` and `imageHeight` are not specified, the compressed image will u | Name | Type | Description | Value Restrictions | ?Default Behavior | | ---- | :---: | ----------- | :----------------: | ----------------- | -| sourceName | String | Name of the source to take a screenshot of | None | N/A | +| ?sourceName | String | Name of the source to take a screenshot of | None | Unknown | +| ?sourceUuid | String | UUID of the source to take a screenshot of | None | Unknown | | imageFormat | String | Image compression format to use. Use `GetVersion` to get compatible image formats | None | N/A | | imageFilePath | String | Path to save the screenshot file to. Eg. `C:\Users\user\Desktop\screenshot.png` | None | N/A | | ?imageWidth | Number | Width to scale the screenshot to | >= 8, <= 4096 | Source value is used | | ?imageHeight | Number | Height to scale the screenshot to | >= 8, <= 4096 | Source value is used | | ?imageCompressionQuality | Number | Compression quality to use. 0 for high compression, 100 for uncompressed. -1 to use "default" (whatever that means, idk) | >= -1, <= 100 | -1 | -**Response Fields:** - -| Name | Type | Description | -| ---- | :---: | ----------- | -| imageData | String | Base64-encoded screenshot | - ## Scenes Requests ### GetSceneList @@ -3219,8 +3327,10 @@ Gets an array of all scenes in OBS. | Name | Type | Description | | ---- | :---: | ----------- | -| currentProgramSceneName | String | Current program scene | -| currentPreviewSceneName | String | Current preview scene. `null` if not in studio mode | +| currentProgramSceneName | String | Current program scene name. Can be `null` if internal state desync | +| currentProgramSceneUuid | String | Current program scene UUID. Can be `null` if internal state desync | +| currentPreviewSceneName | String | Current preview scene name. `null` if not in studio mode | +| currentPreviewSceneUuid | String | Current preview scene UUID. `null` if not in studio mode | | scenes | Array<Object> | Array of scenes | --- @@ -3247,6 +3357,8 @@ Groups in OBS are actually scenes, but renamed and modified. In obs-websocket, w Gets the current program scene. +Note: This request is slated to have the `currentProgram`-prefixed fields removed from in an upcoming RPC version. + - Complexity Rating: `1/5` - Latest Supported RPC Version: `1` - Added in v5.0.0 @@ -3255,7 +3367,10 @@ Gets the current program scene. | Name | Type | Description | | ---- | :---: | ----------- | -| currentProgramSceneName | String | Current program scene | +| sceneName | String | Current program scene name | +| sceneUuid | String | Current program scene UUID | +| currentProgramSceneName | String | Current program scene name (Deprecated) | +| currentProgramSceneUuid | String | Current program scene UUID (Deprecated) | --- @@ -3271,7 +3386,8 @@ Sets the current program scene. | Name | Type | Description | Value Restrictions | ?Default Behavior | | ---- | :---: | ----------- | :----------------: | ----------------- | -| sceneName | String | Scene to set as the current program scene | None | N/A | +| ?sceneName | String | Scene name to set as the current program scene | None | Unknown | +| ?sceneUuid | String | Scene UUID to set as the current program scene | None | Unknown | --- @@ -3281,6 +3397,8 @@ Gets the current preview scene. Only available when studio mode is enabled. +Note: This request is slated to have the `currentPreview`-prefixed fields removed from in an upcoming RPC version. + - Complexity Rating: `1/5` - Latest Supported RPC Version: `1` - Added in v5.0.0 @@ -3289,7 +3407,10 @@ Only available when studio mode is enabled. | Name | Type | Description | | ---- | :---: | ----------- | -| currentPreviewSceneName | String | Current preview scene | +| sceneName | String | Current preview scene name | +| sceneUuid | String | Current preview scene UUID | +| currentPreviewSceneName | String | Current preview scene name | +| currentPreviewSceneUuid | String | Current preview scene UUID | --- @@ -3307,7 +3428,8 @@ Only available when studio mode is enabled. | Name | Type | Description | Value Restrictions | ?Default Behavior | | ---- | :---: | ----------- | :----------------: | ----------------- | -| sceneName | String | Scene to set as the current preview scene | None | N/A | +| ?sceneName | String | Scene name to set as the current preview scene | None | Unknown | +| ?sceneUuid | String | Scene UUID to set as the current preview scene | None | Unknown | --- @@ -3325,6 +3447,12 @@ Creates a new scene in OBS. | ---- | :---: | ----------- | :----------------: | ----------------- | | sceneName | String | Name for the new scene | None | N/A | +**Response Fields:** + +| Name | Type | Description | +| ---- | :---: | ----------- | +| sceneUuid | String | UUID of the created scene | + --- ### RemoveScene @@ -3339,7 +3467,8 @@ Removes a scene from OBS. | Name | Type | Description | Value Restrictions | ?Default Behavior | | ---- | :---: | ----------- | :----------------: | ----------------- | -| sceneName | String | Name of the scene to remove | None | N/A | +| ?sceneName | String | Name of the scene to remove | None | Unknown | +| ?sceneUuid | String | UUID of the scene to remove | None | Unknown | --- @@ -3355,7 +3484,8 @@ Sets the name of a scene (rename). | Name | Type | Description | Value Restrictions | ?Default Behavior | | ---- | :---: | ----------- | :----------------: | ----------------- | -| sceneName | String | Name of the scene to be renamed | None | N/A | +| ?sceneName | String | Name of the scene to be renamed | None | Unknown | +| ?sceneUuid | String | UUID of the scene to be renamed | None | Unknown | | newSceneName | String | New name for the scene | None | N/A | --- @@ -3364,6 +3494,8 @@ Sets the name of a scene (rename). Gets the scene transition overridden for a scene. +Note: A transition UUID response field is not currently able to be implemented as of 2024-1-18. + - Complexity Rating: `2/5` - Latest Supported RPC Version: `1` - Added in v5.0.0 @@ -3372,7 +3504,8 @@ Gets the scene transition overridden for a scene. | Name | Type | Description | Value Restrictions | ?Default Behavior | | ---- | :---: | ----------- | :----------------: | ----------------- | -| sceneName | String | Name of the scene | None | N/A | +| ?sceneName | String | Name of the scene | None | Unknown | +| ?sceneUuid | String | UUID of the scene | None | Unknown | **Response Fields:** @@ -3385,7 +3518,7 @@ Gets the scene transition overridden for a scene. ### SetSceneSceneTransitionOverride -Gets the scene transition overridden for a scene. +Sets the scene transition overridden for a scene. - Complexity Rating: `2/5` - Latest Supported RPC Version: `1` @@ -3395,7 +3528,8 @@ Gets the scene transition overridden for a scene. | Name | Type | Description | Value Restrictions | ?Default Behavior | | ---- | :---: | ----------- | :----------------: | ----------------- | -| sceneName | String | Name of the scene | None | N/A | +| ?sceneName | String | Name of the scene | None | Unknown | +| ?sceneUuid | String | UUID of the scene | None | Unknown | | ?transitionName | String | Name of the scene transition to use as override. Specify `null` to remove | None | Unchanged | | ?transitionDuration | Number | Duration to use for any overridden transition. Specify `null` to remove | >= 50, <= 20000 | Unchanged | @@ -3478,7 +3612,8 @@ Creates a new input, adding it as a scene item to the specified scene. | Name | Type | Description | Value Restrictions | ?Default Behavior | | ---- | :---: | ----------- | :----------------: | ----------------- | -| sceneName | String | Name of the scene to add the input to as a scene item | None | N/A | +| ?sceneName | String | Name of the scene to add the input to as a scene item | None | Unknown | +| ?sceneUuid | String | UUID of the scene to add the input to as a scene item | None | Unknown | | inputName | String | Name of the new input to created | None | N/A | | inputKind | String | The kind of input to be created | None | N/A | | ?inputSettings | Object | Settings object to initialize the input with | None | Default settings used | @@ -3488,6 +3623,7 @@ Creates a new input, adding it as a scene item to the specified scene. | Name | Type | Description | | ---- | :---: | ----------- | +| inputUuid | String | UUID of the newly created input | | sceneItemId | Number | ID of the newly created scene item | --- @@ -3506,7 +3642,8 @@ Note: Will immediately remove all associated scene items. | Name | Type | Description | Value Restrictions | ?Default Behavior | | ---- | :---: | ----------- | :----------------: | ----------------- | -| inputName | String | Name of the input to remove | None | N/A | +| ?inputName | String | Name of the input to remove | None | Unknown | +| ?inputUuid | String | UUID of the input to remove | None | Unknown | --- @@ -3522,7 +3659,8 @@ Sets the name of an input (rename). | Name | Type | Description | Value Restrictions | ?Default Behavior | | ---- | :---: | ----------- | :----------------: | ----------------- | -| inputName | String | Current input name | None | N/A | +| ?inputName | String | Current input name | None | Unknown | +| ?inputUuid | String | Current input UUID | None | Unknown | | newInputName | String | New name for the input | None | N/A | --- @@ -3563,7 +3701,8 @@ Note: Does not include defaults. To create the entire settings object, overlay ` | Name | Type | Description | Value Restrictions | ?Default Behavior | | ---- | :---: | ----------- | :----------------: | ----------------- | -| inputName | String | Name of the input to get the settings of | None | N/A | +| ?inputName | String | Name of the input to get the settings of | None | Unknown | +| ?inputUuid | String | UUID of the input to get the settings of | None | Unknown | **Response Fields:** @@ -3586,7 +3725,8 @@ Sets the settings of an input. | Name | Type | Description | Value Restrictions | ?Default Behavior | | ---- | :---: | ----------- | :----------------: | ----------------- | -| inputName | String | Name of the input to set the settings of | None | N/A | +| ?inputName | String | Name of the input to set the settings of | None | Unknown | +| ?inputUuid | String | UUID of the input to set the settings of | None | Unknown | | inputSettings | Object | Object of settings to apply | None | N/A | | ?overlay | Boolean | True == apply the settings on top of existing ones, False == reset the input to its defaults, then apply settings. | None | true | @@ -3604,7 +3744,8 @@ Gets the audio mute state of an input. | Name | Type | Description | Value Restrictions | ?Default Behavior | | ---- | :---: | ----------- | :----------------: | ----------------- | -| inputName | String | Name of input to get the mute state of | None | N/A | +| ?inputName | String | Name of input to get the mute state of | None | Unknown | +| ?inputUuid | String | UUID of input to get the mute state of | None | Unknown | **Response Fields:** @@ -3626,7 +3767,8 @@ Sets the audio mute state of an input. | Name | Type | Description | Value Restrictions | ?Default Behavior | | ---- | :---: | ----------- | :----------------: | ----------------- | -| inputName | String | Name of the input to set the mute state of | None | N/A | +| ?inputName | String | Name of the input to set the mute state of | None | Unknown | +| ?inputUuid | String | UUID of the input to set the mute state of | None | Unknown | | inputMuted | Boolean | Whether to mute the input or not | None | N/A | --- @@ -3643,7 +3785,8 @@ Toggles the audio mute state of an input. | Name | Type | Description | Value Restrictions | ?Default Behavior | | ---- | :---: | ----------- | :----------------: | ----------------- | -| inputName | String | Name of the input to toggle the mute state of | None | N/A | +| ?inputName | String | Name of the input to toggle the mute state of | None | Unknown | +| ?inputUuid | String | UUID of the input to toggle the mute state of | None | Unknown | **Response Fields:** @@ -3665,7 +3808,8 @@ Gets the current volume setting of an input. | Name | Type | Description | Value Restrictions | ?Default Behavior | | ---- | :---: | ----------- | :----------------: | ----------------- | -| inputName | String | Name of the input to get the volume of | None | N/A | +| ?inputName | String | Name of the input to get the volume of | None | Unknown | +| ?inputUuid | String | UUID of the input to get the volume of | None | Unknown | **Response Fields:** @@ -3688,7 +3832,8 @@ Sets the volume setting of an input. | Name | Type | Description | Value Restrictions | ?Default Behavior | | ---- | :---: | ----------- | :----------------: | ----------------- | -| inputName | String | Name of the input to set the volume of | None | N/A | +| ?inputName | String | Name of the input to set the volume of | None | Unknown | +| ?inputUuid | String | UUID of the input to set the volume of | None | Unknown | | ?inputVolumeMul | Number | Volume setting in mul | >= 0, <= 20 | `inputVolumeDb` should be specified | | ?inputVolumeDb | Number | Volume setting in dB | >= -100, <= 26 | `inputVolumeMul` should be specified | @@ -3706,7 +3851,8 @@ Gets the audio balance of an input. | Name | Type | Description | Value Restrictions | ?Default Behavior | | ---- | :---: | ----------- | :----------------: | ----------------- | -| inputName | String | Name of the input to get the audio balance of | None | N/A | +| ?inputName | String | Name of the input to get the audio balance of | None | Unknown | +| ?inputUuid | String | UUID of the input to get the audio balance of | None | Unknown | **Response Fields:** @@ -3728,7 +3874,8 @@ Sets the audio balance of an input. | Name | Type | Description | Value Restrictions | ?Default Behavior | | ---- | :---: | ----------- | :----------------: | ----------------- | -| inputName | String | Name of the input to set the audio balance of | None | N/A | +| ?inputName | String | Name of the input to set the audio balance of | None | Unknown | +| ?inputUuid | String | UUID of the input to set the audio balance of | None | Unknown | | inputAudioBalance | Number | New audio balance value | >= 0.0, <= 1.0 | N/A | --- @@ -3747,7 +3894,8 @@ Note: The audio sync offset can be negative too! | Name | Type | Description | Value Restrictions | ?Default Behavior | | ---- | :---: | ----------- | :----------------: | ----------------- | -| inputName | String | Name of the input to get the audio sync offset of | None | N/A | +| ?inputName | String | Name of the input to get the audio sync offset of | None | Unknown | +| ?inputUuid | String | UUID of the input to get the audio sync offset of | None | Unknown | **Response Fields:** @@ -3769,7 +3917,8 @@ Sets the audio sync offset of an input. | Name | Type | Description | Value Restrictions | ?Default Behavior | | ---- | :---: | ----------- | :----------------: | ----------------- | -| inputName | String | Name of the input to set the audio sync offset of | None | N/A | +| ?inputName | String | Name of the input to set the audio sync offset of | None | Unknown | +| ?inputUuid | String | UUID of the input to set the audio sync offset of | None | Unknown | | inputAudioSyncOffset | Number | New audio sync offset in milliseconds | >= -950, <= 20000 | N/A | --- @@ -3792,7 +3941,8 @@ The available audio monitor types are: | Name | Type | Description | Value Restrictions | ?Default Behavior | | ---- | :---: | ----------- | :----------------: | ----------------- | -| inputName | String | Name of the input to get the audio monitor type of | None | N/A | +| ?inputName | String | Name of the input to get the audio monitor type of | None | Unknown | +| ?inputUuid | String | UUID of the input to get the audio monitor type of | None | Unknown | **Response Fields:** @@ -3814,7 +3964,8 @@ Sets the audio monitor type of an input. | Name | Type | Description | Value Restrictions | ?Default Behavior | | ---- | :---: | ----------- | :----------------: | ----------------- | -| inputName | String | Name of the input to set the audio monitor type of | None | N/A | +| ?inputName | String | Name of the input to set the audio monitor type of | None | Unknown | +| ?inputUuid | String | UUID of the input to set the audio monitor type of | None | Unknown | | monitorType | String | Audio monitor type | None | N/A | --- @@ -3831,7 +3982,8 @@ Gets the enable state of all audio tracks of an input. | Name | Type | Description | Value Restrictions | ?Default Behavior | | ---- | :---: | ----------- | :----------------: | ----------------- | -| inputName | String | Name of the input | None | N/A | +| ?inputName | String | Name of the input | None | Unknown | +| ?inputUuid | String | UUID of the input | None | Unknown | **Response Fields:** @@ -3853,7 +4005,8 @@ Sets the enable state of audio tracks of an input. | Name | Type | Description | Value Restrictions | ?Default Behavior | | ---- | :---: | ----------- | :----------------: | ----------------- | -| inputName | String | Name of the input | None | N/A | +| ?inputName | String | Name of the input | None | Unknown | +| ?inputUuid | String | UUID of the input | None | Unknown | | inputAudioTracks | Object | Track settings to apply | None | N/A | --- @@ -3872,7 +4025,8 @@ Note: Use this in cases where an input provides a dynamic, selectable list of it | Name | Type | Description | Value Restrictions | ?Default Behavior | | ---- | :---: | ----------- | :----------------: | ----------------- | -| inputName | String | Name of the input | None | N/A | +| ?inputName | String | Name of the input | None | Unknown | +| ?inputUuid | String | UUID of the input | None | Unknown | | propertyName | String | Name of the list property to get the items of | None | N/A | **Response Fields:** @@ -3901,7 +4055,8 @@ Note: Use this in cases where there is a button in the properties of an input th | Name | Type | Description | Value Restrictions | ?Default Behavior | | ---- | :---: | ----------- | :----------------: | ----------------- | -| inputName | String | Name of the input | None | N/A | +| ?inputName | String | Name of the input | None | Unknown | +| ?inputUuid | String | UUID of the input | None | Unknown | | propertyName | String | Name of the button property to press | None | N/A | ## Transitions Requests @@ -3937,6 +4092,7 @@ Gets an array of all scene transitions in OBS. | Name | Type | Description | | ---- | :---: | ----------- | | currentSceneTransitionName | String | Name of the current scene transition. Can be null | +| currentSceneTransitionUuid | String | UUID of the current scene transition. Can be null | | currentSceneTransitionKind | String | Kind of the current scene transition. Can be null | | transitions | Array<Object> | Array of transitions | @@ -3955,6 +4111,7 @@ Gets information about the current scene transition. | Name | Type | Description | | ---- | :---: | ----------- | | transitionName | String | Name of the transition | +| transitionUuid | String | UUID of the transition | | transitionKind | String | Kind of the transition | | transitionFixed | Boolean | Whether the transition uses a fixed (unconfigurable) duration | | transitionDuration | Number | Configured transition duration in milliseconds. `null` if transition is fixed | @@ -4061,6 +4218,24 @@ Sets the position of the TBar. ## Filters Requests +### GetSourceFilterKindList + +Gets an array of all available source filter kinds. + +Similar to `GetInputKindList` + +- Complexity Rating: `2/5` +- Latest Supported RPC Version: `1` +- Added in v5.4.0 + +**Response Fields:** + +| Name | Type | Description | +| ---- | :---: | ----------- | +| sourceFilterKinds | Array<String> | Array of source filter kinds | + +--- + ### GetSourceFilterList Gets an array of all of a source's filters. @@ -4073,7 +4248,8 @@ Gets an array of all of a source's filters. | Name | Type | Description | Value Restrictions | ?Default Behavior | | ---- | :---: | ----------- | :----------------: | ----------------- | -| sourceName | String | Name of the source | None | N/A | +| ?sourceName | String | Name of the source | None | Unknown | +| ?sourceUuid | String | UUID of the source | None | Unknown | **Response Fields:** @@ -4117,7 +4293,8 @@ Creates a new filter, adding it to the specified source. | Name | Type | Description | Value Restrictions | ?Default Behavior | | ---- | :---: | ----------- | :----------------: | ----------------- | -| sourceName | String | Name of the source to add the filter to | None | N/A | +| ?sourceName | String | Name of the source to add the filter to | None | Unknown | +| ?sourceUuid | String | UUID of the source to add the filter to | None | Unknown | | filterName | String | Name of the new filter to be created | None | N/A | | filterKind | String | The kind of filter to be created | None | N/A | | ?filterSettings | Object | Settings object to initialize the filter with | None | Default settings used | @@ -4136,7 +4313,8 @@ Removes a filter from a source. | Name | Type | Description | Value Restrictions | ?Default Behavior | | ---- | :---: | ----------- | :----------------: | ----------------- | -| sourceName | String | Name of the source the filter is on | None | N/A | +| ?sourceName | String | Name of the source the filter is on | None | Unknown | +| ?sourceUuid | String | UUID of the source the filter is on | None | Unknown | | filterName | String | Name of the filter to remove | None | N/A | --- @@ -4153,7 +4331,8 @@ Sets the name of a source filter (rename). | Name | Type | Description | Value Restrictions | ?Default Behavior | | ---- | :---: | ----------- | :----------------: | ----------------- | -| sourceName | String | Name of the source the filter is on | None | N/A | +| ?sourceName | String | Name of the source the filter is on | None | Unknown | +| ?sourceUuid | String | UUID of the source the filter is on | None | Unknown | | filterName | String | Current name of the filter | None | N/A | | newFilterName | String | New name for the filter | None | N/A | @@ -4171,7 +4350,8 @@ Gets the info for a specific source filter. | Name | Type | Description | Value Restrictions | ?Default Behavior | | ---- | :---: | ----------- | :----------------: | ----------------- | -| sourceName | String | Name of the source | None | N/A | +| ?sourceName | String | Name of the source | None | Unknown | +| ?sourceUuid | String | UUID of the source | None | Unknown | | filterName | String | Name of the filter | None | N/A | **Response Fields:** @@ -4197,7 +4377,8 @@ Sets the index position of a filter on a source. | Name | Type | Description | Value Restrictions | ?Default Behavior | | ---- | :---: | ----------- | :----------------: | ----------------- | -| sourceName | String | Name of the source the filter is on | None | N/A | +| ?sourceName | String | Name of the source the filter is on | None | Unknown | +| ?sourceUuid | String | UUID of the source the filter is on | None | Unknown | | filterName | String | Name of the filter | None | N/A | | filterIndex | Number | New index position of the filter | >= 0 | N/A | @@ -4215,7 +4396,8 @@ Sets the settings of a source filter. | Name | Type | Description | Value Restrictions | ?Default Behavior | | ---- | :---: | ----------- | :----------------: | ----------------- | -| sourceName | String | Name of the source the filter is on | None | N/A | +| ?sourceName | String | Name of the source the filter is on | None | Unknown | +| ?sourceUuid | String | UUID of the source the filter is on | None | Unknown | | filterName | String | Name of the filter to set the settings of | None | N/A | | filterSettings | Object | Object of settings to apply | None | N/A | | ?overlay | Boolean | True == apply the settings on top of existing ones, False == reset the input to its defaults, then apply settings. | None | true | @@ -4234,7 +4416,8 @@ Sets the enable state of a source filter. | Name | Type | Description | Value Restrictions | ?Default Behavior | | ---- | :---: | ----------- | :----------------: | ----------------- | -| sourceName | String | Name of the source the filter is on | None | N/A | +| ?sourceName | String | Name of the source the filter is on | None | Unknown | +| ?sourceUuid | String | UUID of the source the filter is on | None | Unknown | | filterName | String | Name of the filter | None | N/A | | filterEnabled | Boolean | New enable state of the filter | None | N/A | @@ -4254,7 +4437,8 @@ Scenes only | Name | Type | Description | Value Restrictions | ?Default Behavior | | ---- | :---: | ----------- | :----------------: | ----------------- | -| sceneName | String | Name of the scene to get the items of | None | N/A | +| ?sceneName | String | Name of the scene to get the items of | None | Unknown | +| ?sceneUuid | String | UUID of the scene to get the items of | None | Unknown | **Response Fields:** @@ -4280,7 +4464,8 @@ Groups only | Name | Type | Description | Value Restrictions | ?Default Behavior | | ---- | :---: | ----------- | :----------------: | ----------------- | -| sceneName | String | Name of the group to get the items of | None | N/A | +| ?sceneName | String | Name of the group to get the items of | None | Unknown | +| ?sceneUuid | String | UUID of the group to get the items of | None | Unknown | **Response Fields:** @@ -4304,7 +4489,8 @@ Scenes and Groups | Name | Type | Description | Value Restrictions | ?Default Behavior | | ---- | :---: | ----------- | :----------------: | ----------------- | -| sceneName | String | Name of the scene or group to search in | None | N/A | +| ?sceneName | String | Name of the scene or group to search in | None | Unknown | +| ?sceneUuid | String | UUID of the scene or group to search in | None | Unknown | | sourceName | String | Name of the source to find | None | N/A | | ?searchOffset | Number | Number of matches to skip during search. >= 0 means first forward. -1 means last (top) item | >= -1 | 0 | @@ -4316,6 +4502,31 @@ Scenes and Groups --- +### GetSceneItemSource + +Gets the source associated with a scene item. + +- Complexity Rating: `3/5` +- Latest Supported RPC Version: `1` +- Added in v5.4.0 + +**Request Fields:** + +| Name | Type | Description | Value Restrictions | ?Default Behavior | +| ---- | :---: | ----------- | :----------------: | ----------------- | +| ?sceneName | String | Name of the scene the item is in | None | Unknown | +| ?sceneUuid | String | UUID of the scene the item is in | None | Unknown | +| sceneItemId | Number | Numeric ID of the scene item | >= 0 | N/A | + +**Response Fields:** + +| Name | Type | Description | +| ---- | :---: | ----------- | +| sourceName | String | Name of the source associated with the scene item | +| sourceUuid | String | UUID of the source associated with the scene item | + +--- + ### CreateSceneItem Creates a new scene item using a source. @@ -4330,8 +4541,10 @@ Scenes only | Name | Type | Description | Value Restrictions | ?Default Behavior | | ---- | :---: | ----------- | :----------------: | ----------------- | -| sceneName | String | Name of the scene to create the new item in | None | N/A | -| sourceName | String | Name of the source to add to the scene | None | N/A | +| ?sceneName | String | Name of the scene to create the new item in | None | Unknown | +| ?sceneUuid | String | UUID of the scene to create the new item in | None | Unknown | +| ?sourceName | String | Name of the source to add to the scene | None | Unknown | +| ?sourceUuid | String | UUID of the source to add to the scene | None | Unknown | | ?sceneItemEnabled | Boolean | Enable state to apply to the scene item on creation | None | True | **Response Fields:** @@ -4356,7 +4569,8 @@ Scenes only | Name | Type | Description | Value Restrictions | ?Default Behavior | | ---- | :---: | ----------- | :----------------: | ----------------- | -| sceneName | String | Name of the scene the item is in | None | N/A | +| ?sceneName | String | Name of the scene the item is in | None | Unknown | +| ?sceneUuid | String | UUID of the scene the item is in | None | Unknown | | sceneItemId | Number | Numeric ID of the scene item | >= 0 | N/A | --- @@ -4375,9 +4589,11 @@ Scenes only | Name | Type | Description | Value Restrictions | ?Default Behavior | | ---- | :---: | ----------- | :----------------: | ----------------- | -| sceneName | String | Name of the scene the item is in | None | N/A | +| ?sceneName | String | Name of the scene the item is in | None | Unknown | +| ?sceneUuid | String | UUID of the scene the item is in | None | Unknown | | sceneItemId | Number | Numeric ID of the scene item | >= 0 | N/A | -| ?destinationSceneName | String | Name of the scene to create the duplicated item in | None | `sceneName` is assumed | +| ?destinationSceneName | String | Name of the scene to create the duplicated item in | None | From scene is assumed | +| ?destinationSceneUuid | String | UUID of the scene to create the duplicated item in | None | From scene is assumed | **Response Fields:** @@ -4401,7 +4617,8 @@ Scenes and Groups | Name | Type | Description | Value Restrictions | ?Default Behavior | | ---- | :---: | ----------- | :----------------: | ----------------- | -| sceneName | String | Name of the scene the item is in | None | N/A | +| ?sceneName | String | Name of the scene the item is in | None | Unknown | +| ?sceneUuid | String | UUID of the scene the item is in | None | Unknown | | sceneItemId | Number | Numeric ID of the scene item | >= 0 | N/A | **Response Fields:** @@ -4424,7 +4641,8 @@ Sets the transform and crop info of a scene item. | Name | Type | Description | Value Restrictions | ?Default Behavior | | ---- | :---: | ----------- | :----------------: | ----------------- | -| sceneName | String | Name of the scene the item is in | None | N/A | +| ?sceneName | String | Name of the scene the item is in | None | Unknown | +| ?sceneUuid | String | UUID of the scene the item is in | None | Unknown | | sceneItemId | Number | Numeric ID of the scene item | >= 0 | N/A | | sceneItemTransform | Object | Object containing scene item transform info to update | None | N/A | @@ -4444,7 +4662,8 @@ Scenes and Groups | Name | Type | Description | Value Restrictions | ?Default Behavior | | ---- | :---: | ----------- | :----------------: | ----------------- | -| sceneName | String | Name of the scene the item is in | None | N/A | +| ?sceneName | String | Name of the scene the item is in | None | Unknown | +| ?sceneUuid | String | UUID of the scene the item is in | None | Unknown | | sceneItemId | Number | Numeric ID of the scene item | >= 0 | N/A | **Response Fields:** @@ -4469,7 +4688,8 @@ Scenes and Groups | Name | Type | Description | Value Restrictions | ?Default Behavior | | ---- | :---: | ----------- | :----------------: | ----------------- | -| sceneName | String | Name of the scene the item is in | None | N/A | +| ?sceneName | String | Name of the scene the item is in | None | Unknown | +| ?sceneUuid | String | UUID of the scene the item is in | None | Unknown | | sceneItemId | Number | Numeric ID of the scene item | >= 0 | N/A | | sceneItemEnabled | Boolean | New enable state of the scene item | None | N/A | @@ -4489,7 +4709,8 @@ Scenes and Groups | Name | Type | Description | Value Restrictions | ?Default Behavior | | ---- | :---: | ----------- | :----------------: | ----------------- | -| sceneName | String | Name of the scene the item is in | None | N/A | +| ?sceneName | String | Name of the scene the item is in | None | Unknown | +| ?sceneUuid | String | UUID of the scene the item is in | None | Unknown | | sceneItemId | Number | Numeric ID of the scene item | >= 0 | N/A | **Response Fields:** @@ -4514,7 +4735,8 @@ Scenes and Group | Name | Type | Description | Value Restrictions | ?Default Behavior | | ---- | :---: | ----------- | :----------------: | ----------------- | -| sceneName | String | Name of the scene the item is in | None | N/A | +| ?sceneName | String | Name of the scene the item is in | None | Unknown | +| ?sceneUuid | String | UUID of the scene the item is in | None | Unknown | | sceneItemId | Number | Numeric ID of the scene item | >= 0 | N/A | | sceneItemLocked | Boolean | New lock state of the scene item | None | N/A | @@ -4536,7 +4758,8 @@ Scenes and Groups | Name | Type | Description | Value Restrictions | ?Default Behavior | | ---- | :---: | ----------- | :----------------: | ----------------- | -| sceneName | String | Name of the scene the item is in | None | N/A | +| ?sceneName | String | Name of the scene the item is in | None | Unknown | +| ?sceneUuid | String | UUID of the scene the item is in | None | Unknown | | sceneItemId | Number | Numeric ID of the scene item | >= 0 | N/A | **Response Fields:** @@ -4561,7 +4784,8 @@ Scenes and Groups | Name | Type | Description | Value Restrictions | ?Default Behavior | | ---- | :---: | ----------- | :----------------: | ----------------- | -| sceneName | String | Name of the scene the item is in | None | N/A | +| ?sceneName | String | Name of the scene the item is in | None | Unknown | +| ?sceneUuid | String | UUID of the scene the item is in | None | Unknown | | sceneItemId | Number | Numeric ID of the scene item | >= 0 | N/A | | sceneItemIndex | Number | New index position of the scene item | >= 0 | N/A | @@ -4591,7 +4815,8 @@ Scenes and Groups | Name | Type | Description | Value Restrictions | ?Default Behavior | | ---- | :---: | ----------- | :----------------: | ----------------- | -| sceneName | String | Name of the scene the item is in | None | N/A | +| ?sceneName | String | Name of the scene the item is in | None | Unknown | +| ?sceneUuid | String | UUID of the scene the item is in | None | Unknown | | sceneItemId | Number | Numeric ID of the scene item | >= 0 | N/A | **Response Fields:** @@ -4616,7 +4841,8 @@ Scenes and Groups | Name | Type | Description | Value Restrictions | ?Default Behavior | | ---- | :---: | ----------- | :----------------: | ----------------- | -| sceneName | String | Name of the scene the item is in | None | N/A | +| ?sceneName | String | Name of the scene the item is in | None | Unknown | +| ?sceneUuid | String | UUID of the scene the item is in | None | Unknown | | sceneItemId | Number | Numeric ID of the scene item | >= 0 | N/A | | sceneItemBlendMode | String | New blend mode | None | N/A | @@ -4993,6 +5219,12 @@ Toggles the status of the record output. - Latest Supported RPC Version: `1` - Added in v5.0.0 +**Response Fields:** + +| Name | Type | Description | +| ---- | :---: | ----------- | +| outputActive | Boolean | The new active state of the output | + --- ### StartRecord @@ -5074,7 +5306,8 @@ Media States: | Name | Type | Description | Value Restrictions | ?Default Behavior | | ---- | :---: | ----------- | :----------------: | ----------------- | -| inputName | String | Name of the media input | None | N/A | +| ?inputName | String | Name of the media input | None | Unknown | +| ?inputUuid | String | UUID of the media input | None | Unknown | **Response Fields:** @@ -5100,7 +5333,8 @@ This request does not perform bounds checking of the cursor position. | Name | Type | Description | Value Restrictions | ?Default Behavior | | ---- | :---: | ----------- | :----------------: | ----------------- | -| inputName | String | Name of the media input | None | N/A | +| ?inputName | String | Name of the media input | None | Unknown | +| ?inputUuid | String | UUID of the media input | None | Unknown | | mediaCursor | Number | New cursor position to set | >= 0 | N/A | --- @@ -5119,7 +5353,8 @@ This request does not perform bounds checking of the cursor position. | Name | Type | Description | Value Restrictions | ?Default Behavior | | ---- | :---: | ----------- | :----------------: | ----------------- | -| inputName | String | Name of the media input | None | N/A | +| ?inputName | String | Name of the media input | None | Unknown | +| ?inputUuid | String | UUID of the media input | None | Unknown | | mediaCursorOffset | Number | Value to offset the current cursor position by | None | N/A | --- @@ -5136,7 +5371,8 @@ Triggers an action on a media input. | Name | Type | Description | Value Restrictions | ?Default Behavior | | ---- | :---: | ----------- | :----------------: | ----------------- | -| inputName | String | Name of the media input | None | N/A | +| ?inputName | String | Name of the media input | None | Unknown | +| ?inputUuid | String | UUID of the media input | None | Unknown | | mediaAction | String | Identifier of the `ObsMediaInputAction` enum | None | N/A | ## Ui Requests @@ -5185,7 +5421,8 @@ Opens the properties dialog of an input. | Name | Type | Description | Value Restrictions | ?Default Behavior | | ---- | :---: | ----------- | :----------------: | ----------------- | -| inputName | String | Name of the input to open the dialog of | None | N/A | +| ?inputName | String | Name of the input to open the dialog of | None | Unknown | +| ?inputUuid | String | UUID of the input to open the dialog of | None | Unknown | --- @@ -5201,7 +5438,8 @@ Opens the filters dialog of an input. | Name | Type | Description | Value Restrictions | ?Default Behavior | | ---- | :---: | ----------- | :----------------: | ----------------- | -| inputName | String | Name of the input to open the dialog of | None | N/A | +| ?inputName | String | Name of the input to open the dialog of | None | Unknown | +| ?inputUuid | String | UUID of the input to open the dialog of | None | Unknown | --- @@ -5217,7 +5455,8 @@ Opens the interact dialog of an input. | Name | Type | Description | Value Restrictions | ?Default Behavior | | ---- | :---: | ----------- | :----------------: | ----------------- | -| inputName | String | Name of the input to open the dialog of | None | N/A | +| ?inputName | String | Name of the input to open the dialog of | None | Unknown | +| ?inputUuid | String | UUID of the input to open the dialog of | None | Unknown | --- @@ -5277,6 +5516,7 @@ Note: This request serves to provide feature parity with 4.x. It is very likely | Name | Type | Description | Value Restrictions | ?Default Behavior | | ---- | :---: | ----------- | :----------------: | ----------------- | -| sourceName | String | Name of the source to open a projector for | None | N/A | +| ?sourceName | String | Name of the source to open a projector for | None | Unknown | +| ?sourceUuid | String | UUID of the source to open a projector for | None | Unknown | | ?monitorIndex | Number | Monitor index, use `GetMonitorList` to obtain index | None | -1: Opens projector in windowed mode | | ?projectorGeometry | String | Size/Position data for a windowed projector, in Qt Base64 encoded format. Mutually exclusive with `monitorIndex` | None | N/A | diff --git a/lib/obs-websocket-api.h b/lib/obs-websocket-api.h index 503eb53f7..adc950197 100644 --- a/lib/obs-websocket-api.h +++ b/lib/obs-websocket-api.h @@ -44,7 +44,7 @@ struct obs_websocket_request_callback { void *priv_data; }; -inline proc_handler_t *_ph; +static proc_handler_t *_ph; /* ==================== INTERNAL API FUNCTIONS ==================== */ @@ -53,7 +53,7 @@ static inline proc_handler_t *obs_websocket_get_ph(void) proc_handler_t *global_ph = obs_get_proc_handler(); assert(global_ph != NULL); - calldata_t cd = {0}; + calldata_t cd = {0, 0, 0, 0}; if (!proc_handler_call(global_ph, "obs_websocket_api_get_ph", &cd)) blog(LOG_DEBUG, "Unable to fetch obs-websocket proc handler object. obs-websocket not installed?"); proc_handler_t *ret = (proc_handler_t *)calldata_ptr(&cd, "ph"); @@ -91,7 +91,7 @@ static inline unsigned int obs_websocket_get_api_version(void) if (!obs_websocket_ensure_ph()) return 0; - calldata_t cd = {0}; + calldata_t cd = {0, 0, 0, 0}; if (!proc_handler_call(_ph, "get_api_version", &cd)) return 1; // API v1 does not include get_api_version @@ -104,7 +104,11 @@ static inline unsigned int obs_websocket_get_api_version(void) } // Calls an obs-websocket request. Free response with `obs_websocket_request_response_free()` -static inline obs_websocket_request_response *obs_websocket_call_request(const char *request_type, obs_data_t *request_data = NULL) +static inline struct obs_websocket_request_response *obs_websocket_call_request(const char *request_type, obs_data_t *request_data +#ifdef __cplusplus + = NULL +#endif +) { if (!obs_websocket_ensure_ph()) return NULL; @@ -113,14 +117,14 @@ static inline obs_websocket_request_response *obs_websocket_call_request(const c if (request_data) request_data_string = obs_data_get_json(request_data); - calldata_t cd = {0}; + calldata_t cd = {0, 0, 0, 0}; calldata_set_string(&cd, "request_type", request_type); calldata_set_string(&cd, "request_data", request_data_string); proc_handler_call(_ph, "call_request", &cd); - auto ret = (struct obs_websocket_request_response *)calldata_ptr(&cd, "response"); + struct obs_websocket_request_response *ret = (struct obs_websocket_request_response *)calldata_ptr(&cd, "response"); calldata_free(&cd); @@ -149,7 +153,7 @@ static inline obs_websocket_vendor obs_websocket_register_vendor(const char *ven if (!obs_websocket_ensure_ph()) return NULL; - calldata_t cd = {0}; + calldata_t cd = {0, 0, 0, 0}; calldata_set_string(&cd, "name", vendor_name); @@ -164,11 +168,9 @@ static inline obs_websocket_vendor obs_websocket_register_vendor(const char *ven static inline bool obs_websocket_vendor_register_request(obs_websocket_vendor vendor, const char *request_type, obs_websocket_request_callback_function request_callback, void *priv_data) { - calldata_t cd = {0}; + calldata_t cd = {0, 0, 0, 0}; - struct obs_websocket_request_callback cb = {}; - cb.callback = request_callback; - cb.priv_data = priv_data; + struct obs_websocket_request_callback cb = {request_callback, priv_data}; calldata_set_string(&cd, "type", request_type); calldata_set_ptr(&cd, "callback", &cb); @@ -182,7 +184,7 @@ static inline bool obs_websocket_vendor_register_request(obs_websocket_vendor ve // Unregisters an existing vendor request static inline bool obs_websocket_vendor_unregister_request(obs_websocket_vendor vendor, const char *request_type) { - calldata_t cd = {0}; + calldata_t cd = {0, 0, 0, 0}; calldata_set_string(&cd, "type", request_type); @@ -196,7 +198,7 @@ static inline bool obs_websocket_vendor_unregister_request(obs_websocket_vendor // Emits an event under the vendor's name static inline bool obs_websocket_vendor_emit_event(obs_websocket_vendor vendor, const char *event_name, obs_data_t *event_data) { - calldata_t cd = {0}; + calldata_t cd = {0, 0, 0, 0}; calldata_set_string(&cd, "type", event_name); calldata_set_ptr(&cd, "data", (void *)event_data); diff --git a/src/Config.cpp b/src/Config.cpp index fbc1f0dd3..296c30910 100644 --- a/src/Config.cpp +++ b/src/Config.cpp @@ -38,16 +38,6 @@ with this program. If not, see #define CMDLINE_WEBSOCKET_DEBUG "websocket_debug" Config::Config() - : PortOverridden(false), - PasswordOverridden(false), - FirstLoad(true), - ServerEnabled(false), - ServerPort(4455), - Ipv4Only(false), - DebugEnabled(false), - AlertsEnabled(false), - AuthRequired(true), - ServerPassword("") { SetDefaultsToGlobalStore(); } diff --git a/src/Config.h b/src/Config.h index 74a501f30..72761bc6f 100644 --- a/src/Config.h +++ b/src/Config.h @@ -30,17 +30,17 @@ struct Config { void Load(); void Save(); void SetDefaultsToGlobalStore(); - config_t *GetConfigStore(); - - std::atomic PortOverridden; - std::atomic PasswordOverridden; - - std::atomic FirstLoad; - std::atomic ServerEnabled; - std::atomic ServerPort; - std::atomic Ipv4Only; - std::atomic DebugEnabled; - std::atomic AlertsEnabled; - std::atomic AuthRequired; + static config_t *GetConfigStore(); + + std::atomic PortOverridden = false; + std::atomic PasswordOverridden = false; + + std::atomic FirstLoad = true; + std::atomic ServerEnabled = false; + std::atomic ServerPort = 4455; + std::atomic Ipv4Only = false; + std::atomic DebugEnabled = false; + std::atomic AlertsEnabled = false; + std::atomic AuthRequired = true; QString ServerPassword; }; diff --git a/src/WebSocketApi.cpp b/src/WebSocketApi.cpp index 554b50615..15c27150d 100644 --- a/src/WebSocketApi.cpp +++ b/src/WebSocketApi.cpp @@ -1,3 +1,21 @@ +/* +obs-websocket +Copyright (C) 2020-2023 Kyle Manning + +This program is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License along +with this program. If not, see +*/ + #include "WebSocketApi.h" #include "requesthandler/RequestHandler.h" #include "obs-websocket.h" diff --git a/src/WebSocketApi.h b/src/WebSocketApi.h index e175bb588..cb8b98169 100644 --- a/src/WebSocketApi.h +++ b/src/WebSocketApi.h @@ -1,3 +1,21 @@ +/* +obs-websocket +Copyright (C) 2020-2023 Kyle Manning + +This program is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License along +with this program. If not, see +*/ + #pragma once #include diff --git a/src/eventhandler/EventHandler.cpp b/src/eventhandler/EventHandler.cpp index ac8e4f5c8..aeb700730 100644 --- a/src/eventhandler/EventHandler.cpp +++ b/src/eventhandler/EventHandler.cpp @@ -20,11 +20,6 @@ with this program. If not, see #include "EventHandler.h" EventHandler::EventHandler() - : _obsLoaded(false), - _inputVolumeMetersRef(0), - _inputActiveStateChangedRef(0), - _inputShowStateChangedRef(0), - _sceneItemTransformChangedRef(0) { blog_debug("[EventHandler::EventHandler] Setting up..."); @@ -36,6 +31,7 @@ EventHandler::EventHandler() signal_handler_connect(coreSignalHandler, "source_destroy", SourceDestroyedMultiHandler, this); signal_handler_connect(coreSignalHandler, "source_remove", SourceRemovedMultiHandler, this); signal_handler_connect(coreSignalHandler, "source_rename", SourceRenamedMultiHandler, this); + signal_handler_connect(coreSignalHandler, "source_update", SourceUpdatedMultiHandler, this); } else { blog(LOG_ERROR, "[EventHandler::EventHandler] Unable to get libobs signal handler!"); } @@ -55,10 +51,25 @@ EventHandler::~EventHandler() signal_handler_disconnect(coreSignalHandler, "source_destroy", SourceDestroyedMultiHandler, this); signal_handler_disconnect(coreSignalHandler, "source_remove", SourceRemovedMultiHandler, this); signal_handler_disconnect(coreSignalHandler, "source_rename", SourceRenamedMultiHandler, this); + signal_handler_disconnect(coreSignalHandler, "source_update", SourceUpdatedMultiHandler, this); } else { blog(LOG_ERROR, "[EventHandler::~EventHandler] Unable to get libobs signal handler!"); } + // Revoke callbacks of all inputs and scenes, in case some still have our callbacks attached + auto enumInputs = [](void *param, obs_source_t *source) { + auto eventHandler = static_cast(param); + eventHandler->DisconnectSourceSignals(source); + return true; + }; + obs_enum_sources(enumInputs, this); + auto enumScenes = [](void *param, obs_source_t *source) { + auto eventHandler = static_cast(param); + eventHandler->DisconnectSourceSignals(source); + return true; + }; + obs_enum_scenes(enumScenes, this); + blog_debug("[EventHandler::~EventHandler] Finished."); } @@ -67,9 +78,9 @@ void EventHandler::SetBroadcastCallback(EventHandler::BroadcastCallback cb) _broadcastCallback = cb; } -void EventHandler::SetObsLoadedCallback(EventHandler::ObsLoadedCallback cb) +void EventHandler::SetObsReadyCallback(EventHandler::ObsReadyCallback cb) { - _obsLoadedCallback = cb; + _obsReadyCallback = cb; } // Function to increment refcounts for high volume event subscriptions @@ -261,15 +272,12 @@ void EventHandler::OnFrontendEvent(enum obs_frontend_event event, void *private_ { auto eventHandler = static_cast(private_data); - if (!eventHandler->_obsLoaded.load() && event != OBS_FRONTEND_EVENT_FINISHED_LOADING) - return; - switch (event) { // General case OBS_FRONTEND_EVENT_FINISHED_LOADING: eventHandler->FrontendFinishedLoadingMultiHandler(); break; - case OBS_FRONTEND_EVENT_EXIT: + case OBS_FRONTEND_EVENT_SCRIPTING_SHUTDOWN: eventHandler->FrontendExitMultiHandler(); break; @@ -283,7 +291,11 @@ void EventHandler::OnFrontendEvent(enum obs_frontend_event event, void *private_ } obs_frontend_source_list_free(&transitions); } + // Before ready update to allow event to broadcast eventHandler->HandleCurrentSceneCollectionChanging(); + eventHandler->_obsReady = false; + if (eventHandler->_obsReadyCallback) + eventHandler->_obsReadyCallback(false); break; case OBS_FRONTEND_EVENT_SCENE_COLLECTION_CHANGED: { obs_frontend_source_list transitions = {}; @@ -294,6 +306,9 @@ void EventHandler::OnFrontendEvent(enum obs_frontend_event event, void *private_ } obs_frontend_source_list_free(&transitions); } + eventHandler->_obsReady = true; + if (eventHandler->_obsReadyCallback) + eventHandler->_obsReadyCallback(true); eventHandler->HandleCurrentSceneCollectionChanged(); break; case OBS_FRONTEND_EVENT_SCENE_COLLECTION_LIST_CHANGED: @@ -430,30 +445,6 @@ void EventHandler::FrontendFinishedLoadingMultiHandler() blog_debug( "[EventHandler::FrontendFinishedLoadingMultiHandler] OBS has finished loading. Connecting final handlers and enabling events..."); - // Connect source signals and enable events only after OBS has fully loaded (to reduce extra logging). - _obsLoaded.store(true); - - // In the case that plugins become hotloadable, this will have to go back into `EventHandler::EventHandler()` - // Enumerate inputs and connect each one - { - auto enumInputs = [](void *param, obs_source_t *source) { - auto eventHandler = static_cast(param); - eventHandler->ConnectSourceSignals(source); - return true; - }; - obs_enum_sources(enumInputs, this); - } - - // Enumerate scenes and connect each one - { - auto enumScenes = [](void *param, obs_source_t *source) { - auto eventHandler = static_cast(param); - eventHandler->ConnectSourceSignals(source); - return true; - }; - obs_enum_scenes(enumScenes, this); - } - // Enumerate all scene transitions and connect each one { obs_frontend_source_list transitions = {}; @@ -465,41 +456,23 @@ void EventHandler::FrontendFinishedLoadingMultiHandler() obs_frontend_source_list_free(&transitions); } - blog_debug("[EventHandler::FrontendFinishedLoadingMultiHandler] Finished."); + _obsReady = true; + if (_obsReadyCallback) + _obsReadyCallback(true); - if (_obsLoadedCallback) - _obsLoadedCallback(); + blog_debug("[EventHandler::FrontendFinishedLoadingMultiHandler] Finished."); } void EventHandler::FrontendExitMultiHandler() { - HandleExitStarted(); - blog_debug("[EventHandler::FrontendExitMultiHandler] OBS is unloading. Disabling events..."); - // Disconnect source signals and disable events when OBS starts unloading (to reduce extra logging). - _obsLoaded.store(false); - - // In the case that plugins become hotloadable, this will have to go back into `EventHandler::~EventHandler()` - // Enumerate inputs and disconnect each one - { - auto enumInputs = [](void *param, obs_source_t *source) { - auto eventHandler = static_cast(param); - eventHandler->DisconnectSourceSignals(source); - return true; - }; - obs_enum_sources(enumInputs, this); - } + HandleExitStarted(); - // Enumerate scenes and disconnect each one - { - auto enumScenes = [](void *param, obs_source_t *source) { - auto eventHandler = static_cast(param); - eventHandler->DisconnectSourceSignals(source); - return true; - }; - obs_enum_scenes(enumScenes, this); - } + // Disconnect source signals and disable events when OBS starts unloading (to reduce extra logging). + _obsReady = false; + if (_obsReadyCallback) + _obsReadyCallback(false); // Enumerate all scene transitions and disconnect each one { @@ -520,10 +493,6 @@ void EventHandler::SourceCreatedMultiHandler(void *param, calldata_t *data) { auto eventHandler = static_cast(param); - // Don't react to signals until OBS has finished loading - if (!eventHandler->_obsLoaded.load()) - return; - obs_source_t *source = GetCalldataPointer(data, "source"); if (!source) return; @@ -556,10 +525,6 @@ void EventHandler::SourceDestroyedMultiHandler(void *param, calldata_t *data) // Disconnect all signals from the source eventHandler->DisconnectSourceSignals(source); - // Don't react to signals if OBS is unloading - if (!eventHandler->_obsLoaded.load()) - return; - switch (obs_source_get_type(source)) { case OBS_SOURCE_TYPE_INPUT: // Only emit removed if the input has not already been removed. This is the case when removing the last scene item of an input. @@ -582,9 +547,6 @@ void EventHandler::SourceRemovedMultiHandler(void *param, calldata_t *data) { auto eventHandler = static_cast(param); - if (!eventHandler->_obsLoaded.load()) - return; - obs_source_t *source = GetCalldataPointer(data, "source"); if (!source) return; @@ -605,9 +567,6 @@ void EventHandler::SourceRenamedMultiHandler(void *param, calldata_t *data) { auto eventHandler = static_cast(param); - if (!eventHandler->_obsLoaded.load()) - return; - obs_source_t *source = GetCalldataPointer(data, "source"); if (!source) return; @@ -631,6 +590,26 @@ void EventHandler::SourceRenamedMultiHandler(void *param, calldata_t *data) } } +void EventHandler::SourceUpdatedMultiHandler(void *param, calldata_t *data) +{ + auto eventHandler = static_cast(param); + + obs_source_t *source = GetCalldataPointer(data, "source"); + if (!source) + return; + + switch (obs_source_get_type(source)) { + case OBS_SOURCE_TYPE_INPUT: + eventHandler->HandleInputSettingsChanged(source); + break; + case OBS_SOURCE_TYPE_FILTER: + eventHandler->HandleSourceFilterSettingsChanged(source); + break; + default: + break; + } +} + void EventHandler::StreamOutputReconnectHandler(void *param, calldata_t *) { auto eventHandler = static_cast(param); diff --git a/src/eventhandler/EventHandler.h b/src/eventhandler/EventHandler.h index 4355a22a0..ed98787f0 100644 --- a/src/eventhandler/EventHandler.h +++ b/src/eventhandler/EventHandler.h @@ -27,32 +27,33 @@ with this program. If not, see #include "../obs-websocket.h" #include "../utils/Obs.h" #include "../utils/Obs_VolumeMeter.h" -#include "../plugin-macros.generated.h" +#include "plugin-macros.generated.h" class EventHandler { public: EventHandler(); ~EventHandler(); - typedef std::function BroadcastCallback; + typedef std::function + BroadcastCallback; // uint64_t requiredIntent, std::string eventType, json eventData, uint8_t rpcVersion void SetBroadcastCallback(BroadcastCallback cb); - typedef std::function ObsLoadedCallback; - void SetObsLoadedCallback(ObsLoadedCallback cb); + typedef std::function ObsReadyCallback; // bool ready + void SetObsReadyCallback(ObsReadyCallback cb); void ProcessSubscription(uint64_t eventSubscriptions); void ProcessUnsubscription(uint64_t eventSubscriptions); private: BroadcastCallback _broadcastCallback; - ObsLoadedCallback _obsLoadedCallback; + ObsReadyCallback _obsReadyCallback; - std::atomic _obsLoaded; + std::atomic _obsReady = false; std::unique_ptr _inputVolumeMetersHandler; - std::atomic _inputVolumeMetersRef; - std::atomic _inputActiveStateChangedRef; - std::atomic _inputShowStateChangedRef; - std::atomic _sceneItemTransformChangedRef; + std::atomic _inputVolumeMetersRef = 0; + std::atomic _inputActiveStateChangedRef = 0; + std::atomic _inputShowStateChangedRef = 0; + std::atomic _sceneItemTransformChangedRef = 0; void ConnectSourceSignals(obs_source_t *source); void DisconnectSourceSignals(obs_source_t *source); @@ -68,9 +69,10 @@ class EventHandler { static void SourceCreatedMultiHandler(void *param, calldata_t *data); static void SourceDestroyedMultiHandler(void *param, calldata_t *data); static void SourceRemovedMultiHandler(void *param, calldata_t *data); - - // Signal handler: source static void SourceRenamedMultiHandler(void *param, calldata_t *data); + static void SourceUpdatedMultiHandler(void *param, calldata_t *data); + + // Signal handler: media sources static void SourceMediaPauseMultiHandler(void *param, calldata_t *data); static void SourceMediaPlayMultiHandler(void *param, calldata_t *data); static void SourceMediaRestartMultiHandler(void *param, calldata_t *data); @@ -105,7 +107,7 @@ class EventHandler { void HandleInputCreated(obs_source_t *source); void HandleInputRemoved(obs_source_t *source); void HandleInputNameChanged(obs_source_t *source, std::string oldInputName, std::string inputName); - void HandleInputVolumeMeters(std::vector inputs); // AudioMeter::Handler callback + void HandleInputSettingsChanged(obs_source_t *source); static void HandleInputActiveStateChanged(void *param, calldata_t *data); // Direct callback static void HandleInputShowStateChanged(void *param, @@ -122,6 +124,7 @@ class EventHandler { calldata_t *data); // Direct callback static void HandleInputAudioMonitorTypeChanged(void *param, calldata_t *data); // Direct callback + void HandleInputVolumeMeters(std::vector inputs); // AudioMeter::Handler callback // Transitions void HandleCurrentSceneTransitionChanged(); @@ -144,6 +147,7 @@ class EventHandler { void HandleSourceFilterRemoved(obs_source_t *source, obs_source_t *filter); static void HandleSourceFilterNameChanged(void *param, calldata_t *data); // Direct callback + void HandleSourceFilterSettingsChanged(obs_source_t *source); static void HandleSourceFilterEnableStateChanged(void *param, calldata_t *data); // Direct callback // Outputs diff --git a/src/eventhandler/EventHandler_Filters.cpp b/src/eventhandler/EventHandler_Filters.cpp index 59c1783cc..103067881 100644 --- a/src/eventhandler/EventHandler_Filters.cpp +++ b/src/eventhandler/EventHandler_Filters.cpp @@ -163,6 +163,32 @@ void EventHandler::HandleSourceFilterNameChanged(void *param, calldata_t *data) eventHandler->BroadcastEvent(EventSubscription::Filters, "SourceFilterNameChanged", eventData); } +/** + * An source filter's settings have changed (been updated). + * + * @dataField sourceName | String | Name of the source the filter is on + * @dataField filterName | String | Name of the filter + * @dataField filterSettings | Object | New settings object of the filter + * + * @eventType SourceFilterSettingsChanged + * @eventSubscription Filters + * @complexity 3 + * @rpcVersion -1 + * @initialVersion 5.4.0 + * @api events + * @category filters + */ +void EventHandler::HandleSourceFilterSettingsChanged(obs_source_t *source) +{ + OBSDataAutoRelease filterSettings = obs_source_get_settings(source); + + json eventData; + eventData["sourceName"] = obs_source_get_name(obs_filter_get_parent(source)); + eventData["filterName"] = obs_source_get_name(source); + eventData["filterSettings"] = Utils::Json::ObsDataToJson(filterSettings); + BroadcastEvent(EventSubscription::Filters, "SourceFilterSettingsChanged", eventData); +} + /** * A source filter's enable state has changed. * diff --git a/src/eventhandler/EventHandler_Inputs.cpp b/src/eventhandler/EventHandler_Inputs.cpp index 07fc1858a..4275f9ff7 100644 --- a/src/eventhandler/EventHandler_Inputs.cpp +++ b/src/eventhandler/EventHandler_Inputs.cpp @@ -23,6 +23,7 @@ with this program. If not, see * An input has been created. * * @dataField inputName | String | Name of the input + * @dataField inputUuid | String | UUID of the input * @dataField inputKind | String | The kind of the input * @dataField unversionedInputKind | String | The unversioned kind of input (aka no `_v2` stuff) * @dataField inputSettings | Object | The settings configured to the input when it was created @@ -44,6 +45,7 @@ void EventHandler::HandleInputCreated(obs_source_t *source) json eventData; eventData["inputName"] = obs_source_get_name(source); + eventData["inputUuid"] = obs_source_get_uuid(source); eventData["inputKind"] = inputKind; eventData["unversionedInputKind"] = obs_source_get_unversioned_id(source); eventData["inputSettings"] = Utils::Json::ObsDataToJson(inputSettings); @@ -55,6 +57,7 @@ void EventHandler::HandleInputCreated(obs_source_t *source) * An input has been removed. * * @dataField inputName | String | Name of the input + * @dataField inputUuid | String | UUID of the input * * @eventType InputRemoved * @eventSubscription Inputs @@ -68,12 +71,14 @@ void EventHandler::HandleInputRemoved(obs_source_t *source) { json eventData; eventData["inputName"] = obs_source_get_name(source); + eventData["inputUuid"] = obs_source_get_uuid(source); BroadcastEvent(EventSubscription::Inputs, "InputRemoved", eventData); } /** * The name of an input has changed. * + * @dataField inputUuid | String | UUID of the input * @dataField oldInputName | String | Old name of the input * @dataField inputName | String | New name of the input * @@ -85,20 +90,50 @@ void EventHandler::HandleInputRemoved(obs_source_t *source) * @api events * @category inputs */ -void EventHandler::HandleInputNameChanged(obs_source_t *, std::string oldInputName, std::string inputName) +void EventHandler::HandleInputNameChanged(obs_source_t *source, std::string oldInputName, std::string inputName) { json eventData; + eventData["inputUuid"] = obs_source_get_uuid(source); eventData["oldInputName"] = oldInputName; eventData["inputName"] = inputName; BroadcastEvent(EventSubscription::Inputs, "InputNameChanged", eventData); } +/** + * An input's settings have changed (been updated). + * + * Note: On some inputs, changing values in the properties dialog will cause an immediate update. Pressing the "Cancel" button will revert the settings, resulting in another event being fired. + * + * @dataField inputName | String | Name of the input + * @dataField inputUuid | String | UUID of the input + * @dataField inputSettings | Object | New settings object of the input + * + * @eventType InputSettingsChanged + * @eventSubscription Inputs + * @complexity 3 + * @rpcVersion -1 + * @initialVersion 5.4.0 + * @api events + * @category inputs + */ +void EventHandler::HandleInputSettingsChanged(obs_source_t *source) +{ + OBSDataAutoRelease inputSettings = obs_source_get_settings(source); + + json eventData; + eventData["inputName"] = obs_source_get_name(source); + eventData["inputUuid"] = obs_source_get_uuid(source); + eventData["inputSettings"] = Utils::Json::ObsDataToJson(inputSettings); + BroadcastEvent(EventSubscription::Inputs, "InputSettingsChanged", eventData); +} + /** * An input's active state has changed. * * When an input is active, it means it's being shown by the program feed. * * @dataField inputName | String | Name of the input + * @dataField inputUuid | String | UUID of the input * @dataField videoActive | Boolean | Whether the input is active * * @eventType InputActiveStateChanged @@ -125,6 +160,7 @@ void EventHandler::HandleInputActiveStateChanged(void *param, calldata_t *data) json eventData; eventData["inputName"] = obs_source_get_name(source); + eventData["inputUuid"] = obs_source_get_uuid(source); eventData["videoActive"] = obs_source_active(source); eventHandler->BroadcastEvent(EventSubscription::InputActiveStateChanged, "InputActiveStateChanged", eventData); } @@ -135,6 +171,7 @@ void EventHandler::HandleInputActiveStateChanged(void *param, calldata_t *data) * When an input is showing, it means it's being shown by the preview or a dialog. * * @dataField inputName | String | Name of the input + * @dataField inputUuid | String | UUID of the input * @dataField videoShowing | Boolean | Whether the input is showing * * @eventType InputShowStateChanged @@ -161,6 +198,7 @@ void EventHandler::HandleInputShowStateChanged(void *param, calldata_t *data) json eventData; eventData["inputName"] = obs_source_get_name(source); + eventData["inputUuid"] = obs_source_get_uuid(source); eventData["videoShowing"] = obs_source_showing(source); eventHandler->BroadcastEvent(EventSubscription::InputShowStateChanged, "InputShowStateChanged", eventData); } @@ -169,6 +207,7 @@ void EventHandler::HandleInputShowStateChanged(void *param, calldata_t *data) * An input's mute state has changed. * * @dataField inputName | String | Name of the input + * @dataField inputUuid | String | UUID of the input * @dataField inputMuted | Boolean | Whether the input is muted * * @eventType InputMuteStateChanged @@ -192,6 +231,7 @@ void EventHandler::HandleInputMuteStateChanged(void *param, calldata_t *data) json eventData; eventData["inputName"] = obs_source_get_name(source); + eventData["inputUuid"] = obs_source_get_uuid(source); eventData["inputMuted"] = obs_source_muted(source); eventHandler->BroadcastEvent(EventSubscription::Inputs, "InputMuteStateChanged", eventData); } @@ -200,6 +240,7 @@ void EventHandler::HandleInputMuteStateChanged(void *param, calldata_t *data) * An input's volume level has changed. * * @dataField inputName | String | Name of the input + * @dataField inputUuid | String | UUID of the input * @dataField inputVolumeMul | Number | New volume level multiplier * @dataField inputVolumeDb | Number | New volume level in dB * @@ -231,6 +272,7 @@ void EventHandler::HandleInputVolumeChanged(void *param, calldata_t *data) json eventData; eventData["inputName"] = obs_source_get_name(source); + eventData["inputUuid"] = obs_source_get_uuid(source); eventData["inputVolumeMul"] = inputVolumeMul; eventData["inputVolumeDb"] = inputVolumeDb; eventHandler->BroadcastEvent(EventSubscription::Inputs, "InputVolumeChanged", eventData); @@ -239,7 +281,8 @@ void EventHandler::HandleInputVolumeChanged(void *param, calldata_t *data) /** * The audio balance value of an input has changed. * - * @dataField inputName | String | Name of the affected input + * @dataField inputName | String | Name of the input + * @dataField inputUuid | String | UUID of the input * @dataField inputAudioBalance | Number | New audio balance value of the input * * @eventType InputAudioBalanceChanged @@ -265,6 +308,7 @@ void EventHandler::HandleInputAudioBalanceChanged(void *param, calldata_t *data) json eventData; eventData["inputName"] = obs_source_get_name(source); + eventData["inputUuid"] = obs_source_get_uuid(source); eventData["inputAudioBalance"] = inputAudioBalance; eventHandler->BroadcastEvent(EventSubscription::Inputs, "InputAudioBalanceChanged", eventData); } @@ -273,6 +317,7 @@ void EventHandler::HandleInputAudioBalanceChanged(void *param, calldata_t *data) * The sync offset of an input has changed. * * @dataField inputName | String | Name of the input + * @dataField inputUuid | String | UUID of the input * @dataField inputAudioSyncOffset | Number | New sync offset in milliseconds * * @eventType InputAudioSyncOffsetChanged @@ -298,6 +343,7 @@ void EventHandler::HandleInputAudioSyncOffsetChanged(void *param, calldata_t *da json eventData; eventData["inputName"] = obs_source_get_name(source); + eventData["inputUuid"] = obs_source_get_uuid(source); eventData["inputAudioSyncOffset"] = inputAudioSyncOffset / 1000000; eventHandler->BroadcastEvent(EventSubscription::Inputs, "InputAudioSyncOffsetChanged", eventData); } @@ -306,6 +352,7 @@ void EventHandler::HandleInputAudioSyncOffsetChanged(void *param, calldata_t *da * The audio tracks of an input have changed. * * @dataField inputName | String | Name of the input + * @dataField inputUuid | String | UUID of the input * @dataField inputAudioTracks | Object | Object of audio tracks along with their associated enable states * * @eventType InputAudioTracksChanged @@ -336,6 +383,7 @@ void EventHandler::HandleInputAudioTracksChanged(void *param, calldata_t *data) json eventData; eventData["inputName"] = obs_source_get_name(source); + eventData["inputUuid"] = obs_source_get_uuid(source); eventData["inputAudioTracks"] = inputAudioTracks; eventHandler->BroadcastEvent(EventSubscription::Inputs, "InputAudioTracksChanged", eventData); } @@ -350,6 +398,7 @@ void EventHandler::HandleInputAudioTracksChanged(void *param, calldata_t *data) * - `OBS_MONITORING_TYPE_MONITOR_AND_OUTPUT` * * @dataField inputName | String | Name of the input + * @dataField inputUuid | String | UUID of the input * @dataField monitorType | String | New monitor type of the input * * @eventType InputAudioMonitorTypeChanged @@ -375,6 +424,7 @@ void EventHandler::HandleInputAudioMonitorTypeChanged(void *param, calldata_t *d json eventData; eventData["inputName"] = obs_source_get_name(source); + eventData["inputUuid"] = obs_source_get_uuid(source); eventData["monitorType"] = monitorType; eventHandler->BroadcastEvent(EventSubscription::Inputs, "InputAudioMonitorTypeChanged", eventData); } diff --git a/src/eventhandler/EventHandler_MediaInputs.cpp b/src/eventhandler/EventHandler_MediaInputs.cpp index 170644b0f..e77d470ab 100644 --- a/src/eventhandler/EventHandler_MediaInputs.cpp +++ b/src/eventhandler/EventHandler_MediaInputs.cpp @@ -124,6 +124,7 @@ void EventHandler::SourceMediaPreviousMultiHandler(void *param, calldata_t *data * A media input has started playing. * * @dataField inputName | String | Name of the input + * @dataField inputUuid | String | UUID of the input * * @eventType MediaInputPlaybackStarted * @eventSubscription MediaInputs @@ -146,6 +147,7 @@ void EventHandler::HandleMediaInputPlaybackStarted(void *param, calldata_t *data json eventData; eventData["inputName"] = obs_source_get_name(source); + eventData["inputUuid"] = obs_source_get_uuid(source); eventHandler->BroadcastEvent(EventSubscription::MediaInputs, "MediaInputPlaybackStarted", eventData); } @@ -153,6 +155,7 @@ void EventHandler::HandleMediaInputPlaybackStarted(void *param, calldata_t *data * A media input has finished playing. * * @dataField inputName | String | Name of the input + * @dataField inputUuid | String | UUID of the input * * @eventType MediaInputPlaybackEnded * @eventSubscription MediaInputs @@ -175,6 +178,7 @@ void EventHandler::HandleMediaInputPlaybackEnded(void *param, calldata_t *data) json eventData; eventData["inputName"] = obs_source_get_name(source); + eventData["inputUuid"] = obs_source_get_uuid(source); eventHandler->BroadcastEvent(EventSubscription::MediaInputs, "MediaInputPlaybackEnded", eventData); } @@ -182,6 +186,7 @@ void EventHandler::HandleMediaInputPlaybackEnded(void *param, calldata_t *data) * An action has been performed on an input. * * @dataField inputName | String | Name of the input + * @dataField inputUuid | String | UUID of the input * @dataField mediaAction | String | Action performed on the input. See `ObsMediaInputAction` enum * * @eventType MediaInputActionTriggered @@ -196,6 +201,7 @@ void EventHandler::HandleMediaInputActionTriggered(obs_source_t *source, ObsMedi { json eventData; eventData["inputName"] = obs_source_get_name(source); + eventData["inputUuid"] = obs_source_get_uuid(source); eventData["mediaAction"] = GetMediaInputActionString(action); BroadcastEvent(EventSubscription::MediaInputs, "MediaInputActionTriggered", eventData); -} \ No newline at end of file +} diff --git a/src/eventhandler/EventHandler_SceneItems.cpp b/src/eventhandler/EventHandler_SceneItems.cpp index 63c2b99ce..bad166321 100644 --- a/src/eventhandler/EventHandler_SceneItems.cpp +++ b/src/eventhandler/EventHandler_SceneItems.cpp @@ -23,7 +23,9 @@ with this program. If not, see * A scene item has been created. * * @dataField sceneName | String | Name of the scene the item was added to + * @dataField sceneUuid | String | UUID of the scene the item was added to * @dataField sourceName | String | Name of the underlying source (input/scene) + * @dataField sourceUuid | String | UUID of the underlying source (input/scene) * @dataField sceneItemId | Number | Numeric ID of the scene item * @dataField sceneItemIndex | Number | Index position of the item * @@ -49,7 +51,9 @@ void EventHandler::HandleSceneItemCreated(void *param, calldata_t *data) json eventData; eventData["sceneName"] = obs_source_get_name(obs_scene_get_source(scene)); + eventData["sceneUuid"] = obs_source_get_uuid(obs_scene_get_source(scene)); eventData["sourceName"] = obs_source_get_name(obs_sceneitem_get_source(sceneItem)); + eventData["sourceUuid"] = obs_source_get_uuid(obs_sceneitem_get_source(sceneItem)); eventData["sceneItemId"] = obs_sceneitem_get_id(sceneItem); eventData["sceneItemIndex"] = obs_sceneitem_get_order_position(sceneItem); eventHandler->BroadcastEvent(EventSubscription::SceneItems, "SceneItemCreated", eventData); @@ -61,7 +65,9 @@ void EventHandler::HandleSceneItemCreated(void *param, calldata_t *data) * This event is not emitted when the scene the item is in is removed. * * @dataField sceneName | String | Name of the scene the item was removed from + * @dataField sceneUuid | String | UUID of the scene the item was removed from * @dataField sourceName | String | Name of the underlying source (input/scene) + * @dataField sourceUuid | String | UUID of the underlying source (input/scene) * @dataField sceneItemId | Number | Numeric ID of the scene item * * @eventType SceneItemRemoved @@ -86,7 +92,9 @@ void EventHandler::HandleSceneItemRemoved(void *param, calldata_t *data) json eventData; eventData["sceneName"] = obs_source_get_name(obs_scene_get_source(scene)); + eventData["sceneUuid"] = obs_source_get_uuid(obs_scene_get_source(scene)); eventData["sourceName"] = obs_source_get_name(obs_sceneitem_get_source(sceneItem)); + eventData["sourceUuid"] = obs_source_get_uuid(obs_sceneitem_get_source(sceneItem)); eventData["sceneItemId"] = obs_sceneitem_get_id(sceneItem); eventHandler->BroadcastEvent(EventSubscription::SceneItems, "SceneItemRemoved", eventData); } @@ -95,6 +103,7 @@ void EventHandler::HandleSceneItemRemoved(void *param, calldata_t *data) * A scene's item list has been reindexed. * * @dataField sceneName | String | Name of the scene + * @dataField sceneUuid | String | UUID of the scene * @dataField sceneItems | Array | Array of scene item objects * * @eventType SceneItemListReindexed @@ -115,6 +124,7 @@ void EventHandler::HandleSceneItemListReindexed(void *param, calldata_t *data) json eventData; eventData["sceneName"] = obs_source_get_name(obs_scene_get_source(scene)); + eventData["sceneUuid"] = obs_source_get_uuid(obs_scene_get_source(scene)); eventData["sceneItems"] = Utils::Obs::ArrayHelper::GetSceneItemList(scene, true); eventHandler->BroadcastEvent(EventSubscription::SceneItems, "SceneItemListReindexed", eventData); } @@ -123,6 +133,7 @@ void EventHandler::HandleSceneItemListReindexed(void *param, calldata_t *data) * A scene item's enable state has changed. * * @dataField sceneName | String | Name of the scene the item is in + * @dataField sceneUuid | String | UUID of the scene the item is in * @dataField sceneItemId | Number | Numeric ID of the scene item * @dataField sceneItemEnabled | Boolean | Whether the scene item is enabled (visible) * @@ -150,6 +161,7 @@ void EventHandler::HandleSceneItemEnableStateChanged(void *param, calldata_t *da json eventData; eventData["sceneName"] = obs_source_get_name(obs_scene_get_source(scene)); + eventData["sceneUuid"] = obs_source_get_uuid(obs_scene_get_source(scene)); eventData["sceneItemId"] = obs_sceneitem_get_id(sceneItem); eventData["sceneItemEnabled"] = sceneItemEnabled; eventHandler->BroadcastEvent(EventSubscription::SceneItems, "SceneItemEnableStateChanged", eventData); @@ -159,6 +171,7 @@ void EventHandler::HandleSceneItemEnableStateChanged(void *param, calldata_t *da * A scene item's lock state has changed. * * @dataField sceneName | String | Name of the scene the item is in + * @dataField sceneUuid | String | UUID of the scene the item is in * @dataField sceneItemId | Number | Numeric ID of the scene item * @dataField sceneItemLocked | Boolean | Whether the scene item is locked * @@ -186,6 +199,7 @@ void EventHandler::HandleSceneItemLockStateChanged(void *param, calldata_t *data json eventData; eventData["sceneName"] = obs_source_get_name(obs_scene_get_source(scene)); + eventData["sceneUuid"] = obs_source_get_uuid(obs_scene_get_source(scene)); eventData["sceneItemId"] = obs_sceneitem_get_id(sceneItem); eventData["sceneItemLocked"] = sceneItemLocked; eventHandler->BroadcastEvent(EventSubscription::SceneItems, "SceneItemLockStateChanged", eventData); @@ -195,6 +209,7 @@ void EventHandler::HandleSceneItemLockStateChanged(void *param, calldata_t *data * A scene item has been selected in the Ui. * * @dataField sceneName | String | Name of the scene the item is in + * @dataField sceneUuid | String | UUID of the scene the item is in * @dataField sceneItemId | Number | Numeric ID of the scene item * * @eventType SceneItemSelected @@ -219,6 +234,7 @@ void EventHandler::HandleSceneItemSelected(void *param, calldata_t *data) json eventData; eventData["sceneName"] = obs_source_get_name(obs_scene_get_source(scene)); + eventData["sceneUuid"] = obs_source_get_uuid(obs_scene_get_source(scene)); eventData["sceneItemId"] = obs_sceneitem_get_id(sceneItem); eventHandler->BroadcastEvent(EventSubscription::SceneItems, "SceneItemSelected", eventData); } @@ -227,6 +243,7 @@ void EventHandler::HandleSceneItemSelected(void *param, calldata_t *data) * The transform/crop of a scene item has changed. * * @dataField sceneName | String | The name of the scene the item is in + * @dataField sceneUuid | String | The UUID of the scene the item is in * @dataField sceneItemId | Number | Numeric ID of the scene item * @dataField sceneItemTransform | Object | New transform/crop info of the scene item * @@ -255,6 +272,7 @@ void EventHandler::HandleSceneItemTransformChanged(void *param, calldata_t *data json eventData; eventData["sceneName"] = obs_source_get_name(obs_scene_get_source(scene)); + eventData["sceneUuid"] = obs_source_get_uuid(obs_scene_get_source(scene)); eventData["sceneItemId"] = obs_sceneitem_get_id(sceneItem); eventData["sceneItemTransform"] = Utils::Obs::ObjectHelper::GetSceneItemTransform(sceneItem); eventHandler->BroadcastEvent(EventSubscription::SceneItemTransformChanged, "SceneItemTransformChanged", eventData); diff --git a/src/eventhandler/EventHandler_Scenes.cpp b/src/eventhandler/EventHandler_Scenes.cpp index f7f818cfe..9dc221100 100644 --- a/src/eventhandler/EventHandler_Scenes.cpp +++ b/src/eventhandler/EventHandler_Scenes.cpp @@ -23,6 +23,7 @@ with this program. If not, see * A new scene has been created. * * @dataField sceneName | String | Name of the new scene + * @dataField sceneUuid | String | UUID of the new scene * @dataField isGroup | Boolean | Whether the new scene is a group * * @eventType SceneCreated @@ -37,6 +38,7 @@ void EventHandler::HandleSceneCreated(obs_source_t *source) { json eventData; eventData["sceneName"] = obs_source_get_name(source); + eventData["sceneUuid"] = obs_source_get_uuid(source); eventData["isGroup"] = obs_source_is_group(source); BroadcastEvent(EventSubscription::Scenes, "SceneCreated", eventData); } @@ -45,6 +47,7 @@ void EventHandler::HandleSceneCreated(obs_source_t *source) * A scene has been removed. * * @dataField sceneName | String | Name of the removed scene + * @dataField sceneUuid | String | UUID of the removed scene * @dataField isGroup | Boolean | Whether the scene was a group * * @eventType SceneRemoved @@ -59,6 +62,7 @@ void EventHandler::HandleSceneRemoved(obs_source_t *source) { json eventData; eventData["sceneName"] = obs_source_get_name(source); + eventData["sceneUuid"] = obs_source_get_uuid(source); eventData["isGroup"] = obs_source_is_group(source); BroadcastEvent(EventSubscription::Scenes, "SceneRemoved", eventData); } @@ -66,6 +70,7 @@ void EventHandler::HandleSceneRemoved(obs_source_t *source) /** * The name of a scene has changed. * + * @dataField sceneUuid | String | UUID of the scene * @dataField oldSceneName | String | Old name of the scene * @dataField sceneName | String | New name of the scene * @@ -77,9 +82,10 @@ void EventHandler::HandleSceneRemoved(obs_source_t *source) * @api events * @category scenes */ -void EventHandler::HandleSceneNameChanged(obs_source_t *, std::string oldSceneName, std::string sceneName) +void EventHandler::HandleSceneNameChanged(obs_source_t *source, std::string oldSceneName, std::string sceneName) { json eventData; + eventData["sceneUuid"] = obs_source_get_uuid(source); eventData["oldSceneName"] = oldSceneName; eventData["sceneName"] = sceneName; BroadcastEvent(EventSubscription::Scenes, "SceneNameChanged", eventData); @@ -89,6 +95,7 @@ void EventHandler::HandleSceneNameChanged(obs_source_t *, std::string oldSceneNa * The current program scene has changed. * * @dataField sceneName | String | Name of the scene that was switched to + * @dataField sceneUuid | String | UUID of the scene that was switched to * * @eventType CurrentProgramSceneChanged * @eventSubscription Scenes @@ -104,6 +111,7 @@ void EventHandler::HandleCurrentProgramSceneChanged() json eventData; eventData["sceneName"] = obs_source_get_name(currentScene); + eventData["sceneUuid"] = obs_source_get_uuid(currentScene); BroadcastEvent(EventSubscription::Scenes, "CurrentProgramSceneChanged", eventData); } @@ -111,6 +119,7 @@ void EventHandler::HandleCurrentProgramSceneChanged() * The current preview scene has changed. * * @dataField sceneName | String | Name of the scene that was switched to + * @dataField sceneUuid | String | UUID of the scene that was switched to * * @eventType CurrentPreviewSceneChanged * @eventSubscription Scenes @@ -130,6 +139,7 @@ void EventHandler::HandleCurrentPreviewSceneChanged() json eventData; eventData["sceneName"] = obs_source_get_name(currentPreviewScene); + eventData["sceneUuid"] = obs_source_get_uuid(currentPreviewScene); BroadcastEvent(EventSubscription::Scenes, "CurrentPreviewSceneChanged", eventData); } diff --git a/src/eventhandler/EventHandler_Transitions.cpp b/src/eventhandler/EventHandler_Transitions.cpp index 61865482a..eefb38873 100644 --- a/src/eventhandler/EventHandler_Transitions.cpp +++ b/src/eventhandler/EventHandler_Transitions.cpp @@ -23,6 +23,7 @@ with this program. If not, see * The current scene transition has changed. * * @dataField transitionName | String | Name of the new transition + * @dataField transitionUuid | String | UUID of the new transition * * @eventType CurrentSceneTransitionChanged * @eventSubscription Transitions @@ -38,6 +39,7 @@ void EventHandler::HandleCurrentSceneTransitionChanged() json eventData; eventData["transitionName"] = obs_source_get_name(transition); + eventData["transitionUuid"] = obs_source_get_uuid(transition); BroadcastEvent(EventSubscription::Transitions, "CurrentSceneTransitionChanged", eventData); } @@ -65,6 +67,7 @@ void EventHandler::HandleCurrentSceneTransitionDurationChanged() * A scene transition has started. * * @dataField transitionName | String | Scene transition name + * @dataField transitionUuid | String | Scene transition UUID * * @eventType SceneTransitionStarted * @eventSubscription Transitions @@ -84,6 +87,7 @@ void EventHandler::HandleSceneTransitionStarted(void *param, calldata_t *data) json eventData; eventData["transitionName"] = obs_source_get_name(source); + eventData["transitionUuid"] = obs_source_get_uuid(source); eventHandler->BroadcastEvent(EventSubscription::Transitions, "SceneTransitionStarted", eventData); } @@ -93,6 +97,7 @@ void EventHandler::HandleSceneTransitionStarted(void *param, calldata_t *data) * Note: Does not appear to trigger when the transition is interrupted by the user. * * @dataField transitionName | String | Scene transition name + * @dataField transitionUuid | String | Scene transition UUID * * @eventType SceneTransitionEnded * @eventSubscription Transitions @@ -112,6 +117,7 @@ void EventHandler::HandleSceneTransitionEnded(void *param, calldata_t *data) json eventData; eventData["transitionName"] = obs_source_get_name(source); + eventData["transitionUuid"] = obs_source_get_uuid(source); eventHandler->BroadcastEvent(EventSubscription::Transitions, "SceneTransitionEnded", eventData); } @@ -124,6 +130,7 @@ void EventHandler::HandleSceneTransitionEnded(void *param, calldata_t *data) * Note: Appears to be called by every transition, regardless of relevance. * * @dataField transitionName | String | Scene transition name + * @dataField transitionUuid | String | Scene transition UUID * * @eventType SceneTransitionVideoEnded * @eventSubscription Transitions @@ -143,5 +150,6 @@ void EventHandler::HandleSceneTransitionVideoEnded(void *param, calldata_t *data json eventData; eventData["transitionName"] = obs_source_get_name(source); + eventData["transitionUuid"] = obs_source_get_uuid(source); eventHandler->BroadcastEvent(EventSubscription::Transitions, "SceneTransitionVideoEnded", eventData); } diff --git a/src/forms/ConnectInfo.cpp b/src/forms/ConnectInfo.cpp index ddb979d2a..02442f004 100644 --- a/src/forms/ConnectInfo.cpp +++ b/src/forms/ConnectInfo.cpp @@ -21,9 +21,9 @@ with this program. If not, see #include #include #include +#include #include "ConnectInfo.h" -#include "../../deps/qr/cpp/QrCode.hpp" #include "../obs-websocket.h" #include "../Config.h" #include "../utils/Platform.h" diff --git a/src/forms/ConnectInfo.h b/src/forms/ConnectInfo.h index b1e13df38..701d7009e 100644 --- a/src/forms/ConnectInfo.h +++ b/src/forms/ConnectInfo.h @@ -21,7 +21,7 @@ with this program. If not, see #include -#include "../plugin-macros.generated.h" +#include "plugin-macros.generated.h" #include "ui_ConnectInfo.h" diff --git a/src/forms/SettingsDialog.h b/src/forms/SettingsDialog.h index 398a801a2..64f90c9ba 100644 --- a/src/forms/SettingsDialog.h +++ b/src/forms/SettingsDialog.h @@ -23,7 +23,7 @@ with this program. If not, see #include #include "ConnectInfo.h" -#include "../plugin-macros.generated.h" +#include "plugin-macros.generated.h" #include "ui_SettingsDialog.h" diff --git a/src/obs-websocket.cpp b/src/obs-websocket.cpp index 48d92a9e9..63ae269b0 100644 --- a/src/obs-websocket.cpp +++ b/src/obs-websocket.cpp @@ -89,7 +89,24 @@ bool obs_module_load(void) return true; } -void obs_module_unload() +#ifdef PLUGIN_TESTS +void test_register_vendor(); +#endif + +void obs_module_post_load(void) +{ +#ifdef PLUGIN_TESTS + test_register_vendor(); +#endif + + // Server will accept clients, but requests and events will not be served until FINISHED_LOADING occurs + if (_config->ServerEnabled) { + blog(LOG_INFO, "[obs_module_post_load] WebSocket server is enabled, starting..."); + _webSocketServer->Start(); + } +} + +void obs_module_unload(void) { blog(LOG_INFO, "[obs_module_unload] Shutting down..."); @@ -108,8 +125,7 @@ void obs_module_unload() // Destroy the event handler _eventHandler.reset(); - // Save and destroy the config manager - _config->Save(); + // Destroy the config manager _config.reset(); // Destroy the cpu stats @@ -193,18 +209,18 @@ static void test_vendor_request_cb(obs_data_t *requestData, obs_data_t *response obs_websocket_vendor_emit_event(priv_data, "TestEvent", requestData); } -void obs_module_post_load() +void test_register_vendor() { - blog(LOG_INFO, "[obs_module_post_load] Post load started."); + blog(LOG_INFO, "[test_register_vendor] Registering test vendor..."); // Test plugin API version fetch uint apiVersion = obs_websocket_get_api_version(); - blog(LOG_INFO, "[obs_module_post_load] obs-websocket plugin API version: %u", apiVersion); + blog(LOG_INFO, "[test_register_vendor] obs-websocket plugin API version: %u", apiVersion); // Test calling obs-websocket requests struct obs_websocket_request_response *response = obs_websocket_call_request("GetVersion"); if (response) { - blog(LOG_INFO, "[obs_module_post_load] Called GetVersion. Status Code: %u | Comment: %s | Response Data: %s", + blog(LOG_INFO, "[test_register_vendor] Called GetVersion. Status Code: %u | Comment: %s | Response Data: %s", response->status_code, response->comment, response->response_data); obs_websocket_request_response_free(response); } @@ -212,17 +228,17 @@ void obs_module_post_load() // Test vendor creation auto vendor = obs_websocket_register_vendor("obs-websocket-test"); if (!vendor) { - blog(LOG_WARNING, "[obs_module_post_load] Failed to create vendor!"); + blog(LOG_WARNING, "[test_register_vendor] Failed to create vendor!"); return; } // Test vendor request registration if (!obs_websocket_vendor_register_request(vendor, "TestRequest", test_vendor_request_cb, vendor)) { - blog(LOG_WARNING, "[obs_module_post_load] Failed to register vendor request!"); + blog(LOG_WARNING, "[test_register_vendor] Failed to register vendor request!"); return; } - blog(LOG_INFO, "[obs_module_post_load] Post load completed."); + blog(LOG_INFO, "[test_register_vendor] Post load completed."); } #endif diff --git a/src/requesthandler/RequestBatchHandler.cpp b/src/requesthandler/RequestBatchHandler.cpp index 8a622b785..21e28c4f7 100644 --- a/src/requesthandler/RequestBatchHandler.cpp +++ b/src/requesthandler/RequestBatchHandler.cpp @@ -31,17 +31,13 @@ struct SerialFrameBatch { json &variables; bool haltOnFailure; - size_t frameCount; - size_t sleepUntilFrame; + size_t frameCount = 0; + size_t sleepUntilFrame = 0; std::mutex conditionMutex; std::condition_variable condition; SerialFrameBatch(RequestHandler &requestHandler, json &variables, bool haltOnFailure) - : requestHandler(requestHandler), - variables(variables), - haltOnFailure(haltOnFailure), - frameCount(0), - sleepUntilFrame(0) + : requestHandler(requestHandler), variables(variables), haltOnFailure(haltOnFailure) { } }; diff --git a/src/requesthandler/RequestHandler.cpp b/src/requesthandler/RequestHandler.cpp index 785b00384..a5be2d780 100644 --- a/src/requesthandler/RequestHandler.cpp +++ b/src/requesthandler/RequestHandler.cpp @@ -51,6 +51,7 @@ const std::unordered_map RequestHandler::_han {"GetStreamServiceSettings", &RequestHandler::GetStreamServiceSettings}, {"SetStreamServiceSettings", &RequestHandler::SetStreamServiceSettings}, {"GetRecordDirectory", &RequestHandler::GetRecordDirectory}, + {"SetRecordDirectory", &RequestHandler::SetRecordDirectory}, // Sources {"GetSourceActive", &RequestHandler::GetSourceActive}, @@ -110,6 +111,7 @@ const std::unordered_map RequestHandler::_han {"SetTBarPosition", &RequestHandler::SetTBarPosition}, // Filters + {"GetSourceFilterKindList", &RequestHandler::GetSourceFilterKindList}, {"GetSourceFilterList", &RequestHandler::GetSourceFilterList}, {"GetSourceFilterDefaultSettings", &RequestHandler::GetSourceFilterDefaultSettings}, {"CreateSourceFilter", &RequestHandler::CreateSourceFilter}, @@ -124,6 +126,7 @@ const std::unordered_map RequestHandler::_han {"GetSceneItemList", &RequestHandler::GetSceneItemList}, {"GetGroupSceneItemList", &RequestHandler::GetGroupSceneItemList}, {"GetSceneItemId", &RequestHandler::GetSceneItemId}, + {"GetSceneItemSource", &RequestHandler::GetSceneItemSource}, {"CreateSceneItem", &RequestHandler::CreateSceneItem}, {"RemoveSceneItem", &RequestHandler::RemoveSceneItem}, {"DuplicateSceneItem", &RequestHandler::DuplicateSceneItem}, @@ -220,9 +223,8 @@ RequestResult RequestHandler::ProcessRequest(const Request &request) std::vector RequestHandler::GetRequestList() { std::vector ret; - for (auto const &[key, val] : _handlerMap) { + for (auto const &[key, val] : _handlerMap) ret.push_back(key); - } return ret; } diff --git a/src/requesthandler/RequestHandler.h b/src/requesthandler/RequestHandler.h index 4d9613843..610fb465f 100644 --- a/src/requesthandler/RequestHandler.h +++ b/src/requesthandler/RequestHandler.h @@ -30,7 +30,7 @@ with this program. If not, see #include "../websocketserver/rpc/WebSocketSession.h" #include "../obs-websocket.h" #include "../utils/Obs.h" -#include "../plugin-macros.generated.h" +#include "plugin-macros.generated.h" class RequestHandler; typedef RequestResult (RequestHandler::*RequestMethodHandler)(const Request &); @@ -70,6 +70,7 @@ class RequestHandler { RequestResult GetStreamServiceSettings(const Request &); RequestResult SetStreamServiceSettings(const Request &); RequestResult GetRecordDirectory(const Request &); + RequestResult SetRecordDirectory(const Request &); // Sources RequestResult GetSourceActive(const Request &); @@ -129,6 +130,7 @@ class RequestHandler { RequestResult SetTBarPosition(const Request &); // Filters + RequestResult GetSourceFilterKindList(const Request &); RequestResult GetSourceFilterList(const Request &); RequestResult GetSourceFilterDefaultSettings(const Request &); RequestResult CreateSourceFilter(const Request &); @@ -143,6 +145,7 @@ class RequestHandler { RequestResult GetSceneItemList(const Request &); RequestResult GetGroupSceneItemList(const Request &); RequestResult GetSceneItemId(const Request &); + RequestResult GetSceneItemSource(const Request &); RequestResult CreateSceneItem(const Request &); RequestResult RemoveSceneItem(const Request &); RequestResult DuplicateSceneItem(const Request &); diff --git a/src/requesthandler/RequestHandler_Config.cpp b/src/requesthandler/RequestHandler_Config.cpp index 78d4ac3ed..b9406d79b 100644 --- a/src/requesthandler/RequestHandler_Config.cpp +++ b/src/requesthandler/RequestHandler_Config.cpp @@ -198,10 +198,7 @@ RequestResult RequestHandler::CreateSceneCollection(const Request &request) if (std::find(sceneCollections.begin(), sceneCollections.end(), sceneCollectionName) != sceneCollections.end()) return RequestResult::Error(RequestStatus::ResourceAlreadyExists); - QMainWindow *mainWindow = static_cast(obs_frontend_get_main_window()); - bool success = false; - QMetaObject::invokeMethod(mainWindow, "AddSceneCollection", Qt::BlockingQueuedConnection, Q_RETURN_ARG(bool, success), - Q_ARG(bool, true), Q_ARG(QString, QString::fromStdString(sceneCollectionName))); + bool success = obs_frontend_add_scene_collection(sceneCollectionName.c_str()); if (!success) return RequestResult::Error(RequestStatus::ResourceCreationFailed, "Failed to create the scene collection."); @@ -599,9 +596,9 @@ 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, nullptr); + OBSServiceAutoRelease 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( @@ -622,7 +619,7 @@ RequestResult RequestHandler::SetStreamServiceSettings(const Request &request) * @responseField recordDirectory | String | Output directory * * @requestType GetRecordDirectory - * @complexity 1 + * @complexity 2 * @rpcVersion -1 * @initialVersion 5.0.0 * @api requests @@ -635,3 +632,35 @@ RequestResult RequestHandler::GetRecordDirectory(const Request &) return RequestResult::Success(responseData); } + +/** + * Sets the current directory that the record output writes files to. + * + * @requestField recordDirectory | String | Output directory + * + * @requestType SetRecordDirectory + * @complexity 2 + * @rpcVersion -1 + * @initialVersion 5.3.0 + * @api requests + * @category config + */ +RequestResult RequestHandler::SetRecordDirectory(const Request &request) +{ + if (obs_frontend_recording_active()) + return RequestResult::Error(RequestStatus::OutputRunning); + + RequestStatus::RequestStatus statusCode; + std::string comment; + if (!request.ValidateString("recordDirectory", statusCode, comment)) + return RequestResult::Error(statusCode, comment); + + std::string recordDirectory = request.RequestData["recordDirectory"]; + + config_t *config = obs_frontend_get_profile_config(); + config_set_string(config, "AdvOut", "RecFilePath", recordDirectory.c_str()); + config_set_string(config, "SimpleOutput", "FilePath", recordDirectory.c_str()); + config_save(config); + + return RequestResult::Success(); +} diff --git a/src/requesthandler/RequestHandler_Filters.cpp b/src/requesthandler/RequestHandler_Filters.cpp index fb07feb5d..bbdaac5af 100644 --- a/src/requesthandler/RequestHandler_Filters.cpp +++ b/src/requesthandler/RequestHandler_Filters.cpp @@ -19,10 +19,32 @@ with this program. If not, see #include "RequestHandler.h" +/** + * Gets an array of all available source filter kinds. + * + * Similar to `GetInputKindList` + * + * @responseField sourceFilterKinds | Array | Array of source filter kinds + * + * @requestType GetSourceFilterKindList + * @complexity 2 + * @rpcVersion -1 + * @initialVersion 5.4.0 + * @api requests + * @category filters + */ +RequestResult RequestHandler::GetSourceFilterKindList(const Request &) +{ + json responseData; + responseData["sourceFilterKinds"] = Utils::Obs::ArrayHelper::GetFilterKindList(); + return RequestResult::Success(responseData); +} + /** * Gets an array of all of a source's filters. * - * @requestField sourceName | String | Name of the source + * @requestField ?sourceName | String | Name of the source + * @requestField ?sourceUuid | String | UUID of the source * * @responseField filters | Array | Array of filters * @@ -37,7 +59,7 @@ RequestResult RequestHandler::GetSourceFilterList(const Request &request) { RequestStatus::RequestStatus statusCode; std::string comment; - OBSSourceAutoRelease source = request.ValidateSource("sourceName", statusCode, comment); + OBSSourceAutoRelease source = request.ValidateSource("sourceName", "sourceUuid", statusCode, comment); if (!source) return RequestResult::Error(statusCode, comment); @@ -85,7 +107,8 @@ RequestResult RequestHandler::GetSourceFilterDefaultSettings(const Request &requ /** * Creates a new filter, adding it to the specified source. * - * @requestField sourceName | String | Name of the source to add the filter to + * @requestField ?sourceName | String | Name of the source to add the filter to + * @requestField ?sourceUuid | String | UUID of the source to add the filter to * @requestField filterName | String | Name of the new filter to be created * @requestField filterKind | String | The kind of filter to be created * @requestField ?filterSettings | Object | Settings object to initialize the filter with | Default settings used @@ -102,7 +125,7 @@ RequestResult RequestHandler::CreateSourceFilter(const Request &request) RequestStatus::RequestStatus statusCode; std::string comment; - OBSSourceAutoRelease source = request.ValidateSource("sourceName", statusCode, comment); + OBSSourceAutoRelease source = request.ValidateSource("sourceName", "sourceUuid", statusCode, comment); if (!(source && request.ValidateString("filterName", statusCode, comment) && request.ValidateString("filterKind", statusCode, comment))) return RequestResult::Error(statusCode, comment); @@ -138,8 +161,9 @@ RequestResult RequestHandler::CreateSourceFilter(const Request &request) /** * Removes a filter from a source. * - * @requestField sourceName | String | Name of the source the filter is on - * @requestField filterName | String | Name of the filter to remove + * @requestField ?sourceName | String | Name of the source the filter is on + * @requestField ?sourceUuid | String | UUID of the source the filter is on + * @requestField filterName | String | Name of the filter to remove * * @requestType RemoveSourceFilter * @complexity 2 @@ -152,7 +176,7 @@ RequestResult RequestHandler::RemoveSourceFilter(const Request &request) { RequestStatus::RequestStatus statusCode; std::string comment; - FilterPair pair = request.ValidateFilter("sourceName", "filterName", statusCode, comment); + FilterPair pair = request.ValidateFilter(statusCode, comment); if (!pair.filter) return RequestResult::Error(statusCode, comment); @@ -164,7 +188,8 @@ RequestResult RequestHandler::RemoveSourceFilter(const Request &request) /** * Sets the name of a source filter (rename). * - * @requestField sourceName | String | Name of the source the filter is on + * @requestField ?sourceName | String | Name of the source the filter is on + * @requestField ?sourceUuid | String | UUID of the source the filter is on * @requestField filterName | String | Current name of the filter * @requestField newFilterName | String | New name for the filter * @@ -179,7 +204,7 @@ RequestResult RequestHandler::SetSourceFilterName(const Request &request) { RequestStatus::RequestStatus statusCode; std::string comment; - FilterPair pair = request.ValidateFilter("sourceName", "filterName", statusCode, comment); + FilterPair pair = request.ValidateFilter(statusCode, comment); if (!pair.filter || !request.ValidateString("newFilterName", statusCode, comment)) return RequestResult::Error(statusCode, comment); @@ -197,8 +222,9 @@ RequestResult RequestHandler::SetSourceFilterName(const Request &request) /** * Gets the info for a specific source filter. * - * @requestField sourceName | String | Name of the source - * @requestField filterName | String | Name of the filter + * @requestField ?sourceName | String | Name of the source + * @requestField ?sourceUuid | String | UUID of the source + * @requestField filterName | String | Name of the filter * * @responseField filterEnabled | Boolean | Whether the filter is enabled * @responseField filterIndex | Number | Index of the filter in the list, beginning at 0 @@ -216,7 +242,7 @@ RequestResult RequestHandler::GetSourceFilter(const Request &request) { RequestStatus::RequestStatus statusCode; std::string comment; - FilterPair pair = request.ValidateFilter("sourceName", "filterName", statusCode, comment); + FilterPair pair = request.ValidateFilter(statusCode, comment); if (!pair.filter) return RequestResult::Error(statusCode, comment); @@ -236,7 +262,8 @@ RequestResult RequestHandler::GetSourceFilter(const Request &request) /** * Sets the index position of a filter on a source. * - * @requestField sourceName | String | Name of the source the filter is on + * @requestField ?sourceName | String | Name of the source the filter is on + * @requestField ?sourceUuid | String | UUID of the source the filter is on * @requestField filterName | String | Name of the filter * @requestField filterIndex | Number | New index position of the filter | >= 0 * @@ -251,7 +278,7 @@ RequestResult RequestHandler::SetSourceFilterIndex(const Request &request) { RequestStatus::RequestStatus statusCode; std::string comment; - FilterPair pair = request.ValidateFilter("sourceName", "filterName", statusCode, comment); + FilterPair pair = request.ValidateFilter(statusCode, comment); if (!(pair.filter && request.ValidateNumber("filterIndex", statusCode, comment, 0, 8192))) return RequestResult::Error(statusCode, comment); @@ -265,7 +292,8 @@ RequestResult RequestHandler::SetSourceFilterIndex(const Request &request) /** * Sets the settings of a source filter. * - * @requestField sourceName | String | Name of the source the filter is on + * @requestField ?sourceName | String | Name of the source the filter is on + * @requestField ?sourceUuid | String | UUID of the source the filter is on * @requestField filterName | String | Name of the filter to set the settings of * @requestField filterSettings | Object | Object of settings to apply * @requestField ?overlay | Boolean | True == apply the settings on top of existing ones, False == reset the input to its defaults, then apply settings. | true @@ -281,7 +309,7 @@ RequestResult RequestHandler::SetSourceFilterSettings(const Request &request) { RequestStatus::RequestStatus statusCode; std::string comment; - FilterPair pair = request.ValidateFilter("sourceName", "filterName", statusCode, comment); + FilterPair pair = request.ValidateFilter(statusCode, comment); if (!(pair.filter && request.ValidateObject("filterSettings", statusCode, comment, true))) return RequestResult::Error(statusCode, comment); @@ -313,7 +341,8 @@ RequestResult RequestHandler::SetSourceFilterSettings(const Request &request) /** * Sets the enable state of a source filter. * - * @requestField sourceName | String | Name of the source the filter is on + * @requestField ?sourceName | String | Name of the source the filter is on + * @requestField ?sourceUuid | String | UUID of the source the filter is on * @requestField filterName | String | Name of the filter * @requestField filterEnabled | Boolean | New enable state of the filter * @@ -328,7 +357,7 @@ RequestResult RequestHandler::SetSourceFilterEnabled(const Request &request) { RequestStatus::RequestStatus statusCode; std::string comment; - FilterPair pair = request.ValidateFilter("sourceName", "filterName", statusCode, comment); + FilterPair pair = request.ValidateFilter(statusCode, comment); if (!(pair.filter && request.ValidateBoolean("filterEnabled", statusCode, comment))) return RequestResult::Error(statusCode, comment); diff --git a/src/requesthandler/RequestHandler_General.cpp b/src/requesthandler/RequestHandler_General.cpp index 436ca7afc..a43d2af7e 100644 --- a/src/requesthandler/RequestHandler_General.cpp +++ b/src/requesthandler/RequestHandler_General.cpp @@ -178,7 +178,7 @@ RequestResult RequestHandler::CallVendorRequest(const Request &request) OBSDataAutoRelease requestData = obs_data_create(); if (request.Contains("requestData")) { - if (!request.ValidateOptionalObject("requestData", statusCode, comment)) + if (!request.ValidateOptionalObject("requestData", statusCode, comment, true)) return RequestResult::Error(statusCode, comment); requestData = Utils::Json::JsonToObsData(request.RequestData["requestData"]); @@ -211,12 +211,14 @@ RequestResult RequestHandler::CallVendorRequest(const Request &request) } /** - * Gets an array of all hotkey names in OBS + * Gets an array of all hotkey names in OBS. + * + * Note: Hotkey functionality in obs-websocket comes as-is, and we do not guarantee support if things are broken. In 9/10 usages of hotkey requests, there exists a better, more reliable method via other requests. * * @responseField hotkeys | Array | Array of hotkey names * * @requestType GetHotkeyList - * @complexity 3 + * @complexity 4 * @rpcVersion -1 * @initialVersion 5.0.0 * @category general @@ -230,12 +232,15 @@ RequestResult RequestHandler::GetHotkeyList(const Request &) } /** - * Triggers a hotkey using its name. See `GetHotkeyList` + * Triggers a hotkey using its name. See `GetHotkeyList`. + * + * Note: Hotkey functionality in obs-websocket comes as-is, and we do not guarantee support if things are broken. In 9/10 usages of hotkey requests, there exists a better, more reliable method via other requests. * * @requestField hotkeyName | String | Name of the hotkey to trigger + * @requestField ?contextName | String | Name of context of the hotkey to trigger * * @requestType TriggerHotkeyByName - * @complexity 3 + * @complexity 4 * @rpcVersion -1 * @initialVersion 5.0.0 * @category general @@ -248,7 +253,15 @@ RequestResult RequestHandler::TriggerHotkeyByName(const Request &request) if (!request.ValidateString("hotkeyName", statusCode, comment)) return RequestResult::Error(statusCode, comment); - obs_hotkey_t *hotkey = Utils::Obs::SearchHelper::GetHotkeyByName(request.RequestData["hotkeyName"]); + std::string contextName; + if (request.Contains("contextName")) { + if (!request.ValidateOptionalString("contextName", statusCode, comment)) + return RequestResult::Error(statusCode, comment); + + contextName = request.RequestData["contextName"]; + } + + obs_hotkey_t *hotkey = Utils::Obs::SearchHelper::GetHotkeyByName(request.RequestData["hotkeyName"], contextName); if (!hotkey) return RequestResult::Error(RequestStatus::ResourceNotFound, "No hotkeys were found by that name."); @@ -260,6 +273,8 @@ RequestResult RequestHandler::TriggerHotkeyByName(const Request &request) /** * Triggers a hotkey using a sequence of keys. * + * Note: Hotkey functionality in obs-websocket comes as-is, and we do not guarantee support if things are broken. In 9/10 usages of hotkey requests, there exists a better, more reliable method via other requests. + * * @requestField ?keyId | String | The OBS key ID to use. See https://github.com/obsproject/obs-studio/blob/master/libobs/obs-hotkeys.h | Not pressed * @requestField ?keyModifiers | Object | Object containing key modifiers to apply | Ignored * @requestField ?keyModifiers.shift | Boolean | Press Shift | Not pressed diff --git a/src/requesthandler/RequestHandler_Inputs.cpp b/src/requesthandler/RequestHandler_Inputs.cpp index e7d5a2f07..42bea54b1 100644 --- a/src/requesthandler/RequestHandler_Inputs.cpp +++ b/src/requesthandler/RequestHandler_Inputs.cpp @@ -123,12 +123,14 @@ RequestResult RequestHandler::GetSpecialInputs(const Request &) /** * Creates a new input, adding it as a scene item to the specified scene. * - * @requestField sceneName | String | Name of the scene to add the input to as a scene item + * @requestField ?sceneName | String | Name of the scene to add the input to as a scene item + * @requestField ?sceneUuid | String | UUID of the scene to add the input to as a scene item * @requestField inputName | String | Name of the new input to created * @requestField inputKind | String | The kind of input to be created * @requestField ?inputSettings | Object | Settings object to initialize the input with | Default settings used * @requestField ?sceneItemEnabled | Boolean | Whether to set the created scene item to enabled or disabled | True * + * @responseField inputUuid | String | UUID of the newly created input * @responseField sceneItemId | Number | ID of the newly created scene item * * @requestType CreateInput @@ -142,7 +144,7 @@ RequestResult RequestHandler::CreateInput(const Request &request) { RequestStatus::RequestStatus statusCode; std::string comment; - OBSSourceAutoRelease sceneSource = request.ValidateScene("sceneName", statusCode, comment); + OBSSourceAutoRelease sceneSource = request.ValidateScene(statusCode, comment); if (!(sceneSource && request.ValidateString("inputName", statusCode, comment) && request.ValidateString("inputKind", statusCode, comment))) return RequestResult::Error(statusCode, comment); @@ -185,6 +187,7 @@ RequestResult RequestHandler::CreateInput(const Request &request) return RequestResult::Error(RequestStatus::ResourceCreationFailed, "Creation of the input or scene item failed."); json responseData; + responseData["inputUuid"] = obs_source_get_uuid(obs_sceneitem_get_source(sceneItem)); responseData["sceneItemId"] = obs_sceneitem_get_id(sceneItem); return RequestResult::Success(responseData); } @@ -194,7 +197,8 @@ RequestResult RequestHandler::CreateInput(const Request &request) * * Note: Will immediately remove all associated scene items. * - * @requestField inputName | String | Name of the input to remove + * @requestField ?inputName | String | Name of the input to remove + * @requestField ?inputUuid | String | UUID of the input to remove * * @requestType RemoveInput * @complexity 2 @@ -207,7 +211,7 @@ RequestResult RequestHandler::RemoveInput(const Request &request) { RequestStatus::RequestStatus statusCode; std::string comment; - OBSSourceAutoRelease input = request.ValidateInput("inputName", statusCode, comment); + OBSSourceAutoRelease input = request.ValidateInput(statusCode, comment); if (!input) return RequestResult::Error(statusCode, comment); @@ -222,7 +226,8 @@ RequestResult RequestHandler::RemoveInput(const Request &request) /** * Sets the name of an input (rename). * - * @requestField inputName | String | Current input name + * @requestField ?inputName | String | Current input name + * @requestField ?inputUuid | String | Current input UUID * @requestField newInputName | String | New name for the input * * @requestType SetInputName @@ -236,7 +241,7 @@ RequestResult RequestHandler::SetInputName(const Request &request) { RequestStatus::RequestStatus statusCode; std::string comment; - OBSSourceAutoRelease input = request.ValidateInput("inputName", statusCode, comment); + OBSSourceAutoRelease input = request.ValidateInput(statusCode, comment); if (!(input && request.ValidateString("newInputName", statusCode, comment))) return RequestResult::Error(statusCode, comment); @@ -292,7 +297,8 @@ RequestResult RequestHandler::GetInputDefaultSettings(const Request &request) * * Note: Does not include defaults. To create the entire settings object, overlay `inputSettings` over the `defaultInputSettings` provided by `GetInputDefaultSettings`. * - * @requestField inputName | String | Name of the input to get the settings of + * @requestField ?inputName | String | Name of the input to get the settings of + * @requestField ?inputUuid | String | UUID of the input to get the settings of * * @responseField inputSettings | Object | Object of settings for the input * @responseField inputKind | String | The kind of the input @@ -308,7 +314,7 @@ RequestResult RequestHandler::GetInputSettings(const Request &request) { RequestStatus::RequestStatus statusCode; std::string comment; - OBSSourceAutoRelease input = request.ValidateInput("inputName", statusCode, comment); + OBSSourceAutoRelease input = request.ValidateInput(statusCode, comment); if (!input) return RequestResult::Error(statusCode, comment); @@ -323,7 +329,8 @@ RequestResult RequestHandler::GetInputSettings(const Request &request) /** * Sets the settings of an input. * - * @requestField inputName | String | Name of the input to set the settings of + * @requestField ?inputName | String | Name of the input to set the settings of + * @requestField ?inputUuid | String | UUID of the input to set the settings of * @requestField inputSettings | Object | Object of settings to apply * @requestField ?overlay | Boolean | True == apply the settings on top of existing ones, False == reset the input to its defaults, then apply settings. | true * @@ -338,7 +345,7 @@ RequestResult RequestHandler::SetInputSettings(const Request &request) { RequestStatus::RequestStatus statusCode; std::string comment; - OBSSourceAutoRelease input = request.ValidateInput("inputName", statusCode, comment); + OBSSourceAutoRelease input = request.ValidateInput(statusCode, comment); if (!(input && request.ValidateObject("inputSettings", statusCode, comment, true))) return RequestResult::Error(statusCode, comment); @@ -373,7 +380,8 @@ RequestResult RequestHandler::SetInputSettings(const Request &request) /** * Gets the audio mute state of an input. * - * @requestField inputName | String | Name of input to get the mute state of + * @requestField ?inputName | String | Name of input to get the mute state of + * @requestField ?inputUuid | String | UUID of input to get the mute state of * * @responseField inputMuted | Boolean | Whether the input is muted * @@ -388,7 +396,7 @@ RequestResult RequestHandler::GetInputMute(const Request &request) { RequestStatus::RequestStatus statusCode; std::string comment; - OBSSourceAutoRelease input = request.ValidateInput("inputName", statusCode, comment); + OBSSourceAutoRelease input = request.ValidateInput(statusCode, comment); if (!input) return RequestResult::Error(statusCode, comment); @@ -403,7 +411,8 @@ RequestResult RequestHandler::GetInputMute(const Request &request) /** * Sets the audio mute state of an input. * - * @requestField inputName | String | Name of the input to set the mute state of + * @requestField ?inputName | String | Name of the input to set the mute state of + * @requestField ?inputUuid | String | UUID of the input to set the mute state of * @requestField inputMuted | Boolean | Whether to mute the input or not * * @requestType SetInputMute @@ -417,7 +426,7 @@ RequestResult RequestHandler::SetInputMute(const Request &request) { RequestStatus::RequestStatus statusCode; std::string comment; - OBSSourceAutoRelease input = request.ValidateInput("inputName", statusCode, comment); + OBSSourceAutoRelease input = request.ValidateInput(statusCode, comment); if (!(input && request.ValidateBoolean("inputMuted", statusCode, comment))) return RequestResult::Error(statusCode, comment); @@ -432,7 +441,8 @@ RequestResult RequestHandler::SetInputMute(const Request &request) /** * Toggles the audio mute state of an input. * - * @requestField inputName | String | Name of the input to toggle the mute state of + * @requestField ?inputName | String | Name of the input to toggle the mute state of + * @requestField ?inputUuid | String | UUID of the input to toggle the mute state of * * @responseField inputMuted | Boolean | Whether the input has been muted or unmuted * @@ -447,7 +457,7 @@ RequestResult RequestHandler::ToggleInputMute(const Request &request) { RequestStatus::RequestStatus statusCode; std::string comment; - OBSSourceAutoRelease input = request.ValidateInput("inputName", statusCode, comment); + OBSSourceAutoRelease input = request.ValidateInput(statusCode, comment); if (!input) return RequestResult::Error(statusCode, comment); @@ -465,7 +475,8 @@ RequestResult RequestHandler::ToggleInputMute(const Request &request) /** * Gets the current volume setting of an input. * - * @requestField inputName | String | Name of the input to get the volume of + * @requestField ?inputName | String | Name of the input to get the volume of + * @requestField ?inputUuid | String | UUID of the input to get the volume of * * @responseField inputVolumeMul | Number | Volume setting in mul * @responseField inputVolumeDb | Number | Volume setting in dB @@ -481,7 +492,7 @@ RequestResult RequestHandler::GetInputVolume(const Request &request) { RequestStatus::RequestStatus statusCode; std::string comment; - OBSSourceAutoRelease input = request.ValidateInput("inputName", statusCode, comment); + OBSSourceAutoRelease input = request.ValidateInput(statusCode, comment); if (!input) return RequestResult::Error(statusCode, comment); @@ -502,7 +513,8 @@ RequestResult RequestHandler::GetInputVolume(const Request &request) /** * Sets the volume setting of an input. * - * @requestField inputName | String | Name of the input to set the volume of + * @requestField ?inputName | String | Name of the input to set the volume of + * @requestField ?inputUuid | String | UUID of the input to set the volume of * @requestField ?inputVolumeMul | Number | Volume setting in mul | >= 0, <= 20 | `inputVolumeDb` should be specified * @requestField ?inputVolumeDb | Number | Volume setting in dB | >= -100, <= 26 | `inputVolumeMul` should be specified * @@ -517,7 +529,7 @@ RequestResult RequestHandler::SetInputVolume(const Request &request) { RequestStatus::RequestStatus statusCode; std::string comment; - OBSSourceAutoRelease input = request.ValidateInput("inputName", statusCode, comment); + OBSSourceAutoRelease input = request.ValidateInput(statusCode, comment); if (!input) return RequestResult::Error(statusCode, comment); @@ -552,7 +564,8 @@ RequestResult RequestHandler::SetInputVolume(const Request &request) /** * Gets the audio balance of an input. * - * @requestField inputName | String | Name of the input to get the audio balance of + * @requestField ?inputName | String | Name of the input to get the audio balance of + * @requestField ?inputUuid | String | UUID of the input to get the audio balance of * * @responseField inputAudioBalance | Number | Audio balance value from 0.0-1.0 * @@ -567,7 +580,7 @@ RequestResult RequestHandler::GetInputAudioBalance(const Request &request) { RequestStatus::RequestStatus statusCode; std::string comment; - OBSSourceAutoRelease input = request.ValidateInput("inputName", statusCode, comment); + OBSSourceAutoRelease input = request.ValidateInput(statusCode, comment); if (!input) return RequestResult::Error(statusCode, comment); @@ -583,7 +596,8 @@ RequestResult RequestHandler::GetInputAudioBalance(const Request &request) /** * Sets the audio balance of an input. * - * @requestField inputName | String | Name of the input to set the audio balance of + * @requestField ?inputName | String | Name of the input to set the audio balance of + * @requestField ?inputUuid | String | UUID of the input to set the audio balance of * @requestField inputAudioBalance | Number | New audio balance value | >= 0.0, <= 1.0 * * @requestType SetInputAudioBalance @@ -597,7 +611,7 @@ RequestResult RequestHandler::SetInputAudioBalance(const Request &request) { RequestStatus::RequestStatus statusCode; std::string comment; - OBSSourceAutoRelease input = request.ValidateInput("inputName", statusCode, comment); + OBSSourceAutoRelease input = request.ValidateInput(statusCode, comment); if (!(input && request.ValidateNumber("inputAudioBalance", statusCode, comment, 0.0, 1.0))) return RequestResult::Error(statusCode, comment); @@ -615,7 +629,8 @@ RequestResult RequestHandler::SetInputAudioBalance(const Request &request) * * Note: The audio sync offset can be negative too! * - * @requestField inputName | String | Name of the input to get the audio sync offset of + * @requestField ?inputName | String | Name of the input to get the audio sync offset of + * @requestField ?inputUuid | String | UUID of the input to get the audio sync offset of * * @responseField inputAudioSyncOffset | Number | Audio sync offset in milliseconds * @@ -630,7 +645,7 @@ RequestResult RequestHandler::GetInputAudioSyncOffset(const Request &request) { RequestStatus::RequestStatus statusCode; std::string comment; - OBSSourceAutoRelease input = request.ValidateInput("inputName", statusCode, comment); + OBSSourceAutoRelease input = request.ValidateInput(statusCode, comment); if (!input) return RequestResult::Error(statusCode, comment); @@ -647,7 +662,8 @@ RequestResult RequestHandler::GetInputAudioSyncOffset(const Request &request) /** * Sets the audio sync offset of an input. * - * @requestField inputName | String | Name of the input to set the audio sync offset of + * @requestField ?inputName | String | Name of the input to set the audio sync offset of + * @requestField ?inputUuid | String | UUID of the input to set the audio sync offset of * @requestField inputAudioSyncOffset | Number | New audio sync offset in milliseconds | >= -950, <= 20000 * * @requestType SetInputAudioSyncOffset @@ -661,7 +677,7 @@ RequestResult RequestHandler::SetInputAudioSyncOffset(const Request &request) { RequestStatus::RequestStatus statusCode; std::string comment; - OBSSourceAutoRelease input = request.ValidateInput("inputName", statusCode, comment); + OBSSourceAutoRelease input = request.ValidateInput(statusCode, comment); if (!(input && request.ValidateNumber("inputAudioSyncOffset", statusCode, comment, -950, 20000))) return RequestResult::Error(statusCode, comment); @@ -683,7 +699,8 @@ RequestResult RequestHandler::SetInputAudioSyncOffset(const Request &request) * - `OBS_MONITORING_TYPE_MONITOR_ONLY` * - `OBS_MONITORING_TYPE_MONITOR_AND_OUTPUT` * - * @requestField inputName | String | Name of the input to get the audio monitor type of + * @requestField ?inputName | String | Name of the input to get the audio monitor type of + * @requestField ?inputUuid | String | UUID of the input to get the audio monitor type of * * @responseField monitorType | String | Audio monitor type * @@ -698,7 +715,7 @@ RequestResult RequestHandler::GetInputAudioMonitorType(const Request &request) { RequestStatus::RequestStatus statusCode; std::string comment; - OBSSourceAutoRelease input = request.ValidateInput("inputName", statusCode, comment); + OBSSourceAutoRelease input = request.ValidateInput(statusCode, comment); if (!input) return RequestResult::Error(statusCode, comment); @@ -714,7 +731,8 @@ RequestResult RequestHandler::GetInputAudioMonitorType(const Request &request) /** * Sets the audio monitor type of an input. * - * @requestField inputName | String | Name of the input to set the audio monitor type of + * @requestField ?inputName | String | Name of the input to set the audio monitor type of + * @requestField ?inputUuid | String | UUID of the input to set the audio monitor type of * @requestField monitorType | String | Audio monitor type * * @requestType SetInputAudioMonitorType @@ -728,7 +746,7 @@ RequestResult RequestHandler::SetInputAudioMonitorType(const Request &request) { RequestStatus::RequestStatus statusCode; std::string comment; - OBSSourceAutoRelease input = request.ValidateInput("inputName", statusCode, comment); + OBSSourceAutoRelease input = request.ValidateInput(statusCode, comment); if (!(input && request.ValidateString("monitorType", statusCode, comment))) return RequestResult::Error(statusCode, comment); @@ -759,7 +777,8 @@ RequestResult RequestHandler::SetInputAudioMonitorType(const Request &request) /** * Gets the enable state of all audio tracks of an input. * - * @requestField inputName | String | Name of the input + * @requestField ?inputName | String | Name of the input + * @requestField ?inputUuid | String | UUID of the input * * @responseField inputAudioTracks | Object | Object of audio tracks and associated enable states * @@ -774,7 +793,7 @@ RequestResult RequestHandler::GetInputAudioTracks(const Request &request) { RequestStatus::RequestStatus statusCode; std::string comment; - OBSSourceAutoRelease input = request.ValidateInput("inputName", statusCode, comment); + OBSSourceAutoRelease input = request.ValidateInput(statusCode, comment); if (!input) return RequestResult::Error(statusCode, comment); @@ -797,7 +816,8 @@ RequestResult RequestHandler::GetInputAudioTracks(const Request &request) /** * Sets the enable state of audio tracks of an input. * - * @requestField inputName | String | Name of the input + * @requestField ?inputName | String | Name of the input + * @requestField ?inputUuid | String | UUID of the input * @requestField inputAudioTracks | Object | Track settings to apply * * @requestType SetInputAudioTracks @@ -811,7 +831,7 @@ RequestResult RequestHandler::SetInputAudioTracks(const Request &request) { RequestStatus::RequestStatus statusCode; std::string comment; - OBSSourceAutoRelease input = request.ValidateInput("inputName", statusCode, comment); + OBSSourceAutoRelease input = request.ValidateInput(statusCode, comment); if (!input || !request.ValidateObject("inputAudioTracks", statusCode, comment)) return RequestResult::Error(statusCode, comment); @@ -851,7 +871,8 @@ RequestResult RequestHandler::SetInputAudioTracks(const Request &request) * * Note: Use this in cases where an input provides a dynamic, selectable list of items. For example, display capture, where it provides a list of available displays. * - * @requestField inputName | String | Name of the input + * @requestField ?inputName | String | Name of the input + * @requestField ?inputUuid | String | UUID of the input * @requestField propertyName | String | Name of the list property to get the items of * * @responseField propertyItems | Array | Array of items in the list property @@ -867,7 +888,7 @@ RequestResult RequestHandler::GetInputPropertiesListPropertyItems(const Request { RequestStatus::RequestStatus statusCode; std::string comment; - OBSSourceAutoRelease input = request.ValidateInput("inputName", statusCode, comment); + OBSSourceAutoRelease input = request.ValidateInput(statusCode, comment); if (!(input && request.ValidateString("propertyName", statusCode, comment))) return RequestResult::Error(statusCode, comment); @@ -895,7 +916,8 @@ RequestResult RequestHandler::GetInputPropertiesListPropertyItems(const Request * * Note: Use this in cases where there is a button in the properties of an input that cannot be accessed in any other way. For example, browser sources, where there is a refresh button. * - * @requestField inputName | String | Name of the input + * @requestField ?inputName | String | Name of the input + * @requestField ?inputUuid | String | UUID of the input * @requestField propertyName | String | Name of the button property to press * * @requestType PressInputPropertiesButton @@ -909,7 +931,7 @@ RequestResult RequestHandler::PressInputPropertiesButton(const Request &request) { RequestStatus::RequestStatus statusCode; std::string comment; - OBSSourceAutoRelease input = request.ValidateInput("inputName", statusCode, comment); + OBSSourceAutoRelease input = request.ValidateInput(statusCode, comment); if (!(input && request.ValidateString("propertyName", statusCode, comment))) return RequestResult::Error(statusCode, comment); diff --git a/src/requesthandler/RequestHandler_MediaInputs.cpp b/src/requesthandler/RequestHandler_MediaInputs.cpp index 298976001..3c176e20d 100644 --- a/src/requesthandler/RequestHandler_MediaInputs.cpp +++ b/src/requesthandler/RequestHandler_MediaInputs.cpp @@ -39,7 +39,8 @@ bool IsMediaTimeValid(obs_source_t *input) * - `OBS_MEDIA_STATE_ENDED` * - `OBS_MEDIA_STATE_ERROR` * - * @requestField inputName | String | Name of the media input + * @requestField ?inputName | String | Name of the media input + * @requestField ?inputUuid | String | UUID of the media input * * @responseField mediaState | String | State of the media input * @responseField mediaDuration | Number | Total duration of the playing media in milliseconds. `null` if not playing @@ -56,7 +57,7 @@ RequestResult RequestHandler::GetMediaInputStatus(const Request &request) { RequestStatus::RequestStatus statusCode; std::string comment; - OBSSourceAutoRelease input = request.ValidateInput("inputName", statusCode, comment); + OBSSourceAutoRelease input = request.ValidateInput(statusCode, comment); if (!input) return RequestResult::Error(statusCode, comment); @@ -80,7 +81,8 @@ RequestResult RequestHandler::GetMediaInputStatus(const Request &request) * * This request does not perform bounds checking of the cursor position. * - * @requestField inputName | String | Name of the media input + * @requestField ?inputName | String | Name of the media input + * @requestField ?inputUuid | String | UUID of the media input * @requestField mediaCursor | Number | New cursor position to set | >= 0 * * @requestType SetMediaInputCursor @@ -94,7 +96,7 @@ RequestResult RequestHandler::SetMediaInputCursor(const Request &request) { RequestStatus::RequestStatus statusCode; std::string comment; - OBSSourceAutoRelease input = request.ValidateInput("inputName", statusCode, comment); + OBSSourceAutoRelease input = request.ValidateInput(statusCode, comment); if (!(input && request.ValidateNumber("mediaCursor", statusCode, comment, 0))) return RequestResult::Error(statusCode, comment); @@ -115,7 +117,8 @@ RequestResult RequestHandler::SetMediaInputCursor(const Request &request) * * This request does not perform bounds checking of the cursor position. * - * @requestField inputName | String | Name of the media input + * @requestField ?inputName | String | Name of the media input + * @requestField ?inputUuid | String | UUID of the media input * @requestField mediaCursorOffset | Number | Value to offset the current cursor position by | None * * @requestType OffsetMediaInputCursor @@ -129,7 +132,7 @@ RequestResult RequestHandler::OffsetMediaInputCursor(const Request &request) { RequestStatus::RequestStatus statusCode; std::string comment; - OBSSourceAutoRelease input = request.ValidateInput("inputName", statusCode, comment); + OBSSourceAutoRelease input = request.ValidateInput(statusCode, comment); if (!(input && request.ValidateNumber("mediaCursorOffset", statusCode, comment))) return RequestResult::Error(statusCode, comment); @@ -151,7 +154,8 @@ RequestResult RequestHandler::OffsetMediaInputCursor(const Request &request) /** * Triggers an action on a media input. * - * @requestField inputName | String | Name of the media input + * @requestField ?inputName | String | Name of the media input + * @requestField ?inputUuid | String | UUID of the media input * @requestField mediaAction | String | Identifier of the `ObsMediaInputAction` enum * * @requestType TriggerMediaInputAction @@ -165,7 +169,7 @@ RequestResult RequestHandler::TriggerMediaInputAction(const Request &request) { RequestStatus::RequestStatus statusCode; std::string comment; - OBSSourceAutoRelease input = request.ValidateInput("inputName", statusCode, comment); + OBSSourceAutoRelease input = request.ValidateInput(statusCode, comment); if (!(input && request.ValidateString("mediaAction", statusCode, comment))) return RequestResult::Error(statusCode, comment); diff --git a/src/requesthandler/RequestHandler_Record.cpp b/src/requesthandler/RequestHandler_Record.cpp index b35a5c43d..e7310588e 100644 --- a/src/requesthandler/RequestHandler_Record.cpp +++ b/src/requesthandler/RequestHandler_Record.cpp @@ -54,6 +54,8 @@ RequestResult RequestHandler::GetRecordStatus(const Request &) /** * Toggles the status of the record output. * + * @responseField outputActive | Boolean | The new active state of the output + * * @requestType ToggleRecord * @complexity 1 * @rpcVersion -1 diff --git a/src/requesthandler/RequestHandler_SceneItems.cpp b/src/requesthandler/RequestHandler_SceneItems.cpp index 0c5024a04..ea70ca7b9 100644 --- a/src/requesthandler/RequestHandler_SceneItems.cpp +++ b/src/requesthandler/RequestHandler_SceneItems.cpp @@ -24,7 +24,8 @@ with this program. If not, see * * Scenes only * - * @requestField sceneName | String | Name of the scene to get the items of + * @requestField ?sceneName | String | Name of the scene to get the items of + * @requestField ?sceneUuid | String | UUID of the scene to get the items of * * @responseField sceneItems | Array | Array of scene items in the scene * @@ -39,7 +40,7 @@ RequestResult RequestHandler::GetSceneItemList(const Request &request) { RequestStatus::RequestStatus statusCode; std::string comment; - OBSSourceAutoRelease scene = request.ValidateScene("sceneName", statusCode, comment); + OBSSourceAutoRelease scene = request.ValidateScene(statusCode, comment); if (!scene) return RequestResult::Error(statusCode, comment); @@ -56,7 +57,8 @@ RequestResult RequestHandler::GetSceneItemList(const Request &request) * * Groups only * - * @requestField sceneName | String | Name of the group to get the items of + * @requestField ?sceneName | String | Name of the group to get the items of + * @requestField ?sceneUuid | String | UUID of the group to get the items of * * @responseField sceneItems | Array | Array of scene items in the group * @@ -71,7 +73,7 @@ RequestResult RequestHandler::GetGroupSceneItemList(const Request &request) { RequestStatus::RequestStatus statusCode; std::string comment; - OBSSourceAutoRelease scene = request.ValidateScene("sceneName", statusCode, comment, OBS_WEBSOCKET_SCENE_FILTER_GROUP_ONLY); + OBSSourceAutoRelease scene = request.ValidateScene(statusCode, comment, OBS_WEBSOCKET_SCENE_FILTER_GROUP_ONLY); if (!scene) return RequestResult::Error(statusCode, comment); @@ -86,7 +88,8 @@ RequestResult RequestHandler::GetGroupSceneItemList(const Request &request) * * Scenes and Groups * - * @requestField sceneName | String | Name of the scene or group to search in + * @requestField ?sceneName | String | Name of the scene or group to search in + * @requestField ?sceneUuid | String | UUID of the scene or group to search in * @requestField sourceName | String | Name of the source to find * @requestField ?searchOffset | Number | Number of matches to skip during search. >= 0 means first forward. -1 means last (top) item | >= -1 | 0 * @@ -104,8 +107,8 @@ RequestResult RequestHandler::GetSceneItemId(const Request &request) RequestStatus::RequestStatus statusCode; std::string comment; OBSSceneAutoRelease scene = - request.ValidateScene2("sceneName", statusCode, comment, OBS_WEBSOCKET_SCENE_FILTER_SCENE_OR_GROUP); - if (!(scene && request.ValidateString("sourceName", statusCode, comment))) + request.ValidateScene2(statusCode, comment, OBS_WEBSOCKET_SCENE_FILTER_SCENE_OR_GROUP); + if (!(scene && request.ValidateString("sourceName", statusCode, comment))) // TODO: Source UUID support return RequestResult::Error(statusCode, comment); std::string sourceName = request.RequestData["sourceName"]; @@ -128,13 +131,49 @@ RequestResult RequestHandler::GetSceneItemId(const Request &request) return RequestResult::Success(responseData); } +/** + * Gets the source associated with a scene item. + * + * @requestField ?sceneName | String | Name of the scene the item is in + * @requestField ?sceneUuid | String | UUID of the scene the item is in + * @requestField sceneItemId | Number | Numeric ID of the scene item | >= 0 + * + * @responseField sourceName | String | Name of the source associated with the scene item + * @responseField sourceUuid | String | UUID of the source associated with the scene item + * + * @requestType GetSceneItemSource + * @complexity 3 + * @rpcVersion -1 + * @initialVersion 5.4.0 + * @api requests + * @category scene items + */ +RequestResult RequestHandler::GetSceneItemSource(const Request &request) +{ + RequestStatus::RequestStatus statusCode; + std::string comment; + OBSSceneItemAutoRelease sceneItem = request.ValidateSceneItem(statusCode, comment); + if (!sceneItem) + return RequestResult::Error(statusCode, comment); + + OBSSource source = obs_sceneitem_get_source(sceneItem); + + json responseData; + responseData["sourceName"] = obs_source_get_name(source); + responseData["sourceUuid"] = obs_source_get_uuid(source); + + return RequestResult::Success(responseData); +} + /** * Creates a new scene item using a source. * * Scenes only * - * @requestField sceneName | String | Name of the scene to create the new item in - * @requestField sourceName | String | Name of the source to add to the scene + * @requestField ?sceneName | String | Name of the scene to create the new item in + * @requestField ?sceneUuid | String | UUID of the scene to create the new item in + * @requestField ?sourceName | String | Name of the source to add to the scene + * @requestField ?sourceUuid | String | UUID of the source to add to the scene * @requestField ?sceneItemEnabled | Boolean | Enable state to apply to the scene item on creation | True * * @responseField sceneItemId | Number | Numeric ID of the scene item @@ -150,17 +189,17 @@ RequestResult RequestHandler::CreateSceneItem(const Request &request) { RequestStatus::RequestStatus statusCode; std::string comment; - OBSSourceAutoRelease sceneSource = request.ValidateScene("sceneName", statusCode, comment); + OBSSourceAutoRelease sceneSource = request.ValidateScene(statusCode, comment); if (!sceneSource) return RequestResult::Error(statusCode, comment); OBSScene scene = obs_scene_from_source(sceneSource); - OBSSourceAutoRelease source = request.ValidateSource("sourceName", statusCode, comment); + OBSSourceAutoRelease source = request.ValidateSource("sourceName", "sourceUuid", statusCode, comment); if (!source) return RequestResult::Error(statusCode, comment); - if (request.RequestData["sceneName"] == request.RequestData["sourceName"]) + if (sceneSource == source) return RequestResult::Error(RequestStatus::CannotAct, "You cannot create scene item of a scene within itself."); bool sceneItemEnabled = true; @@ -185,7 +224,8 @@ RequestResult RequestHandler::CreateSceneItem(const Request &request) * * Scenes only * - * @requestField sceneName | String | Name of the scene the item is in + * @requestField ?sceneName | String | Name of the scene the item is in + * @requestField ?sceneUuid | String | UUID of the scene the item is in * @requestField sceneItemId | Number | Numeric ID of the scene item | >= 0 * * @requestType RemoveSceneItem @@ -199,7 +239,7 @@ RequestResult RequestHandler::RemoveSceneItem(const Request &request) { RequestStatus::RequestStatus statusCode; std::string comment; - OBSSceneItemAutoRelease sceneItem = request.ValidateSceneItem("sceneName", "sceneItemId", statusCode, comment); + OBSSceneItemAutoRelease sceneItem = request.ValidateSceneItem(statusCode, comment); if (!sceneItem) return RequestResult::Error(statusCode, comment); @@ -214,9 +254,11 @@ RequestResult RequestHandler::RemoveSceneItem(const Request &request) * * Scenes only * - * @requestField sceneName | String | Name of the scene the item is in + * @requestField ?sceneName | String | Name of the scene the item is in + * @requestField ?sceneUuid | String | UUID of the scene the item is in * @requestField sceneItemId | Number | Numeric ID of the scene item | >= 0 - * @requestField ?destinationSceneName | String | Name of the scene to create the duplicated item in | `sceneName` is assumed + * @requestField ?destinationSceneName | String | Name of the scene to create the duplicated item in | From scene is assumed + * @requestField ?destinationSceneUuid | String | UUID of the scene to create the duplicated item in | From scene is assumed * * @responseField sceneItemId | Number | Numeric ID of the duplicated scene item * @@ -231,16 +273,24 @@ RequestResult RequestHandler::DuplicateSceneItem(const Request &request) { RequestStatus::RequestStatus statusCode; std::string comment; - OBSSceneItemAutoRelease sceneItem = request.ValidateSceneItem("sceneName", "sceneItemId", statusCode, comment); + OBSSceneItemAutoRelease sceneItem = request.ValidateSceneItem(statusCode, comment); if (!sceneItem) return RequestResult::Error(statusCode, comment); // Get destination scene obs_scene_t *destinationScene; if (request.Contains("destinationSceneName")) { - destinationScene = request.ValidateScene2("destinationSceneName", statusCode, comment); - if (!destinationScene) + OBSSourceAutoRelease destinationSceneSource = request.ValidateSource("destinationSceneName", "destinationSceneUuid", statusCode, comment); + if (!destinationSceneSource) return RequestResult::Error(statusCode, comment); + + // Reimplementation of ValidateScene2 + if (obs_source_get_type(destinationSceneSource) != OBS_SOURCE_TYPE_SCENE) + return RequestResult::Error(RequestStatus::InvalidResourceType, "The specified source is not a scene."); + if (obs_source_is_group(destinationSceneSource)) + return RequestResult::Error(RequestStatus::InvalidResourceType, "The specified source is not a scene. (Is group)"); + + destinationScene = obs_scene_get_ref(obs_scene_from_source(destinationSceneSource)); } else { destinationScene = obs_scene_get_ref(obs_sceneitem_get_scene(sceneItem)); if (!destinationScene) @@ -279,7 +329,8 @@ RequestResult RequestHandler::DuplicateSceneItem(const Request &request) * * Scenes and Groups * - * @requestField sceneName | String | Name of the scene the item is in + * @requestField ?sceneName | String | Name of the scene the item is in + * @requestField ?sceneUuid | String | UUID of the scene the item is in * @requestField sceneItemId | Number | Numeric ID of the scene item | >= 0 * * @responseField sceneItemTransform | Object | Object containing scene item transform info @@ -295,8 +346,7 @@ RequestResult RequestHandler::GetSceneItemTransform(const Request &request) { RequestStatus::RequestStatus statusCode; std::string comment; - OBSSceneItemAutoRelease sceneItem = request.ValidateSceneItem("sceneName", "sceneItemId", statusCode, comment, - OBS_WEBSOCKET_SCENE_FILTER_SCENE_OR_GROUP); + OBSSceneItemAutoRelease sceneItem = request.ValidateSceneItem(statusCode, comment, OBS_WEBSOCKET_SCENE_FILTER_SCENE_OR_GROUP); if (!sceneItem) return RequestResult::Error(statusCode, comment); @@ -309,7 +359,8 @@ RequestResult RequestHandler::GetSceneItemTransform(const Request &request) /** * Sets the transform and crop info of a scene item. * - * @requestField sceneName | String | Name of the scene the item is in + * @requestField ?sceneName | String | Name of the scene the item is in + * @requestField ?sceneUuid | String | UUID of the scene the item is in * @requestField sceneItemId | Number | Numeric ID of the scene item | >= 0 * @requestField sceneItemTransform | Object | Object containing scene item transform info to update * @@ -324,8 +375,7 @@ RequestResult RequestHandler::SetSceneItemTransform(const Request &request) { RequestStatus::RequestStatus statusCode; std::string comment; - OBSSceneItemAutoRelease sceneItem = request.ValidateSceneItem("sceneName", "sceneItemId", statusCode, comment, - OBS_WEBSOCKET_SCENE_FILTER_SCENE_OR_GROUP); + OBSSceneItemAutoRelease sceneItem = request.ValidateSceneItem(statusCode, comment, OBS_WEBSOCKET_SCENE_FILTER_SCENE_OR_GROUP); if (!(sceneItem && request.ValidateObject("sceneItemTransform", statusCode, comment))) return RequestResult::Error(statusCode, comment); @@ -466,7 +516,8 @@ RequestResult RequestHandler::SetSceneItemTransform(const Request &request) * * Scenes and Groups * - * @requestField sceneName | String | Name of the scene the item is in + * @requestField ?sceneName | String | Name of the scene the item is in + * @requestField ?sceneUuid | String | UUID of the scene the item is in * @requestField sceneItemId | Number | Numeric ID of the scene item | >= 0 * * @responseField sceneItemEnabled | Boolean | Whether the scene item is enabled. `true` for enabled, `false` for disabled @@ -482,8 +533,7 @@ RequestResult RequestHandler::GetSceneItemEnabled(const Request &request) { RequestStatus::RequestStatus statusCode; std::string comment; - OBSSceneItemAutoRelease sceneItem = request.ValidateSceneItem("sceneName", "sceneItemId", statusCode, comment, - OBS_WEBSOCKET_SCENE_FILTER_SCENE_OR_GROUP); + OBSSceneItemAutoRelease sceneItem = request.ValidateSceneItem(statusCode, comment, OBS_WEBSOCKET_SCENE_FILTER_SCENE_OR_GROUP); if (!sceneItem) return RequestResult::Error(statusCode, comment); @@ -498,7 +548,8 @@ RequestResult RequestHandler::GetSceneItemEnabled(const Request &request) * * Scenes and Groups * - * @requestField sceneName | String | Name of the scene the item is in + * @requestField ?sceneName | String | Name of the scene the item is in + * @requestField ?sceneUuid | String | UUID of the scene the item is in * @requestField sceneItemId | Number | Numeric ID of the scene item | >= 0 * @requestField sceneItemEnabled | Boolean | New enable state of the scene item * @@ -513,8 +564,7 @@ RequestResult RequestHandler::SetSceneItemEnabled(const Request &request) { RequestStatus::RequestStatus statusCode; std::string comment; - OBSSceneItemAutoRelease sceneItem = request.ValidateSceneItem("sceneName", "sceneItemId", statusCode, comment, - OBS_WEBSOCKET_SCENE_FILTER_SCENE_OR_GROUP); + OBSSceneItemAutoRelease sceneItem = request.ValidateSceneItem(statusCode, comment, OBS_WEBSOCKET_SCENE_FILTER_SCENE_OR_GROUP); if (!(sceneItem && request.ValidateBoolean("sceneItemEnabled", statusCode, comment))) return RequestResult::Error(statusCode, comment); @@ -530,7 +580,8 @@ RequestResult RequestHandler::SetSceneItemEnabled(const Request &request) * * Scenes and Groups * - * @requestField sceneName | String | Name of the scene the item is in + * @requestField ?sceneName | String | Name of the scene the item is in + * @requestField ?sceneUuid | String | UUID of the scene the item is in * @requestField sceneItemId | Number | Numeric ID of the scene item | >= 0 * * @responseField sceneItemLocked | Boolean | Whether the scene item is locked. `true` for locked, `false` for unlocked @@ -546,8 +597,7 @@ RequestResult RequestHandler::GetSceneItemLocked(const Request &request) { RequestStatus::RequestStatus statusCode; std::string comment; - OBSSceneItemAutoRelease sceneItem = request.ValidateSceneItem("sceneName", "sceneItemId", statusCode, comment, - OBS_WEBSOCKET_SCENE_FILTER_SCENE_OR_GROUP); + OBSSceneItemAutoRelease sceneItem = request.ValidateSceneItem(statusCode, comment, OBS_WEBSOCKET_SCENE_FILTER_SCENE_OR_GROUP); if (!sceneItem) return RequestResult::Error(statusCode, comment); @@ -562,8 +612,9 @@ RequestResult RequestHandler::GetSceneItemLocked(const Request &request) * * Scenes and Group * - * @requestField sceneName | String | Name of the scene the item is in - * @requestField sceneItemId | Number | Numeric ID of the scene item | >= 0 + * @requestField ?sceneName | String | Name of the scene the item is in + * @requestField ?sceneUuid | String | UUID of the scene the item is in + * @requestField sceneItemId | Number | Numeric ID of the scene item | >= 0 * @requestField sceneItemLocked | Boolean | New lock state of the scene item * * @requestType SetSceneItemLocked @@ -577,8 +628,7 @@ RequestResult RequestHandler::SetSceneItemLocked(const Request &request) { RequestStatus::RequestStatus statusCode; std::string comment; - OBSSceneItemAutoRelease sceneItem = request.ValidateSceneItem("sceneName", "sceneItemId", statusCode, comment, - OBS_WEBSOCKET_SCENE_FILTER_SCENE_OR_GROUP); + OBSSceneItemAutoRelease sceneItem = request.ValidateSceneItem(statusCode, comment, OBS_WEBSOCKET_SCENE_FILTER_SCENE_OR_GROUP); if (!(sceneItem && request.ValidateBoolean("sceneItemLocked", statusCode, comment))) return RequestResult::Error(statusCode, comment); @@ -596,7 +646,8 @@ RequestResult RequestHandler::SetSceneItemLocked(const Request &request) * * Scenes and Groups * - * @requestField sceneName | String | Name of the scene the item is in + * @requestField ?sceneName | String | Name of the scene the item is in + * @requestField ?sceneUuid | String | UUID of the scene the item is in * @requestField sceneItemId | Number | Numeric ID of the scene item | >= 0 * * @responseField sceneItemIndex | Number | Index position of the scene item @@ -612,8 +663,7 @@ RequestResult RequestHandler::GetSceneItemIndex(const Request &request) { RequestStatus::RequestStatus statusCode; std::string comment; - OBSSceneItemAutoRelease sceneItem = request.ValidateSceneItem("sceneName", "sceneItemId", statusCode, comment, - OBS_WEBSOCKET_SCENE_FILTER_SCENE_OR_GROUP); + OBSSceneItemAutoRelease sceneItem = request.ValidateSceneItem(statusCode, comment, OBS_WEBSOCKET_SCENE_FILTER_SCENE_OR_GROUP); if (!sceneItem) return RequestResult::Error(statusCode, comment); @@ -628,7 +678,8 @@ RequestResult RequestHandler::GetSceneItemIndex(const Request &request) * * Scenes and Groups * - * @requestField sceneName | String | Name of the scene the item is in + * @requestField ?sceneName | String | Name of the scene the item is in + * @requestField ?sceneUuid | String | UUID of the scene the item is in * @requestField sceneItemId | Number | Numeric ID of the scene item | >= 0 * @requestField sceneItemIndex | Number | New index position of the scene item | >= 0 * @@ -643,8 +694,7 @@ RequestResult RequestHandler::SetSceneItemIndex(const Request &request) { RequestStatus::RequestStatus statusCode; std::string comment; - OBSSceneItemAutoRelease sceneItem = request.ValidateSceneItem("sceneName", "sceneItemId", statusCode, comment, - OBS_WEBSOCKET_SCENE_FILTER_SCENE_OR_GROUP); + OBSSceneItemAutoRelease sceneItem = request.ValidateSceneItem(statusCode, comment, OBS_WEBSOCKET_SCENE_FILTER_SCENE_OR_GROUP); if (!(sceneItem && request.ValidateNumber("sceneItemIndex", statusCode, comment, 0, 8192))) return RequestResult::Error(statusCode, comment); @@ -670,7 +720,8 @@ RequestResult RequestHandler::SetSceneItemIndex(const Request &request) * * Scenes and Groups * - * @requestField sceneName | String | Name of the scene the item is in + * @requestField ?sceneName | String | Name of the scene the item is in + * @requestField ?sceneUuid | String | UUID of the scene the item is in * @requestField sceneItemId | Number | Numeric ID of the scene item | >= 0 * * @responseField sceneItemBlendMode | String | Current blend mode @@ -686,8 +737,7 @@ RequestResult RequestHandler::GetSceneItemBlendMode(const Request &request) { RequestStatus::RequestStatus statusCode; std::string comment; - OBSSceneItemAutoRelease sceneItem = request.ValidateSceneItem("sceneName", "sceneItemId", statusCode, comment, - OBS_WEBSOCKET_SCENE_FILTER_SCENE_OR_GROUP); + OBSSceneItemAutoRelease sceneItem = request.ValidateSceneItem(statusCode, comment, OBS_WEBSOCKET_SCENE_FILTER_SCENE_OR_GROUP); if (!sceneItem) return RequestResult::Error(statusCode, comment); @@ -704,7 +754,8 @@ RequestResult RequestHandler::GetSceneItemBlendMode(const Request &request) * * Scenes and Groups * - * @requestField sceneName | String | Name of the scene the item is in + * @requestField ?sceneName | String | Name of the scene the item is in + * @requestField ?sceneUuid | String | UUID of the scene the item is in * @requestField sceneItemId | Number | Numeric ID of the scene item | >= 0 * @requestField sceneItemBlendMode | String | New blend mode * @@ -719,8 +770,7 @@ RequestResult RequestHandler::SetSceneItemBlendMode(const Request &request) { RequestStatus::RequestStatus statusCode; std::string comment; - OBSSceneItemAutoRelease sceneItem = request.ValidateSceneItem("sceneName", "sceneItemId", statusCode, comment, - OBS_WEBSOCKET_SCENE_FILTER_SCENE_OR_GROUP); + OBSSceneItemAutoRelease sceneItem = request.ValidateSceneItem(statusCode, comment, OBS_WEBSOCKET_SCENE_FILTER_SCENE_OR_GROUP); if (!(sceneItem && request.ValidateString("sceneItemBlendMode", statusCode, comment))) return RequestResult::Error(statusCode, comment); @@ -739,8 +789,7 @@ RequestResult RequestHandler::GetSceneItemPrivateSettings(const Request &request { RequestStatus::RequestStatus statusCode; std::string comment; - OBSSceneItemAutoRelease sceneItem = request.ValidateSceneItem("sceneName", "sceneItemId", statusCode, comment, - OBS_WEBSOCKET_SCENE_FILTER_SCENE_OR_GROUP); + OBSSceneItemAutoRelease sceneItem = request.ValidateSceneItem(statusCode, comment, OBS_WEBSOCKET_SCENE_FILTER_SCENE_OR_GROUP); if (!sceneItem) return RequestResult::Error(statusCode, comment); @@ -757,8 +806,7 @@ RequestResult RequestHandler::SetSceneItemPrivateSettings(const Request &request { RequestStatus::RequestStatus statusCode; std::string comment; - OBSSceneItemAutoRelease sceneItem = request.ValidateSceneItem("sceneName", "sceneItemId", statusCode, comment, - OBS_WEBSOCKET_SCENE_FILTER_SCENE_OR_GROUP); + OBSSceneItemAutoRelease sceneItem = request.ValidateSceneItem(statusCode, comment, OBS_WEBSOCKET_SCENE_FILTER_SCENE_OR_GROUP); if (!sceneItem || !request.ValidateObject("sceneItemSettings", statusCode, comment, true)) return RequestResult::Error(statusCode, comment); diff --git a/src/requesthandler/RequestHandler_Scenes.cpp b/src/requesthandler/RequestHandler_Scenes.cpp index fcf293908..47ede5dda 100644 --- a/src/requesthandler/RequestHandler_Scenes.cpp +++ b/src/requesthandler/RequestHandler_Scenes.cpp @@ -22,8 +22,10 @@ with this program. If not, see /** * Gets an array of all scenes in OBS. * - * @responseField currentProgramSceneName | String | Current program scene - * @responseField currentPreviewSceneName | String | Current preview scene. `null` if not in studio mode + * @responseField currentProgramSceneName | String | Current program scene name. Can be `null` if internal state desync + * @responseField currentProgramSceneUuid | String | Current program scene UUID. Can be `null` if internal state desync + * @responseField currentPreviewSceneName | String | Current preview scene name. `null` if not in studio mode + * @responseField currentPreviewSceneUuid | String | Current preview scene UUID. `null` if not in studio mode * @responseField scenes | Array | Array of scenes * * @requestType GetSceneList @@ -38,16 +40,22 @@ RequestResult RequestHandler::GetSceneList(const Request &) json responseData; OBSSourceAutoRelease currentProgramScene = obs_frontend_get_current_scene(); - if (currentProgramScene) + if (currentProgramScene) { responseData["currentProgramSceneName"] = obs_source_get_name(currentProgramScene); - else + responseData["currentProgramSceneUuid"] = obs_source_get_uuid(currentProgramScene); + } else { responseData["currentProgramSceneName"] = nullptr; + responseData["currentProgramSceneUuid"] = nullptr; + } OBSSourceAutoRelease currentPreviewScene = obs_frontend_get_current_preview_scene(); - if (currentPreviewScene) + if (currentPreviewScene) { responseData["currentPreviewSceneName"] = obs_source_get_name(currentPreviewScene); - else + responseData["currentPreviewSceneUuid"] = obs_source_get_uuid(currentPreviewScene); + } else { responseData["currentPreviewSceneName"] = nullptr; + responseData["currentPreviewSceneUuid"] = nullptr; + } responseData["scenes"] = Utils::Obs::ArrayHelper::GetSceneList(); @@ -80,7 +88,12 @@ RequestResult RequestHandler::GetGroupList(const Request &) /** * Gets the current program scene. * - * @responseField currentProgramSceneName | String | Current program scene + * Note: This request is slated to have the `currentProgram`-prefixed fields removed from in an upcoming RPC version. + * + * @responseField sceneName | String | Current program scene name + * @responseField sceneUuid | String | Current program scene UUID + * @responseField currentProgramSceneName | String | Current program scene name (Deprecated) + * @responseField currentProgramSceneUuid | String | Current program scene UUID (Deprecated) * * @requestType GetCurrentProgramScene * @complexity 1 @@ -93,7 +106,8 @@ RequestResult RequestHandler::GetCurrentProgramScene(const Request &) { json responseData; OBSSourceAutoRelease currentProgramScene = obs_frontend_get_current_scene(); - responseData["currentProgramSceneName"] = obs_source_get_name(currentProgramScene); + responseData["sceneName"] = responseData["currentProgramSceneName"] = obs_source_get_name(currentProgramScene); + responseData["sceneUuid"] = responseData["currentProgramSceneUuid"] = obs_source_get_uuid(currentProgramScene); return RequestResult::Success(responseData); } @@ -101,7 +115,8 @@ RequestResult RequestHandler::GetCurrentProgramScene(const Request &) /** * Sets the current program scene. * - * @requestField sceneName | String | Scene to set as the current program scene + * @requestField ?sceneName | String | Scene name to set as the current program scene + * @requestField ?sceneUuid | String | Scene UUID to set as the current program scene * * @requestType SetCurrentProgramScene * @complexity 1 @@ -114,7 +129,7 @@ RequestResult RequestHandler::SetCurrentProgramScene(const Request &request) { RequestStatus::RequestStatus statusCode; std::string comment; - OBSSourceAutoRelease scene = request.ValidateScene("sceneName", statusCode, comment); + OBSSourceAutoRelease scene = request.ValidateScene(statusCode, comment); if (!scene) return RequestResult::Error(statusCode, comment); @@ -128,7 +143,12 @@ RequestResult RequestHandler::SetCurrentProgramScene(const Request &request) * * Only available when studio mode is enabled. * - * @responseField currentPreviewSceneName | String | Current preview scene + * Note: This request is slated to have the `currentPreview`-prefixed fields removed from in an upcoming RPC version. + * + * @responseField sceneName | String | Current preview scene name + * @responseField sceneUuid | String | Current preview scene UUID + * @responseField currentPreviewSceneName | String | Current preview scene name + * @responseField currentPreviewSceneUuid | String | Current preview scene UUID * * @requestType GetCurrentPreviewScene * @complexity 1 @@ -145,7 +165,8 @@ RequestResult RequestHandler::GetCurrentPreviewScene(const Request &) OBSSourceAutoRelease currentPreviewScene = obs_frontend_get_current_preview_scene(); json responseData; - responseData["currentPreviewSceneName"] = obs_source_get_name(currentPreviewScene); + responseData["sceneName"] = responseData["currentPreviewSceneName"] = obs_source_get_name(currentPreviewScene); + responseData["sceneUuid"] = responseData["currentPreviewSceneUuid"] = obs_source_get_uuid(currentPreviewScene); return RequestResult::Success(responseData); } @@ -155,7 +176,8 @@ RequestResult RequestHandler::GetCurrentPreviewScene(const Request &) * * Only available when studio mode is enabled. * - * @requestField sceneName | String | Scene to set as the current preview scene + * @requestField ?sceneName | String | Scene name to set as the current preview scene + * @requestField ?sceneUuid | String | Scene UUID to set as the current preview scene * * @requestType SetCurrentPreviewScene * @complexity 1 @@ -171,7 +193,7 @@ RequestResult RequestHandler::SetCurrentPreviewScene(const Request &request) RequestStatus::RequestStatus statusCode; std::string comment; - OBSSourceAutoRelease scene = request.ValidateScene("sceneName", statusCode, comment); + OBSSourceAutoRelease scene = request.ValidateScene(statusCode, comment); if (!scene) return RequestResult::Error(statusCode, comment); @@ -185,6 +207,8 @@ RequestResult RequestHandler::SetCurrentPreviewScene(const Request &request) * * @requestField sceneName | String | Name for the new scene * + * @responseField sceneUuid | String | UUID of the created scene + * * @requestType CreateScene * @complexity 2 * @rpcVersion -1 @@ -205,19 +229,21 @@ RequestResult RequestHandler::CreateScene(const Request &request) if (scene) return RequestResult::Error(RequestStatus::ResourceAlreadyExists, "A source already exists by that scene name."); - obs_scene_t *createdScene = obs_scene_create(sceneName.c_str()); + OBSSceneAutoRelease createdScene = obs_scene_create(sceneName.c_str()); if (!createdScene) return RequestResult::Error(RequestStatus::ResourceCreationFailed, "Failed to create the scene."); - obs_scene_release(createdScene); + json responseData; + responseData["sceneUuid"] = obs_source_get_uuid(obs_scene_get_source(createdScene)); - return RequestResult::Success(); + return RequestResult::Success(responseData); } /** * Removes a scene from OBS. * - * @requestField sceneName | String | Name of the scene to remove + * @requestField ?sceneName | String | Name of the scene to remove + * @requestField ?sceneUuid | String | UUID of the scene to remove * * @requestType RemoveScene * @complexity 2 @@ -230,7 +256,7 @@ RequestResult RequestHandler::RemoveScene(const Request &request) { RequestStatus::RequestStatus statusCode; std::string comment; - OBSSourceAutoRelease scene = request.ValidateScene("sceneName", statusCode, comment); + OBSSourceAutoRelease scene = request.ValidateScene(statusCode, comment); if (!scene) return RequestResult::Error(statusCode, comment); @@ -246,7 +272,8 @@ RequestResult RequestHandler::RemoveScene(const Request &request) /** * Sets the name of a scene (rename). * - * @requestField sceneName | String | Name of the scene to be renamed + * @requestField ?sceneName | String | Name of the scene to be renamed + * @requestField ?sceneUuid | String | UUID of the scene to be renamed * @requestField newSceneName | String | New name for the scene * * @requestType SetSceneName @@ -260,7 +287,7 @@ RequestResult RequestHandler::SetSceneName(const Request &request) { RequestStatus::RequestStatus statusCode; std::string comment; - OBSSourceAutoRelease scene = request.ValidateScene("sceneName", statusCode, comment); + OBSSourceAutoRelease scene = request.ValidateScene(statusCode, comment); if (!(scene && request.ValidateString("newSceneName", statusCode, comment))) return RequestResult::Error(statusCode, comment); @@ -279,7 +306,10 @@ RequestResult RequestHandler::SetSceneName(const Request &request) /** * Gets the scene transition overridden for a scene. * - * @requestField sceneName | String | Name of the scene + * Note: A transition UUID response field is not currently able to be implemented as of 2024-1-18. + * + * @requestField ?sceneName | String | Name of the scene + * @requestField ?sceneUuid | String | UUID of the scene * * @responseField transitionName | String | Name of the overridden scene transition, else `null` * @responseField transitionDuration | Number | Duration of the overridden scene transition, else `null` @@ -295,7 +325,7 @@ RequestResult RequestHandler::GetSceneSceneTransitionOverride(const Request &req { RequestStatus::RequestStatus statusCode; std::string comment; - OBSSourceAutoRelease scene = request.ValidateScene("sceneName", statusCode, comment); + OBSSourceAutoRelease scene = request.ValidateScene(statusCode, comment); if (!scene) return RequestResult::Error(statusCode, comment); @@ -317,9 +347,10 @@ RequestResult RequestHandler::GetSceneSceneTransitionOverride(const Request &req } /** - * Gets the scene transition overridden for a scene. + * Sets the scene transition overridden for a scene. * - * @requestField sceneName | String | Name of the scene + * @requestField ?sceneName | String | Name of the scene + * @requestField ?sceneUuid | String | UUID of the scene * @requestField ?transitionName | String | Name of the scene transition to use as override. Specify `null` to remove | Unchanged * @requestField ?transitionDuration | Number | Duration to use for any overridden transition. Specify `null` to remove | >= 50, <= 20000 | Unchanged * @@ -334,7 +365,7 @@ RequestResult RequestHandler::SetSceneSceneTransitionOverride(const Request &req { RequestStatus::RequestStatus statusCode; std::string comment; - OBSSourceAutoRelease scene = request.ValidateScene("sceneName", statusCode, comment); + OBSSourceAutoRelease scene = request.ValidateScene(statusCode, comment); if (!scene) return RequestResult::Error(statusCode, comment); diff --git a/src/requesthandler/RequestHandler_Sources.cpp b/src/requesthandler/RequestHandler_Sources.cpp index 58d91f513..459901ced 100644 --- a/src/requesthandler/RequestHandler_Sources.cpp +++ b/src/requesthandler/RequestHandler_Sources.cpp @@ -114,7 +114,8 @@ bool IsImageFormatValid(std::string format) * * **Compatible with inputs and scenes.** * - * @requestField sourceName | String | Name of the source to get the active state of + * @requestField ?sourceName | String | Name of the source to get the active state of + * @requestField ?sourceUuid | String | UUID of the source to get the active state of * * @responseField videoActive | Boolean | Whether the source is showing in Program * @responseField videoShowing | Boolean | Whether the source is showing in the UI (Preview, Projector, Properties) @@ -130,7 +131,7 @@ RequestResult RequestHandler::GetSourceActive(const Request &request) { RequestStatus::RequestStatus statusCode; std::string comment; - OBSSourceAutoRelease source = request.ValidateSource("sourceName", statusCode, comment); + OBSSourceAutoRelease source = request.ValidateSource("sourceName", "sourceUuid", statusCode, comment); if (!source) return RequestResult::Error(statusCode, comment); @@ -151,7 +152,8 @@ RequestResult RequestHandler::GetSourceActive(const Request &request) * * **Compatible with inputs and scenes.** * - * @requestField sourceName | String | Name of the source to take a screenshot of + * @requestField ?sourceName | String | Name of the source to take a screenshot of + * @requestField ?sourceUuid | String | UUID of the source to take a screenshot of * @requestField imageFormat | String | Image compression format to use. Use `GetVersion` to get compatible image formats * @requestField ?imageWidth | Number | Width to scale the screenshot to | >= 8, <= 4096 | Source value is used * @requestField ?imageHeight | Number | Height to scale the screenshot to | >= 8, <= 4096 | Source value is used @@ -170,7 +172,7 @@ RequestResult RequestHandler::GetSourceScreenshot(const Request &request) { RequestStatus::RequestStatus statusCode; std::string comment; - OBSSourceAutoRelease source = request.ValidateSource("sourceName", statusCode, comment); + OBSSourceAutoRelease source = request.ValidateSource("sourceName", "sourceUuid", statusCode, comment); if (!(source && request.ValidateString("imageFormat", statusCode, comment))) return RequestResult::Error(statusCode, comment); @@ -238,15 +240,14 @@ RequestResult RequestHandler::GetSourceScreenshot(const Request &request) * * **Compatible with inputs and scenes.** * - * @requestField sourceName | String | Name of the source to take a screenshot of + * @requestField ?sourceName | String | Name of the source to take a screenshot of + * @requestField ?sourceUuid | String | UUID of the source to take a screenshot of * @requestField imageFormat | String | Image compression format to use. Use `GetVersion` to get compatible image formats * @requestField imageFilePath | String | Path to save the screenshot file to. Eg. `C:\Users\user\Desktop\screenshot.png` * @requestField ?imageWidth | Number | Width to scale the screenshot to | >= 8, <= 4096 | Source value is used * @requestField ?imageHeight | Number | Height to scale the screenshot to | >= 8, <= 4096 | Source value is used * @requestField ?imageCompressionQuality | Number | Compression quality to use. 0 for high compression, 100 for uncompressed. -1 to use "default" (whatever that means, idk) | >= -1, <= 100 | -1 * - * @responseField imageData | String | Base64-encoded screenshot - * * @requestType SaveSourceScreenshot * @complexity 3 * @rpcVersion -1 @@ -258,7 +259,7 @@ RequestResult RequestHandler::SaveSourceScreenshot(const Request &request) { RequestStatus::RequestStatus statusCode; std::string comment; - OBSSourceAutoRelease source = request.ValidateSource("sourceName", statusCode, comment); + OBSSourceAutoRelease source = request.ValidateSource("sourceName", "sourceUuid", statusCode, comment); if (!(source && request.ValidateString("imageFormat", statusCode, comment) && request.ValidateString("imageFilePath", statusCode, comment))) return RequestResult::Error(statusCode, comment); @@ -321,7 +322,7 @@ RequestResult RequestHandler::GetSourcePrivateSettings(const Request &request) { RequestStatus::RequestStatus statusCode; std::string comment; - OBSSourceAutoRelease source = request.ValidateSource("sourceName", statusCode, comment); + OBSSourceAutoRelease source = request.ValidateSource("sourceName", "sourceUuid", statusCode, comment); if (!source) return RequestResult::Error(statusCode, comment); @@ -338,7 +339,7 @@ RequestResult RequestHandler::SetSourcePrivateSettings(const Request &request) { RequestStatus::RequestStatus statusCode; std::string comment; - OBSSourceAutoRelease source = request.ValidateSource("sourceName", statusCode, comment); + OBSSourceAutoRelease source = request.ValidateSource("sourceName", "sourceUuid", statusCode, comment); if (!source || !request.ValidateObject("sourceSettings", statusCode, comment, true)) return RequestResult::Error(statusCode, comment); diff --git a/src/requesthandler/RequestHandler_Stream.cpp b/src/requesthandler/RequestHandler_Stream.cpp index 1a0b6ee23..35936d0d9 100644 --- a/src/requesthandler/RequestHandler_Stream.cpp +++ b/src/requesthandler/RequestHandler_Stream.cpp @@ -44,12 +44,16 @@ RequestResult RequestHandler::GetStreamStatus(const Request &) uint64_t outputDuration = Utils::Obs::NumberHelper::GetOutputDuration(streamOutput); + float outputCongestion = obs_output_get_congestion(streamOutput); + if (std::isnan(outputCongestion)) // libobs does not handle NaN, so we're handling it here + outputCongestion = 0.0f; + json responseData; responseData["outputActive"] = obs_output_active(streamOutput); responseData["outputReconnecting"] = obs_output_reconnecting(streamOutput); responseData["outputTimecode"] = Utils::Obs::StringHelper::DurationToTimecode(outputDuration); responseData["outputDuration"] = outputDuration; - responseData["outputCongestion"] = obs_output_get_congestion(streamOutput); + responseData["outputCongestion"] = outputCongestion; 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); diff --git a/src/requesthandler/RequestHandler_Transitions.cpp b/src/requesthandler/RequestHandler_Transitions.cpp index 785cfbe8b..e2d87c5c5 100644 --- a/src/requesthandler/RequestHandler_Transitions.cpp +++ b/src/requesthandler/RequestHandler_Transitions.cpp @@ -46,6 +46,7 @@ RequestResult RequestHandler::GetTransitionKindList(const Request &) * Gets an array of all scene transitions in OBS. * * @responseField currentSceneTransitionName | String | Name of the current scene transition. Can be null + * @responseField currentSceneTransitionUuid | String | UUID of the current scene transition. Can be null * @responseField currentSceneTransitionKind | String | Kind of the current scene transition. Can be null * @responseField transitions | Array | Array of transitions * @@ -63,9 +64,11 @@ RequestResult RequestHandler::GetSceneTransitionList(const Request &) OBSSourceAutoRelease transition = obs_frontend_get_current_transition(); if (transition) { responseData["currentSceneTransitionName"] = obs_source_get_name(transition); + responseData["currentSceneTransitionUuid"] = obs_source_get_uuid(transition); responseData["currentSceneTransitionKind"] = obs_source_get_id(transition); } else { responseData["currentSceneTransitionName"] = nullptr; + responseData["currentSceneTransitionUuid"] = nullptr; responseData["currentSceneTransitionKind"] = nullptr; } @@ -78,6 +81,7 @@ RequestResult RequestHandler::GetSceneTransitionList(const Request &) * Gets information about the current scene transition. * * @responseField transitionName | String | Name of the transition + * @responseField transitionUuid | String | UUID of the transition * @responseField transitionKind | String | Kind of the transition * @responseField transitionFixed | Boolean | Whether the transition uses a fixed (unconfigurable) duration * @responseField transitionDuration | Number | Configured transition duration in milliseconds. `null` if transition is fixed @@ -100,6 +104,7 @@ RequestResult RequestHandler::GetCurrentSceneTransition(const Request &) json responseData; responseData["transitionName"] = obs_source_get_name(transition); + responseData["transitionUuid"] = obs_source_get_uuid(transition); responseData["transitionKind"] = obs_source_get_id(transition); if (obs_transition_fixed(transition)) { diff --git a/src/requesthandler/RequestHandler_Ui.cpp b/src/requesthandler/RequestHandler_Ui.cpp index aa3d0f1ee..29896bda2 100644 --- a/src/requesthandler/RequestHandler_Ui.cpp +++ b/src/requesthandler/RequestHandler_Ui.cpp @@ -82,7 +82,8 @@ RequestResult RequestHandler::SetStudioModeEnabled(const Request &request) /** * Opens the properties dialog of an input. * - * @requestField inputName | String | Name of the input to open the dialog of + * @requestField ?inputName | String | Name of the input to open the dialog of + * @requestField ?inputUuid | String | UUID of the input to open the dialog of * * @requestType OpenInputPropertiesDialog * @complexity 1 @@ -95,7 +96,7 @@ RequestResult RequestHandler::OpenInputPropertiesDialog(const Request &request) { RequestStatus::RequestStatus statusCode; std::string comment; - OBSSourceAutoRelease input = request.ValidateInput("inputName", statusCode, comment); + OBSSourceAutoRelease input = request.ValidateInput(statusCode, comment); if (!input) return RequestResult::Error(statusCode, comment); @@ -107,7 +108,8 @@ RequestResult RequestHandler::OpenInputPropertiesDialog(const Request &request) /** * Opens the filters dialog of an input. * - * @requestField inputName | String | Name of the input to open the dialog of + * @requestField ?inputName | String | Name of the input to open the dialog of + * @requestField ?inputUuid | String | UUID of the input to open the dialog of * * @requestType OpenInputFiltersDialog * @complexity 1 @@ -120,7 +122,7 @@ RequestResult RequestHandler::OpenInputFiltersDialog(const Request &request) { RequestStatus::RequestStatus statusCode; std::string comment; - OBSSourceAutoRelease input = request.ValidateInput("inputName", statusCode, comment); + OBSSourceAutoRelease input = request.ValidateInput(statusCode, comment); if (!input) return RequestResult::Error(statusCode, comment); @@ -132,7 +134,8 @@ RequestResult RequestHandler::OpenInputFiltersDialog(const Request &request) /** * Opens the interact dialog of an input. * - * @requestField inputName | String | Name of the input to open the dialog of + * @requestField ?inputName | String | Name of the input to open the dialog of + * @requestField ?inputUuid | String | UUID of the input to open the dialog of * * @requestType OpenInputInteractDialog * @complexity 1 @@ -145,7 +148,7 @@ RequestResult RequestHandler::OpenInputInteractDialog(const Request &request) { RequestStatus::RequestStatus statusCode; std::string comment; - OBSSourceAutoRelease input = request.ValidateInput("inputName", statusCode, comment); + OBSSourceAutoRelease input = request.ValidateInput(statusCode, comment); if (!input) return RequestResult::Error(statusCode, comment); @@ -262,7 +265,8 @@ RequestResult RequestHandler::OpenVideoMixProjector(const Request &request) * * Note: This request serves to provide feature parity with 4.x. It is very likely to be changed/deprecated in a future release. * - * @requestField sourceName | String | Name of the source to open a projector for + * @requestField ?sourceName | String | Name of the source to open a projector for + * @requestField ?sourceUuid | String | UUID of the source to open a projector for * @requestField ?monitorIndex | Number | Monitor index, use `GetMonitorList` to obtain index | None | -1: Opens projector in windowed mode * @requestField ?projectorGeometry | String | Size/Position data for a windowed projector, in Qt Base64 encoded format. Mutually exclusive with `monitorIndex` | N/A * @@ -277,7 +281,7 @@ RequestResult RequestHandler::OpenSourceProjector(const Request &request) { RequestStatus::RequestStatus statusCode; std::string comment; - OBSSourceAutoRelease source = request.ValidateSource("sourceName", statusCode, comment); + OBSSourceAutoRelease source = request.ValidateSource("sourceName", "sourceUuid", statusCode, comment); if (!source) return RequestResult::Error(statusCode, comment); diff --git a/src/requesthandler/rpc/Request.cpp b/src/requesthandler/rpc/Request.cpp index 1dc9bef12..d131e506b 100644 --- a/src/requesthandler/rpc/Request.cpp +++ b/src/requesthandler/rpc/Request.cpp @@ -211,28 +211,39 @@ bool Request::ValidateArray(const std::string &keyName, RequestStatus::RequestSt return true; } -obs_source_t *Request::ValidateSource(const std::string &keyName, RequestStatus::RequestStatus &statusCode, +obs_source_t *Request::ValidateSource(const std::string &nameKeyName, const std::string &uuidKeyName, RequestStatus::RequestStatus &statusCode, std::string &comment) const { - if (!ValidateString(keyName, statusCode, comment)) - return nullptr; - - std::string sourceName = RequestData[keyName]; + if (ValidateString(nameKeyName, statusCode, comment)) { + std::string sourceName = RequestData[nameKeyName]; + obs_source_t *ret = obs_get_source_by_name(sourceName.c_str()); + if (!ret) { + statusCode = RequestStatus::ResourceNotFound; + comment = std::string("No source was found by the name of `") + sourceName + "`."; + return nullptr; + } + return ret; + } - obs_source_t *ret = obs_get_source_by_name(sourceName.c_str()); - if (!ret) { - statusCode = RequestStatus::ResourceNotFound; - comment = std::string("No source was found by the name of `") + sourceName + "`."; - return nullptr; + if (ValidateString(uuidKeyName, statusCode, comment)) { + std::string sourceUuid = RequestData[uuidKeyName]; + obs_source_t *ret = obs_get_source_by_uuid(sourceUuid.c_str()); + if (!ret) { + statusCode = RequestStatus::ResourceNotFound; + comment = std::string("No source was found by the UUID of `") + sourceUuid + "`."; + return nullptr; + } + return ret; } - return ret; + statusCode = RequestStatus::MissingRequestField; + comment = std::string("Your request must contain at least one of the following fields: `") + nameKeyName + "` or `" + uuidKeyName + "`."; + return nullptr; } -obs_source_t *Request::ValidateScene(const std::string &keyName, RequestStatus::RequestStatus &statusCode, std::string &comment, - const ObsWebSocketSceneFilter filter) const +obs_source_t *Request::ValidateScene(RequestStatus::RequestStatus &statusCode, std::string &comment, const ObsWebSocketSceneFilter filter) const { - obs_source_t *ret = ValidateSource(keyName, statusCode, comment); + obs_source_t *ret = ValidateSource("sceneName", "sceneUuid", statusCode, comment); if (!ret) return nullptr; @@ -259,10 +270,9 @@ obs_source_t *Request::ValidateScene(const std::string &keyName, RequestStatus:: return ret; } -obs_scene_t *Request::ValidateScene2(const std::string &keyName, RequestStatus::RequestStatus &statusCode, std::string &comment, - const ObsWebSocketSceneFilter filter) const +obs_scene_t *Request::ValidateScene2(RequestStatus::RequestStatus &statusCode, std::string &comment, const ObsWebSocketSceneFilter filter) const { - OBSSourceAutoRelease sceneSource = ValidateSource(keyName, statusCode, comment); + OBSSourceAutoRelease sceneSource = ValidateSource("sceneName", "sceneUuid", statusCode, comment); if (!sceneSource) return nullptr; @@ -290,10 +300,9 @@ obs_scene_t *Request::ValidateScene2(const std::string &keyName, RequestStatus:: } } -obs_source_t *Request::ValidateInput(const std::string &keyName, RequestStatus::RequestStatus &statusCode, - std::string &comment) const +obs_source_t *Request::ValidateInput(RequestStatus::RequestStatus &statusCode, std::string &comment) const { - obs_source_t *ret = ValidateSource(keyName, statusCode, comment); + obs_source_t *ret = ValidateSource("inputName", "inputUuid", statusCode, comment); if (!ret) return nullptr; @@ -307,47 +316,44 @@ obs_source_t *Request::ValidateInput(const std::string &keyName, RequestStatus:: return ret; } -FilterPair Request::ValidateFilter(const std::string &sourceKeyName, const std::string &filterKeyName, - RequestStatus::RequestStatus &statusCode, std::string &comment) const +FilterPair Request::ValidateFilter(RequestStatus::RequestStatus &statusCode, std::string &comment) const { - obs_source_t *source = ValidateSource(sourceKeyName, statusCode, comment); + obs_source_t *source = ValidateSource("sourceName", "sourceUuid", statusCode, comment); if (!source) return FilterPair{source, nullptr}; - if (!ValidateString(filterKeyName, statusCode, comment)) + if (!ValidateString("filterName", statusCode, comment)) return FilterPair{source, nullptr}; - std::string filterName = RequestData[filterKeyName]; + std::string filterName = RequestData["filterName"]; obs_source_t *filter = obs_source_get_filter_by_name(source, filterName.c_str()); if (!filter) { + std::string sourceName = obs_source_get_name(source); statusCode = RequestStatus::ResourceNotFound; - comment = std::string("No filter was found in the source `") + RequestData[sourceKeyName].get() + - "` with the name `" + filterName + "`."; + comment = std::string("No filter was found in the source `") + sourceName + "` with the name `" + filterName + "`."; return FilterPair{source, nullptr}; } return FilterPair{source, filter}; } -obs_sceneitem_t *Request::ValidateSceneItem(const std::string &sceneKeyName, const std::string &sceneItemIdKeyName, - RequestStatus::RequestStatus &statusCode, std::string &comment, - const ObsWebSocketSceneFilter filter) const +obs_sceneitem_t *Request::ValidateSceneItem(RequestStatus::RequestStatus &statusCode, std::string &comment, const ObsWebSocketSceneFilter filter) const { - OBSSceneAutoRelease scene = ValidateScene2(sceneKeyName, statusCode, comment, filter); + OBSSceneAutoRelease scene = ValidateScene2(statusCode, comment, filter); if (!scene) return nullptr; - if (!ValidateNumber(sceneItemIdKeyName, statusCode, comment, 0)) + if (!ValidateNumber("sceneItemId", statusCode, comment, 0)) return nullptr; - int64_t sceneItemId = RequestData[sceneItemIdKeyName]; + int64_t sceneItemId = RequestData["sceneItemId"]; OBSSceneItem sceneItem = obs_scene_find_sceneitem_by_id(scene, sceneItemId); if (!sceneItem) { + std::string sceneName = obs_source_get_name(obs_scene_get_source(scene)); statusCode = RequestStatus::ResourceNotFound; - comment = std::string("No scene items were found in scene `") + RequestData[sceneKeyName].get() + - "` with the ID `" + std::to_string(sceneItemId) + "`."; + comment = std::string("No scene items were found in scene `") + sceneName + "` with the ID `" + std::to_string(sceneItemId) + "`."; return nullptr; } diff --git a/src/requesthandler/rpc/Request.h b/src/requesthandler/rpc/Request.h index 3ee1149a3..ef96e5bb5 100644 --- a/src/requesthandler/rpc/Request.h +++ b/src/requesthandler/rpc/Request.h @@ -64,21 +64,13 @@ struct Request { const bool allowEmpty = false) const; // All return values have incremented refcounts - obs_source_t *ValidateSource(const std::string &keyName, RequestStatus::RequestStatus &statusCode, - std::string &comment) const; - obs_source_t *ValidateScene(const std::string &keyName, RequestStatus::RequestStatus &statusCode, std::string &comment, - const ObsWebSocketSceneFilter filter = OBS_WEBSOCKET_SCENE_FILTER_SCENE_ONLY) const; - obs_scene_t *ValidateScene2(const std::string &keyName, RequestStatus::RequestStatus &statusCode, std::string &comment, - const ObsWebSocketSceneFilter filter = OBS_WEBSOCKET_SCENE_FILTER_SCENE_ONLY) const; - obs_source_t *ValidateInput(const std::string &keyName, RequestStatus::RequestStatus &statusCode, - std::string &comment) const; - FilterPair ValidateFilter(const std::string &sourceKeyName, const std::string &filterKeyName, - RequestStatus::RequestStatus &statusCode, std::string &comment) const; - obs_sceneitem_t *ValidateSceneItem(const std::string &sceneKeyName, const std::string &sceneItemIdKeyName, - RequestStatus::RequestStatus &statusCode, std::string &comment, - const ObsWebSocketSceneFilter filter = OBS_WEBSOCKET_SCENE_FILTER_SCENE_ONLY) const; - obs_output_t *ValidateOutput(const std::string &keyName, RequestStatus::RequestStatus &statusCode, - std::string &comment) const; + obs_source_t *ValidateSource(const std::string &nameKeyName, const std::string &uuidKeyName, RequestStatus::RequestStatus &statusCode, std::string &comment) const; + obs_source_t *ValidateScene(RequestStatus::RequestStatus &statusCode, std::string &comment, const ObsWebSocketSceneFilter filter = OBS_WEBSOCKET_SCENE_FILTER_SCENE_ONLY) const; + obs_scene_t *ValidateScene2(RequestStatus::RequestStatus &statusCode, std::string &comment, const ObsWebSocketSceneFilter filter = OBS_WEBSOCKET_SCENE_FILTER_SCENE_ONLY) const; + obs_source_t *ValidateInput(RequestStatus::RequestStatus &statusCode, std::string &comment) const; + FilterPair ValidateFilter(RequestStatus::RequestStatus &statusCode, std::string &comment) const; + obs_sceneitem_t *ValidateSceneItem(RequestStatus::RequestStatus &statusCode, std::string &comment, const ObsWebSocketSceneFilter filter = OBS_WEBSOCKET_SCENE_FILTER_SCENE_ONLY) const; + obs_output_t *ValidateOutput(const std::string &keyName, RequestStatus::RequestStatus &statusCode, std::string &comment) const; std::string RequestType; bool HasRequestData; diff --git a/src/requesthandler/types/RequestStatus.h b/src/requesthandler/types/RequestStatus.h index 604863c84..03c8ff4c5 100644 --- a/src/requesthandler/types/RequestStatus.h +++ b/src/requesthandler/types/RequestStatus.h @@ -103,6 +103,19 @@ namespace RequestStatus { * @api enums */ UnsupportedRequestBatchExecutionType = 206, + /** + * The server is not ready to handle the request. + * + * Note: This usually occurs during OBS scene collection change or exit. Requests may be tried again after a delay if this code is given. + * + * @enumIdentifier NotReady + * @enumValue 207 + * @enumType RequestStatus + * @rpcVersion -1 + * @initialVersion 5.3.0 + * @api enums + */ + NotReady = 207, /** * A required request field is missing. diff --git a/src/utils/Crypto.cpp b/src/utils/Crypto.cpp index 4e30e8305..b594be6c7 100644 --- a/src/utils/Crypto.cpp +++ b/src/utils/Crypto.cpp @@ -22,7 +22,7 @@ with this program. If not, see #include #include "Crypto.h" -#include "../plugin-macros.generated.h" +#include "plugin-macros.generated.h" static const char allowedChars[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"; static const int allowedCharsCount = static_cast(sizeof(allowedChars) - 1); diff --git a/src/utils/Json.cpp b/src/utils/Json.cpp index d61c43750..81fa52af1 100644 --- a/src/utils/Json.cpp +++ b/src/utils/Json.cpp @@ -19,7 +19,7 @@ with this program. If not, see #include "Json.h" #include "Platform.h" -#include "../plugin-macros.generated.h" +#include "plugin-macros.generated.h" bool Utils::Json::JsonArrayIsValidObsArray(const json &j) { diff --git a/src/utils/Obs.cpp b/src/utils/Obs.cpp index 131e8d229..d17b253a5 100644 --- a/src/utils/Obs.cpp +++ b/src/utils/Obs.cpp @@ -18,4 +18,4 @@ with this program. If not, see */ #include "Obs.h" -#include "../plugin-macros.generated.h" +#include "plugin-macros.generated.h" diff --git a/src/utils/Obs.h b/src/utils/Obs.h index 0e646c835..9110a6ccb 100644 --- a/src/utils/Obs.h +++ b/src/utils/Obs.h @@ -297,7 +297,7 @@ namespace Utils { } namespace SearchHelper { - obs_hotkey_t *GetHotkeyByName(std::string name); + obs_hotkey_t *GetHotkeyByName(std::string name, std::string context); obs_source_t *GetSceneTransitionByName(std::string name); // Increments source ref. Use OBSSourceAutoRelease obs_sceneitem_t *GetSceneItemByName(obs_scene_t *scene, std::string name, int offset = 0); // Increments ref. Use OBSSceneItemAutoRelease diff --git a/src/utils/Obs_ActionHelper.cpp b/src/utils/Obs_ActionHelper.cpp index 4cdfb71f4..e3615060f 100644 --- a/src/utils/Obs_ActionHelper.cpp +++ b/src/utils/Obs_ActionHelper.cpp @@ -17,7 +17,7 @@ with this program. If not, see */ #include "Obs.h" -#include "../plugin-macros.generated.h" +#include "plugin-macros.generated.h" struct CreateSceneItemData { obs_source_t *source; // In diff --git a/src/utils/Obs_ArrayHelper.cpp b/src/utils/Obs_ArrayHelper.cpp index 1a48e419e..48a1c499c 100644 --- a/src/utils/Obs_ArrayHelper.cpp +++ b/src/utils/Obs_ArrayHelper.cpp @@ -20,7 +20,7 @@ with this program. If not, see #include #include "Obs.h" -#include "../plugin-macros.generated.h" +#include "plugin-macros.generated.h" static std::vector ConvertStringArray(char **array) { @@ -96,6 +96,7 @@ std::vector Utils::Obs::ArrayHelper::GetSceneList() json sceneJson; sceneJson["sceneName"] = obs_source_get_name(scene); + sceneJson["sceneUuid"] = obs_source_get_uuid(scene); sceneJson["sceneIndex"] = sceneList.sources.num - i - 1; ret.push_back(sceneJson); @@ -150,6 +151,7 @@ std::vector Utils::Obs::ArrayHelper::GetSceneItemList(obs_scene_t *scene, item["sceneItemBlendMode"] = obs_sceneitem_get_blending_mode(sceneItem); OBSSource itemSource = obs_sceneitem_get_source(sceneItem); item["sourceName"] = obs_source_get_name(itemSource); + item["sourceUuid"] = obs_source_get_uuid(itemSource); item["sourceType"] = obs_source_get_type(itemSource); if (obs_source_get_type(itemSource) == OBS_SOURCE_TYPE_INPUT) item["inputKind"] = obs_source_get_id(itemSource); @@ -195,6 +197,7 @@ std::vector Utils::Obs::ArrayHelper::GetInputList(std::string inputKind) json inputJson; inputJson["inputName"] = obs_source_get_name(input); + inputJson["inputUuid"] = obs_source_get_uuid(input); inputJson["inputKind"] = inputKind; inputJson["unversionedInputKind"] = obs_source_get_unversioned_id(input); @@ -281,6 +284,7 @@ std::vector Utils::Obs::ArrayHelper::GetSceneTransitionList() obs_source_t *transition = transitionList.sources.array[i]; json transitionJson; transitionJson["transitionName"] = obs_source_get_name(transition); + transitionJson["transitionUuid"] = obs_source_get_uuid(transition); transitionJson["transitionKind"] = obs_source_get_id(transition); transitionJson["transitionFixed"] = obs_transition_fixed(transition); transitionJson["transitionConfigurable"] = obs_source_configurable(transition); diff --git a/src/utils/Obs_NumberHelper.cpp b/src/utils/Obs_NumberHelper.cpp index 2246707ee..74b032be8 100644 --- a/src/utils/Obs_NumberHelper.cpp +++ b/src/utils/Obs_NumberHelper.cpp @@ -21,7 +21,7 @@ with this program. If not, see #include #include "Obs.h" -#include "../plugin-macros.generated.h" +#include "plugin-macros.generated.h" uint64_t Utils::Obs::NumberHelper::GetOutputDuration(obs_output_t *output) { diff --git a/src/utils/Obs_ObjectHelper.cpp b/src/utils/Obs_ObjectHelper.cpp index 007be63ba..6679c2c12 100644 --- a/src/utils/Obs_ObjectHelper.cpp +++ b/src/utils/Obs_ObjectHelper.cpp @@ -21,7 +21,7 @@ with this program. If not, see #include "Obs.h" #include "../obs-websocket.h" -#include "../plugin-macros.generated.h" +#include "plugin-macros.generated.h" json Utils::Obs::ObjectHelper::GetStats() { diff --git a/src/utils/Obs_SearchHelper.cpp b/src/utils/Obs_SearchHelper.cpp index 7895f0278..7b98512af 100644 --- a/src/utils/Obs_SearchHelper.cpp +++ b/src/utils/Obs_SearchHelper.cpp @@ -17,9 +17,9 @@ with this program. If not, see */ #include "Obs.h" -#include "../plugin-macros.generated.h" +#include "plugin-macros.generated.h" -obs_hotkey_t *Utils::Obs::SearchHelper::GetHotkeyByName(std::string name) +obs_hotkey_t *Utils::Obs::SearchHelper::GetHotkeyByName(std::string name, std::string context) { if (name.empty()) return nullptr; @@ -27,8 +27,47 @@ obs_hotkey_t *Utils::Obs::SearchHelper::GetHotkeyByName(std::string name) auto hotkeys = ArrayHelper::GetHotkeyList(); for (auto hotkey : hotkeys) { - if (obs_hotkey_get_name(hotkey) == name) + if (obs_hotkey_get_name(hotkey) != name) + continue; + + if (context.empty()) return hotkey; + + auto type = obs_hotkey_get_registerer_type(hotkey); + if (type == OBS_HOTKEY_REGISTERER_SOURCE) { + OBSSourceAutoRelease source = obs_weak_source_get_source((obs_weak_source_t *)obs_hotkey_get_registerer(hotkey)); + if (!source) + continue; + + if (context != obs_source_get_name(source)) + continue; + + } else if (type == OBS_HOTKEY_REGISTERER_OUTPUT) { + OBSOutputAutoRelease output = obs_weak_output_get_output((obs_weak_output_t *)obs_hotkey_get_registerer(hotkey)); + if (!output) + continue; + + if (context != obs_output_get_name(output)) + continue; + + } else if (type == OBS_HOTKEY_REGISTERER_ENCODER) { + OBSEncoderAutoRelease encoder = obs_weak_encoder_get_encoder((obs_weak_encoder_t *)obs_hotkey_get_registerer(hotkey)); + if (!encoder) + continue; + + if (context != obs_encoder_get_name(encoder)) + continue; + + } else if (type == OBS_HOTKEY_REGISTERER_SERVICE) { + OBSServiceAutoRelease service = obs_weak_service_get_service((obs_weak_service_t *)obs_hotkey_get_registerer(hotkey)); + if (!service) + continue; + + if (context != obs_service_get_name(service)) + continue; + + } + return hotkey; } return nullptr; diff --git a/src/utils/Obs_StringHelper.cpp b/src/utils/Obs_StringHelper.cpp index cc9e1145c..fc541ec68 100644 --- a/src/utils/Obs_StringHelper.cpp +++ b/src/utils/Obs_StringHelper.cpp @@ -20,8 +20,10 @@ with this program. If not, see #include #include +#include + #include "Obs.h" -#include "../plugin-macros.generated.h" +#include "plugin-macros.generated.h" #define CASE(x) \ case x: \ @@ -42,33 +44,29 @@ std::string Utils::Obs::StringHelper::GetObsVersion() std::string Utils::Obs::StringHelper::GetCurrentSceneCollection() { - char *sceneCollectionName = obs_frontend_get_current_scene_collection(); - std::string ret = sceneCollectionName; - bfree(sceneCollectionName); + BPtr sceneCollectionName = obs_frontend_get_current_scene_collection(); + std::string ret = sceneCollectionName.Get(); return ret; } std::string Utils::Obs::StringHelper::GetCurrentProfile() { - char *profileName = obs_frontend_get_current_profile(); - std::string ret = profileName; - bfree(profileName); + BPtr profileName = obs_frontend_get_current_profile(); + std::string ret = profileName.Get(); return ret; } std::string Utils::Obs::StringHelper::GetCurrentProfilePath() { - char *profilePath = obs_frontend_get_current_profile_path(); - std::string ret = profilePath; - bfree(profilePath); + BPtr profilePath = obs_frontend_get_current_profile_path(); + std::string ret = profilePath.Get(); return ret; } std::string Utils::Obs::StringHelper::GetCurrentRecordOutputPath() { - char *recordOutputPath = obs_frontend_get_current_record_output_path(); - std::string ret = recordOutputPath; - bfree(recordOutputPath); + BPtr recordOutputPath = obs_frontend_get_current_record_output_path(); + std::string ret = recordOutputPath.Get(); return ret; } @@ -94,17 +92,15 @@ std::string Utils::Obs::StringHelper::GetLastRecordFileName() std::string Utils::Obs::StringHelper::GetLastReplayBufferFileName() { - char *replayBufferPath = obs_frontend_get_last_replay(); - std::string ret = replayBufferPath; - bfree(replayBufferPath); + BPtr replayBufferPath = obs_frontend_get_last_replay(); + std::string ret = replayBufferPath.Get(); return ret; } std::string Utils::Obs::StringHelper::GetLastScreenshotFileName() { - char *screenshotPath = obs_frontend_get_last_screenshot(); - std::string ret = screenshotPath; - bfree(screenshotPath); + BPtr screenshotPath = obs_frontend_get_last_screenshot(); + std::string ret = screenshotPath.Get(); return ret; } diff --git a/src/utils/Obs_VolumeMeter.cpp b/src/utils/Obs_VolumeMeter.cpp index 52eae6670..0aa718b4d 100644 --- a/src/utils/Obs_VolumeMeter.cpp +++ b/src/utils/Obs_VolumeMeter.cpp @@ -93,6 +93,7 @@ json Utils::Obs::VolumeMeter::Meter::GetMeterData() l.unlock(); ret["inputName"] = obs_source_get_name(input); + ret["inputUuid"] = obs_source_get_uuid(input); ret["inputLevelsMul"] = levels; return ret; diff --git a/src/utils/Platform.cpp b/src/utils/Platform.cpp index 0e9defd5e..d8920c233 100644 --- a/src/utils/Platform.cpp +++ b/src/utils/Platform.cpp @@ -25,7 +25,7 @@ with this program. If not, see #include #include "Platform.h" -#include "../plugin-macros.generated.h" +#include "plugin-macros.generated.h" std::string Utils::Platform::GetLocalAddress() { @@ -116,11 +116,12 @@ void Utils::Platform::SendTrayNotification(QSystemTrayIcon::MessageIcon icon, QS obs_queue_task( OBS_TASK_UI, [](void *param) { - void *systemTrayPtr = obs_frontend_get_system_tray(); - auto systemTray = static_cast(systemTrayPtr); - auto notification = static_cast(param); - systemTray->showMessage(notification->title, notification->body, notification->icon); + void *systemTrayPtr = obs_frontend_get_system_tray(); + if (systemTrayPtr) { + auto systemTray = static_cast(systemTrayPtr); + systemTray->showMessage(notification->title, notification->body, notification->icon); + } delete notification; }, (void *)notification, false); diff --git a/src/websocketserver/WebSocketServer.cpp b/src/websocketserver/WebSocketServer.cpp index 605ec3076..fdea4e801 100644 --- a/src/websocketserver/WebSocketServer.cpp +++ b/src/websocketserver/WebSocketServer.cpp @@ -31,7 +31,7 @@ with this program. If not, see #include "../utils/Platform.h" #include "../utils/Compat.h" -WebSocketServer::WebSocketServer() : QObject(nullptr), _sessions() +WebSocketServer::WebSocketServer() : QObject(nullptr) { _server.get_alog().clear_channels(websocketpp::log::alevel::all); _server.get_elog().clear_channels(websocketpp::log::elevel::all); @@ -49,14 +49,21 @@ WebSocketServer::WebSocketServer() : QObject(nullptr), _sessions() websocketpp::lib::placeholders::_2)); auto eventHandler = GetEventHandler(); - eventHandler->SetBroadcastCallback(std::bind(&WebSocketServer::BroadcastEvent, this, std::placeholders::_1, - std::placeholders::_2, std::placeholders::_3, std::placeholders::_4)); - - eventHandler->SetObsLoadedCallback(std::bind(&WebSocketServer::onObsLoaded, this)); + if (eventHandler) { + eventHandler->SetBroadcastCallback(std::bind(&WebSocketServer::BroadcastEvent, this, std::placeholders::_1, + std::placeholders::_2, std::placeholders::_3, std::placeholders::_4)); + eventHandler->SetObsReadyCallback(std::bind(&WebSocketServer::onObsReady, this, std::placeholders::_1)); + } } WebSocketServer::~WebSocketServer() { + auto eventHandler = GetEventHandler(); + if (eventHandler) { + eventHandler->SetObsReadyCallback(nullptr); + eventHandler->SetBroadcastCallback(nullptr); + } + if (_server.is_listening()) Stop(); } @@ -113,6 +120,10 @@ void WebSocketServer::Start() } else { blog(LOG_INFO, "[WebSocketServer::Start] Not locked to IPv4 bindings"); _server.listen(conf->ServerPort, errorCode); + if (errorCode && errorCode == websocketpp::lib::asio::error::address_family_not_supported) { + blog(LOG_INFO, "[WebSocketServer::Start] IPv6 address family not supported, binding only to IPv4"); + _server.listen(websocketpp::lib::asio::ip::tcp::v4(), conf->ServerPort, errorCode); + } } if (errorCode) { @@ -158,9 +169,8 @@ void WebSocketServer::Stop() _threadPool.waitForDone(); // This can delay the thread that it is running on. Bad but kinda required. - while (_sessions.size() > 0) { + while (_sessions.size() > 0) std::this_thread::sleep_for(std::chrono::milliseconds(10)); - } _serverThread.join(); @@ -205,18 +215,9 @@ std::vector WebSocketServer::GetWebSocke return webSocketSessions; } -void WebSocketServer::onObsLoaded() +void WebSocketServer::onObsReady(bool ready) { - auto conf = GetConfig(); - if (!conf) { - blog(LOG_ERROR, "[WebSocketServer::onObsLoaded] Unable to retreive config!"); - return; - } - - if (conf->ServerEnabled) { - blog(LOG_INFO, "[WebSocketServer::onObsLoaded] WebSocket server is enabled, starting..."); - Start(); - } + _obsReady = ready; } bool WebSocketServer::onValidate(websocketpp::connection_hdl hdl) @@ -266,7 +267,7 @@ void WebSocketServer::onOpen(websocketpp::connection_hdl hdl) json helloMessageData; helloMessageData["obsWebSocketVersion"] = OBS_WEBSOCKET_VERSION; helloMessageData["rpcVersion"] = OBS_WEBSOCKET_RPC_VERSION; - if (conf->AuthRequired) { + if (session->AuthenticationRequired()) { session->SetSecret(_authenticationSecret); std::string sessionChallenge = Utils::Crypto::GenerateSalt(); session->SetChallenge(sessionChallenge); diff --git a/src/websocketserver/WebSocketServer.h b/src/websocketserver/WebSocketServer.h index 651ee9b38..a0d35edd0 100644 --- a/src/websocketserver/WebSocketServer.h +++ b/src/websocketserver/WebSocketServer.h @@ -32,7 +32,7 @@ with this program. If not, see #include "types/WebSocketOpCode.h" #include "../utils/Json.h" #include "../requesthandler/rpc/Request.h" -#include "../plugin-macros.generated.h" +#include "plugin-macros.generated.h" class WebSocketServer : QObject { Q_OBJECT @@ -77,7 +77,7 @@ class WebSocketServer : QObject { void ServerRunner(); - void onObsLoaded(); + void onObsReady(bool loaded); bool onValidate(websocketpp::connection_hdl hdl); void onOpen(websocketpp::connection_hdl hdl); void onClose(websocketpp::connection_hdl hdl); @@ -96,4 +96,6 @@ class WebSocketServer : QObject { std::mutex _sessionMutex; std::map> _sessions; + + std::atomic _obsReady = false; }; diff --git a/src/websocketserver/WebSocketServer_Protocol.cpp b/src/websocketserver/WebSocketServer_Protocol.cpp index 2dec4d7e0..8d7d7e710 100644 --- a/src/websocketserver/WebSocketServer_Protocol.cpp +++ b/src/websocketserver/WebSocketServer_Protocol.cpp @@ -82,7 +82,7 @@ void WebSocketServer::ProcessMessage(SessionPtr session, WebSocketServer::Proces } // Only `Identify` is allowed when not identified - if (!session->IsIdentified() && opCode != 1) { + if (!session->IsIdentified() && opCode != WebSocketOpCode::Identify) { ret.closeCode = WebSocketCloseCode::NotIdentified; ret.closeReason = "You attempted to send a non-Identify message while not identified."; return; @@ -104,6 +104,11 @@ void WebSocketServer::ProcessMessage(SessionPtr session, WebSocketServer::Proces "Your payload's data is missing an `authentication` string, however authentication is required."; return; } + if (!payloadData["authentication"].is_string()) { + ret.closeCode = WebSocketCloseCode::AuthenticationFailed; + ret.closeReason = "Your `authentication` field is not a string."; + return; + } if (!Utils::Crypto::CheckAuthenticationString(session->Secret(), session->Challenge(), payloadData["authentication"])) { auto conf = GetConfig(); @@ -141,9 +146,8 @@ void WebSocketServer::ProcessMessage(SessionPtr session, WebSocketServer::Proces session->SetRpcVersion(requestedRpcVersion); SetSessionParameters(session, ret, payloadData); - if (ret.closeCode != WebSocketCloseCode::DontClose) { + if (ret.closeCode != WebSocketCloseCode::DontClose) return; - } // Increment refs for event subscriptions auto eventHandler = GetEventHandler(); @@ -173,9 +177,8 @@ void WebSocketServer::ProcessMessage(SessionPtr session, WebSocketServer::Proces eventHandler->ProcessUnsubscription(session->EventSubscriptions()); SetSessionParameters(session, ret, payloadData); - if (ret.closeCode != WebSocketCloseCode::DontClose) { + if (ret.closeCode != WebSocketCloseCode::DontClose) return; - } // Increment refs for new subscriptions eventHandler->ProcessSubscription(session->EventSubscriptions()); @@ -204,13 +207,17 @@ void WebSocketServer::ProcessMessage(SessionPtr session, WebSocketServer::Proces return; } - RequestHandler requestHandler(session); - std::string requestType = payloadData["requestType"]; - json requestData = payloadData["requestData"]; - Request request(requestType, requestData); + RequestResult requestResult; + if (_obsReady) { + json requestData = payloadData["requestData"]; + Request request(requestType, requestData); - RequestResult requestResult = requestHandler.ProcessRequest(request); + RequestHandler requestHandler(session); + requestResult = requestHandler.ProcessRequest(request); + } else { + requestResult = RequestResult::Error(RequestStatus::NotReady, "OBS is not ready to perform the request."); + } json resultPayloadData; resultPayloadData["requestType"] = requestType; @@ -298,22 +305,34 @@ void WebSocketServer::ProcessMessage(SessionPtr session, WebSocketServer::Proces } std::vector requests = payloadData["requests"]; + std::vector resultsVector; + if (_obsReady) { + std::vector requestsVector; + for (auto &requestJson : requests) { + if (!requestJson["requestType"].is_string()) + requestJson["requestType"] = + ""; // Workaround for what would otherwise be extensive additional logic for a rare edge case + std::string requestType = requestJson["requestType"]; + json requestData = requestJson["requestData"]; + json inputVariables = requestJson["inputVariables"]; + json outputVariables = requestJson["outputVariables"]; + requestsVector.emplace_back(requestType, requestData, executionType, inputVariables, + outputVariables); + } - std::vector requestsVector; - for (auto &requestJson : requests) { - if (!requestJson["requestType"].is_string()) - requestJson["requestType"] = - ""; // Workaround for what would otherwise be extensive additional logic for a rare edge case - std::string requestType = requestJson["requestType"]; - json requestData = requestJson["requestData"]; - json inputVariables = requestJson["inputVariables"]; - json outputVariables = requestJson["outputVariables"]; - requestsVector.emplace_back(requestType, requestData, executionType, inputVariables, outputVariables); + resultsVector = RequestBatchHandler::ProcessRequestBatch( + _threadPool, session, executionType, requestsVector, payloadData["variables"], haltOnFailure); + } else { + // I lowkey hate this, but whatever + if (haltOnFailure) { + resultsVector.emplace_back(RequestStatus::NotReady, "OBS is not ready to perform the request."); + } else { + for (size_t i = 0; i < requests.size(); i++) + resultsVector.emplace_back(RequestStatus::NotReady, + "OBS is not ready to perform the request."); + } } - auto resultsVector = RequestBatchHandler::ProcessRequestBatch(_threadPool, session, executionType, requestsVector, - payloadData["variables"], haltOnFailure); - size_t i = 0; std::vector results; for (auto &requestResult : resultsVector) { @@ -337,7 +356,7 @@ void WebSocketServer::ProcessMessage(SessionPtr session, WebSocketServer::Proces void WebSocketServer::BroadcastEvent(uint64_t requiredIntent, const std::string &eventType, const json &eventData, uint8_t rpcVersion) { - if (!_server.is_listening()) + if (!_server.is_listening() || !_obsReady) return; _threadPool.start(Utils::Compat::CreateFunctionRunnable([=]() { @@ -356,19 +375,16 @@ void WebSocketServer::BroadcastEvent(uint64_t requiredIntent, const std::string // Recurse connected sessions and send the event to suitable sessions. std::unique_lock lock(_sessionMutex); for (auto &it : _sessions) { - if (!it.second->IsIdentified()) { + if (!it.second->IsIdentified()) continue; - } - if (rpcVersion && it.second->RpcVersion() != rpcVersion) { + if (rpcVersion && it.second->RpcVersion() != rpcVersion) continue; - } if ((it.second->EventSubscriptions() & requiredIntent) != 0) { websocketpp::lib::error_code errorCode; switch (it.second->Encoding()) { case WebSocketEncoding::Json: - if (messageJson.empty()) { + if (messageJson.empty()) messageJson = eventMessage.dump(); - } _server.send((websocketpp::connection_hdl)it.first, messageJson, websocketpp::frame::opcode::text, errorCode); it.second->IncrementOutgoingMessages(); diff --git a/src/websocketserver/rpc/WebSocketSession.cpp b/src/websocketserver/rpc/WebSocketSession.cpp deleted file mode 100644 index e5e103140..000000000 --- a/src/websocketserver/rpc/WebSocketSession.cpp +++ /dev/null @@ -1,153 +0,0 @@ -/* -obs-websocket -Copyright (C) 2016-2021 Stephane Lepin -Copyright (C) 2020-2021 Kyle Manning - -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License along -with this program. If not, see -*/ - -#include "WebSocketSession.h" -#include "../../eventhandler/types/EventSubscription.h" - -WebSocketSession::WebSocketSession() - : _remoteAddress(""), - _connectedAt(0), - _incomingMessages(0), - _outgoingMessages(0), - _encoding(0), - _challenge(""), - _rpcVersion(OBS_WEBSOCKET_RPC_VERSION), - _isIdentified(false), - _eventSubscriptions(EventSubscription::All) -{ -} - -std::string WebSocketSession::RemoteAddress() -{ - std::lock_guard lock(_remoteAddressMutex); - std::string ret(_remoteAddress); - return ret; -} - -void WebSocketSession::SetRemoteAddress(std::string address) -{ - std::lock_guard lock(_remoteAddressMutex); - _remoteAddress = address; -} - -uint64_t WebSocketSession::ConnectedAt() -{ - return _connectedAt.load(); -} - -void WebSocketSession::SetConnectedAt(uint64_t at) -{ - _connectedAt.store(at); -} - -uint64_t WebSocketSession::IncomingMessages() -{ - return _incomingMessages.load(); -} - -void WebSocketSession::IncrementIncomingMessages() -{ - _incomingMessages++; -} - -uint64_t WebSocketSession::OutgoingMessages() -{ - return _outgoingMessages.load(); -} - -void WebSocketSession::IncrementOutgoingMessages() -{ - _outgoingMessages++; -} - -uint8_t WebSocketSession::Encoding() -{ - return _encoding.load(); -} - -void WebSocketSession::SetEncoding(uint8_t encoding) -{ - _encoding.store(encoding); -} - -bool WebSocketSession::AuthenticationRequired() -{ - return _authenticationRequired.load(); -} - -void WebSocketSession::SetAuthenticationRequired(bool required) -{ - _authenticationRequired.store(required); -} - -std::string WebSocketSession::Secret() -{ - std::lock_guard lock(_secretMutex); - std::string ret(_secret); - return ret; -} - -void WebSocketSession::SetSecret(std::string secret) -{ - std::lock_guard lock(_secretMutex); - _secret = secret; -} - -std::string WebSocketSession::Challenge() -{ - std::lock_guard lock(_challengeMutex); - std::string ret(_challenge); - return ret; -} - -void WebSocketSession::SetChallenge(std::string challengeString) -{ - std::lock_guard lock(_challengeMutex); - _challenge = challengeString; -} - -uint8_t WebSocketSession::RpcVersion() -{ - return _rpcVersion.load(); -} - -void WebSocketSession::SetRpcVersion(uint8_t version) -{ - _rpcVersion.store(version); -} - -bool WebSocketSession::IsIdentified() -{ - return _isIdentified.load(); -} - -void WebSocketSession::SetIsIdentified(bool identified) -{ - _isIdentified.store(identified); -} - -uint64_t WebSocketSession::EventSubscriptions() -{ - return _eventSubscriptions.load(); -} - -void WebSocketSession::SetEventSubscriptions(uint64_t subscriptions) -{ - _eventSubscriptions.store(subscriptions); -} diff --git a/src/websocketserver/rpc/WebSocketSession.h b/src/websocketserver/rpc/WebSocketSession.h index c3160286c..8e328641f 100644 --- a/src/websocketserver/rpc/WebSocketSession.h +++ b/src/websocketserver/rpc/WebSocketSession.h @@ -24,63 +24,86 @@ with this program. If not, see #include #include -#include "../../plugin-macros.generated.h" +#include "../../eventhandler/types/EventSubscription.h" +#include "plugin-macros.generated.h" class WebSocketSession; typedef std::shared_ptr SessionPtr; class WebSocketSession { public: - WebSocketSession(); - - std::string RemoteAddress(); - void SetRemoteAddress(std::string address); - - uint64_t ConnectedAt(); - void SetConnectedAt(uint64_t at); - - uint64_t IncomingMessages(); - void IncrementIncomingMessages(); - - uint64_t OutgoingMessages(); - void IncrementOutgoingMessages(); - - uint8_t Encoding(); - void SetEncoding(uint8_t encoding); - - bool AuthenticationRequired(); - void SetAuthenticationRequired(bool required); - - std::string Secret(); - void SetSecret(std::string secret); - - std::string Challenge(); - void SetChallenge(std::string challenge); - - uint8_t RpcVersion(); - void SetRpcVersion(uint8_t version); - - bool IsIdentified(); - void SetIsIdentified(bool identified); - - uint64_t EventSubscriptions(); - void SetEventSubscriptions(uint64_t subscriptions); + inline std::string RemoteAddress() + { + std::lock_guard lock(_remoteAddressMutex); + return _remoteAddress; + } + inline void SetRemoteAddress(std::string address) + { + std::lock_guard lock(_remoteAddressMutex); + _remoteAddress = address; + } + + inline uint64_t ConnectedAt() { return _connectedAt; } + inline void SetConnectedAt(uint64_t at) { _connectedAt = at; } + + inline uint64_t IncomingMessages() { return _incomingMessages; } + inline void IncrementIncomingMessages() { _incomingMessages++; } + + inline uint64_t OutgoingMessages() { return _outgoingMessages; } + inline void IncrementOutgoingMessages() { _outgoingMessages++; } + + inline uint8_t Encoding() { return _encoding; } + inline void SetEncoding(uint8_t encoding) { _encoding = encoding; } + + inline bool AuthenticationRequired() { return _authenticationRequired; } + inline void SetAuthenticationRequired(bool required) { _authenticationRequired = required; } + + inline std::string Secret() + { + std::lock_guard lock(_secretMutex); + return _secret; + } + inline void SetSecret(std::string secret) + { + std::lock_guard lock(_secretMutex); + _secret = secret; + } + + inline std::string Challenge() + { + std::lock_guard lock(_challengeMutex); + return _challenge; + } + inline void SetChallenge(std::string challenge) + { + std::lock_guard lock(_challengeMutex); + _challenge = challenge; + } + + inline uint8_t RpcVersion() { return _rpcVersion; } + inline void SetRpcVersion(uint8_t version) { _rpcVersion = version; } + + inline bool IsIdentified() { return _isIdentified; } + inline void SetIsIdentified(bool identified) { _isIdentified = identified; } + + inline uint64_t EventSubscriptions() { return _eventSubscriptions; } + inline void SetEventSubscriptions(uint64_t subscriptions) { _eventSubscriptions = subscriptions; } std::mutex OperationMutex; private: std::mutex _remoteAddressMutex; std::string _remoteAddress; - std::atomic _connectedAt; - std::atomic _incomingMessages; - std::atomic _outgoingMessages; - std::atomic _encoding; - std::atomic _authenticationRequired; + std::atomic _connectedAt = 0; + std::atomic _incomingMessages = 0; + std::atomic _outgoingMessages = 0; + std::atomic _encoding = 0; + std::atomic _authenticationRequired = false; std::mutex _secretMutex; std::string _secret; std::mutex _challengeMutex; std::string _challenge; - std::atomic _rpcVersion; - std::atomic _isIdentified; - std::atomic _eventSubscriptions; + std::atomic _rpcVersion = OBS_WEBSOCKET_RPC_VERSION; + std::atomic _isIdentified = false; + std::atomic _eventSubscriptions = EventSubscription::All; };