Compare commits

...

171 Commits

Author SHA1 Message Date
faf0866f1b cmake: Downgrade deprecation error for MSVC compilations
Error has already been downgraded for Clang, AppleClang, and GCC.
2024-08-01 14:24:00 -07:00
228afd3405 cmake: Downgrade deprecation error for GCC compilations
Error has already been downgraded for Clang and AppleClang, not doing
so for GCC was an oversight.
2024-08-01 10:26:50 -07:00
0548c7798a base: Update version to 5.5.2
Bug Fixes:
- Fix an issue where the virtualcam requests would report that the
virtualcam is not available.
- Fix an issue with the config migration where the migrated settings
were not being persisted to disk.
2024-07-18 12:45:53 -07:00
6c9fd55c63 config: Always write config when migrating
Fixes an issue where OBS 30.1.2 migrations would work on the first
30.2.0 load, but the settings would not persist to disk for further
loads.
2024-07-17 22:58:54 -07:00
7e3f2a82f0 Update translations from Crowdin 2024-07-17 09:34:11 +00:00
65396e1db7 requesthandler: Use existence of virtualcam output to test availability
An upstream commit removed the `vcamEnabled` private data field from
being set, so we need to use a new method now.
2024-07-16 11:44:02 -07:00
f8bc7c4f59 base: Update version to 5.5.1
Enhancements:
- Updated translation strings

Bug Fixes:
- Fixed a potential crash with the migration on systems set to
non-english languages
2024-06-11 15:41:13 -07:00
9e48274617 Config: Ensure conversion to filesystem::path uses utf-8 2024-06-11 13:43:10 -07:00
3b7c1c5381 Update translations from Crowdin 2024-06-07 09:47:56 +00:00
20551043f9 base: Update version to 5.5.0
New Features:
- Added `CreateRecordChapter` request for the new native MP4 muxer
[tt2468]
- Added `SplitRecordFile` request to create a file split [tt2468]
- Added `RecordFileChanged` request for when the current recording is
split [tt2468]
- Added obs-websocket-api as a Cmake target, allowing plugins to build
against it without directly including the header file in their source
tree. [tytan652]
- Added the ability to subscribe to obs-websocket events via the
obs-websocket-api header file. [tt2468]

Enhancements:
- Added `cropToBounds` boolean value to Get/SetSceneItemTransform
[exeldro]

Bug Fixes:
- Fixed screenshot behavior of sources with a crop filter not
respecting the cropped size (#1132) [tt2468]
- Fixed an issue with `TriggerHotkeyByName` not releasing keys
correctly when multiple keys are specified. [exeldro]

Other Notes:
- Fixed a few enums showing as deprecated in the documentation
- The location of the obs-websocket global settings data has changed!
Settings located in `global.ini` have moved to the
`plugin_config/obs-websocket` directory. This includes the `global`
realm for the `*PersistentData` requests. Upon loading with an
un-migrated configuration, obs-websocket will perform a migration and
delete the old configurations.
As such, **migration is not reversible**
2024-06-07 01:30:46 -07:00
086bf06008 docs(ci): Update generated docs - 6483dca [skip ci] 2024-06-07 08:29:25 +00:00
6483dcaef0 requesthandler: Add CreateRecordChapter
The new `Hybrid MP4 [BETA]` output added in OBS adds support for
writing chapter markers to the file.
2024-06-07 01:29:10 -07:00
71920c484b eventhandler: Add RecordFileChanged event
When a file split happens, this will fire with the new file name
2024-06-07 01:29:10 -07:00
0eda8f9406 requesthandler: Add SplitRecordFile request 2024-06-07 01:29:10 -07:00
3b873ceb30 requesthandler: Fix releasing hotkeys triggered by name 2024-06-06 00:04:39 -07:00
36f50adf8a requesthandler: Add cropToBounds to scene item 2024-06-06 00:03:26 -07:00
acd1af12a1 docs(ci): Update generated docs - eb28825 [skip ci] 2024-06-06 06:53:33 +00:00
eb2882515f docs: Fix some enums showing up as deprecated
Closes #1141
2024-06-05 23:50:48 -07:00
5c3c4c76c8 requesthandler: Fix resolution of screenshots of cropped sources
This applies the same fix found in obsproject/obs-studio#10077 to get
the target source's real width and height, not the width and height
values from the pre-filter stage.

Closes #1213
2024-06-05 23:34:04 -07:00
8c80e0745a Config: Fix plugin startup for fresh installs
The commit to migrate data from global.ini to the plugin_config folder
accidentally broke plugin startup for fresh configurations. Instead of
returning early if no configuration is found, simply generate a new one
from defaults.

Closes #1225
2024-06-05 23:26:36 -07:00
5b4aa9dabd WebSocketApi: Implement backend for obs-websocket event listening 2024-04-23 01:50:51 -07:00
ee283c7141 lib: Implement obs-websocket event callback access
This allows plugins to listen directly for obs-websocket events.
2024-04-23 01:50:11 -07:00
179e197bd5 base: Many random fixups preparing for WebSocketApi event callbacks 2024-04-23 00:28:00 -07:00
5fc39ef054 base: Apply latest clang-format changes from upstream
Minus, some customizations, of course
2024-04-22 23:44:04 -07:00
74719ce502 base: Move some direct crosstalk to callback system 2024-04-22 23:35:16 -07:00
9123879c76 Config: Use std::string for ServerPassword instead of QString
Less Qt leeching into things is better.
2024-04-22 22:50:10 -07:00
9db7464faa base: Use std::make_shared when allocating classes
Follows c++ recommendations.
2024-04-22 22:42:55 -07:00
e2b8a06d94 requesthandler: Use new global realm path in persistent data requests
The `MigratePersistentData()` function handles migrating persistent
data on module load, and will fail if the data cannot be migrated.
2024-04-22 22:36:12 -07:00
af31f1adca Config: Migrate config/persistent data to plugin_config directory
This commit moves the Config value storage from `global.ini` to a new
`config.json` file in the `plugin_config/obs-websocket` directory. This
comes after some internal discussion about plugins not using the
`plugin_config` directory, and that obs-websocket was offending.

Settings are currently stored as a JSON object, and field names have
been changed from using PascalCase to snake_case, to better align
with how JSON is stored elsewhere in OBS.
2024-04-22 22:30:44 -07:00
4410e30684 utils: Pass fileName by value in GetModuleConfigPath()
Lots of `const char *` values, preventing usage of passing by reference
2024-04-22 22:29:21 -07:00
2c884ca690 utils: Make SetJsonFileContent() create directories by default 2024-04-22 22:28:45 -07:00
f72f23a9d7 utils: Minor code fixups 2024-04-22 18:40:50 -07:00
a589e80bdb utils: Implement helper to get current module config path 2024-04-22 18:38:19 -07:00
305afd763d utils: Remove old *AutoRelease definitions
Now that OBS has been out with the upstream AutoRelease definitions,
and obs-websocket is also in-tree-only, these are no longer necessary.
2024-04-22 18:32:51 -07:00
42e7eb6c34 utils: Remove text file Get/Set methods from Platform
No longer needed, and using Qt isn't good anyway
2024-04-22 18:23:39 -07:00
bdf812dc09 utils: Reimplement Get/SetJsonFileContent helpers
Uses <fstream> instead of the text helpers
2024-04-22 18:22:27 -07:00
c8cf2d94ac cmake,lib,base: Export obs-websocket-api as a target
This enables the installation of the header in the include directory
2024-03-30 17:04:37 -07:00
d2d4bfb3e7 Update translations from Crowdin 2024-03-12 18:11:05 +00:00
d5077fca03 base: Update to version 5.4.2
Bug Fixes:
- Fixes version update to use both legacy and main CMake files
2024-02-21 11:21:17 -06:00
4a647c5262 base: Update to version 5.4.1
Bug Fixes:
- Updated scene item transform API to latest version to prevent
  deprecation warnings (obs_sceneitem_set_info2 and
  obs_sceneitem_get_info2)
2024-02-20 21:44:33 -06:00
3ea3d3228b requesthandler: Update scene item transform API
Updates:
obs_sceneitem_get_info to obs_sceneitem_get_info2
obs_sceneitem_set_info to obs_sceneitem_set_info2

Ensures that we're using the latest versions of these functions in order
to prevent future deprecation
2024-02-20 21:44:33 -06:00
e94f9194a2 CI: Update first-party GitHub Actions to v4
GitHub Actions has deprecated actions based on node16. The v4 actions
are based on node20. Replace first-party v2/v3 actions with their v4
counterparts.

GitHub Actions has deprecated actions based on node12 and forces them to
run on node16, which is also deprecated. Update to v4 actions to avoid
warnings on CI.

See:
https://github.blog/changelog/2023-06-13-github-actions-all-actions-will-run-on-node16-instead-of-node12-by-default/
https://github.blog/changelog/2023-09-22-github-actions-transitioning-from-node-16-to-node-20/
2024-01-30 16:25:38 -08:00
9ee6e2ff2a Update translations from Crowdin 2024-01-29 20:47:37 +00:00
b61a5c2431 base: Update version to 5.4.0
New Features:
- Added `GetSourceFilterKindList` request
- Added `GetSceneItemSource` request
- Added `InputSettingsChanged` event
- Added `SourceFilterSettingsChanged` event
- Added UUID support to Sources (Inputs/Scenes), Inputs, Scenes,
Transitions
  - The `Source` requests/events use `sourceUuid`
  - The `Input` requests/events use `inputUuid`
  - The `Scene` requests/events use `sceneUuid`
  - The `Transition` requests/events use `transitionUuid`
  - Filters do not have support for UUIDs at this time.

Enhancements:
- Added `contextName` field to `TriggerHotkeyByName` (exeldro)

Bug Fixes:
- Fixed a crash on shutdown with notifications enabled (r1ch)
- Added safety check to prevent `null` `outputCongestion` values in
`GetStreamStatus`
- Fixed a memory leak when switching service kinds via
`SetStreamServiceSettings`

Other Notes:
- Documented missing `outputActive` `ToggleRecord` response field
- Added a few new client softwares to the README list
- Removed a mis-documented `imageData` field
- Added a note to the hotkey requests that they are as-is and we
will not provide support for them
2024-01-24 15:51:27 -08:00
fbd4cfb4af docs(ci): Update generated docs - e5aa4c2 [skip ci] 2024-01-19 03:35:08 +00:00
e5aa4c2f69 requesthandler: Rename GetSceneItemSourceName to GetSceneItemSource
Not an API break, this was introduced just a few commits ago.
2024-01-18 19:34:51 -08:00
4cf8de8382 docs(ci): Update generated docs - 7adfb58 [skip ci] 2024-01-19 03:30:20 +00:00
7adfb5874c requesthandler: Implement input, scene, and transition UUID support
Transition UUID support is partial due to the current state of the OBS
frontend API.

Most requests which accepted things like `sourceName` now allow
`sourceUuid` (or equivalent) to be specified instead. While both fields
on the various requests may be marked as optional, at least one field
will still be required.
2024-01-18 19:27:57 -08:00
f18f46543b eventhandler: Implement input, scene, and transition UUID support
Adds `inputUuid` next to `inputName` etc.
2024-01-18 16:58:40 -08:00
f40426efa1 utils: Implement input, scene, and transition UUID support 2024-01-18 16:56:20 -08:00
830f7eb931 utils: Use BPtr for strings instead of manual bfree() 2024-01-18 16:17:48 -08:00
5e3fff78f3 docs(ci): Update generated docs - b53527c [skip ci] 2024-01-19 00:06:25 +00:00
b53527cba8 requesthandler: Add note about as-is status of hotkey requests
Too much trouble for too little gain. Please stop using these requests.
2024-01-18 16:06:07 -08:00
b806a0cfb1 docs(ci): Update generated docs - 1d0db34 [skip ci] 2024-01-19 00:02:16 +00:00
1d0db34bb2 requesthandler: Add GetSceneItemSourceName request
Closes #1122
2024-01-18 16:01:41 -08:00
690726d281 docs(ci): Update generated docs - ef4142f [skip ci] 2024-01-18 23:54:27 +00:00
ef4142fe75 eventhandler: Add SourceFilterSettingsChanged event
Closes #1059
2024-01-18 15:54:08 -08:00
caaec5d97f requesthandler: Use Frontend API for CreateSceneCollection 2024-01-18 15:43:46 -08:00
6c67b276a7 lib: Fix compile errors on C and warnings on C++ 2024-01-16 01:39:27 -08:00
fad7dfd55c docs(ci): Update generated docs - a5c459b [skip ci] 2024-01-16 09:37:45 +00:00
a5c459b6d4 docs: Fix SaveSourceScreenshot's Response Field 2024-01-16 01:37:29 -08:00
899a9b3801 README: Bump Godot client library to 4.0.x 2024-01-16 01:36:49 -08:00
939e503736 README: Add MATRIC to client software list
Closes #1177
2024-01-16 01:35:11 -08:00
5b149add99 RequestHandler: Fix memory leak when setting streaming service 2024-01-16 01:33:29 -08:00
50b57d38d0 README: Add Macrograph to Client Software 2024-01-16 01:23:59 -08:00
9b58dd1627 docs(ci): Update generated docs - 81b307e [skip ci] 2024-01-16 08:41:23 +00:00
81b307e5ad eventhandler: Add InputSettingsChanged
Fired when an input's settings change, like via the properties dialog
or via `SetInputSettings`.

Closes #1157
2024-01-16 00:41:03 -08:00
52733ddce7 docs(ci): Update generated docs - 444caeb [skip ci] 2024-01-16 08:19:11 +00:00
444caeb1d7 requesthandler: Add GetSourceFilterKindList
Closes #1198
2024-01-16 00:18:52 -08:00
f03e82c3f8 docs(ci): Update generated docs - bbdc5bc [skip ci] 2024-01-16 07:46:34 +00:00
bbdc5bc823 requesthandler: Prevent NaN outputCongestion values (null) 2024-01-15 23:45:33 -08:00
9ecc9532e8 requesthandler: Document ToggleRecord outputActive response field 2024-01-15 23:44:50 -08:00
0189c3a3f5 Utils: Check system tray exists before trying to use it
Fixes https://github.com/obsproject/obs-studio/issues/9991
2024-01-15 23:19:09 -08:00
f48fcc06ec docs(ci): Update generated docs - f43ef8e [skip ci] 2024-01-09 07:06:29 +00:00
f43ef8e2da requesthandler: Add optional context to TriggerHotkeyByName 2024-01-08 23:06:12 -08:00
7a1c71bb96 base: Update version to 5.3.5
- CMake update, no functional changes
2023-12-22 16:38:27 -05:00
cf285b3761 cmake: Update formatting and switch to native find_package call for Qt6 2023-12-20 15:09:11 -05:00
ede66a68cb Update translations from Crowdin 2023-12-05 22:04:30 +00:00
e8089a5bbf base: Update version to 5.3.4
- eventhandler: Disconnect signals from all public sources on shutdown
- websocketserver: Check for EventHandler validity in de/constructor
2023-12-05 14:15:04 -05:00
07537a33fa websocketserver: Check for EventHandler validity in de/constructor
Redundant fix for shutdown crash
2023-11-14 00:07:05 -08:00
efeae8d640 eventhandler: Disconnect signals from all public sources on shutdown
Fixes crash on shutdown when memory leaks lead to un-destroyed
sources after plugin shutdown.
2023-11-14 00:07:05 -08:00
4ff109b62b base: Update version to 5.3.3
- Update translations and docs
2023-10-16 10:42:15 -04:00
42da47f81d docs(ci): Update generated docs - a889799 [skip ci] 2023-10-13 21:25:41 +00:00
a889799655 docs: Update introduction header to 5.x.x
We don't need to be having specific versions here, considering each event/request has its own "added at" version.
2023-10-13 14:25:23 -07:00
f52f47ec5d Update translations from Crowdin 2023-10-10 13:34:40 +00:00
08767ae5a7 base: Update version to 5.3.2
- Fix plugin tests being enabled by default
2023-10-09 16:34:30 -04:00
16bf61aab6 cmake: Fix condition to disable plugin tests
The CMake generator expression to enable plugin tests mistakenly used a
string literal, which evaluated to 1, which enabled the plugin tests by
default. Use variable notation to correctly test this value.
2023-10-02 14:37:04 -07:00
e9c0eee9e4 base: Update version to 5.3.1
- Fix issues with qrcodegencpp CMake preventing Debug builds
2023-09-19 13:21:47 -04:00
f4a3de575c cmake: Update library and target names for qrcodegen
qrcodegen is identified as such (without the "lib" prefix) and as the
target "qrcodegencpp::qrcodegencpp" by the CMake package generated by
obs-deps and the finders in obs-studio when using module fallback.
2023-09-19 13:13:57 -04:00
2bfa1b4c64 cmake: Ignore LNK4099 warning
Despite building the PDBs for qrcodegencpp debug builds, we do not
currently ship those PDBs, so MSVC emits an LNK4099 warning, which
causes a build failure. It's unlikely that we'll need to debug in linked
dependencies, so we can ignore this warning. Should we decide in the
future to ship PDBs for these dependencies, the warning would no longer
be emitted, and this flag would be superfluous without requiring a
change. For now, let's make sure we can build in Debug.
2023-09-19 10:52:15 -04:00
0e611f579b cmake: Update library and target names for qrcodegen
qrcodegen is identified as such (without the "lib" prefix) and as the
target "qrcodegencpp::qrcodegencpp" by the CMake package generated by
obs-deps.
2023-09-18 12:50:40 -04:00
ec2cdc8475 base: Update version to 5.3.0
- Various minor build process cleanups
- Various code cleanups
- requesthandler: Added NotReady request status
- base: Pause requests and events during start, SC change, and shutdown
- eventhandler: Use OBS_FRONTEND_EVENT_SCRIPTING_SHUTDOWN for exit
- requesthandler: Added SetRecordDirectory
- websocketserver: Retry listen on IPv4 if IPv6 is not available
2023-09-05 14:31:41 -04:00
3cd8163945 base: Fix error to save configuration at obs_module_unload
When `obs_module_unload` is called, the frontend API is no longer
available so that `_config->Save()` is failing with error messages.
Since the configuration is saved from the OK or the Apply button on the
dialog, it is not necessary to save it again at `obs_module_unload`.
2023-08-16 12:56:12 -07:00
132d4bafdd CI: Add obs-crowdin-sync 2023-08-16 12:51:54 -07:00
d991e21f29 Update translations from Crowdin 2023-08-13 14:09:13 +00:00
a74468e07e docs(ci): Update generated docs - 55b3f88 [skip ci] 2023-08-10 01:53:35 +00:00
55b3f88db9 base: Fix a comment for SetSceneSceneTransitionOverride 2023-08-09 21:53:17 -04:00
ba7839bb69 locale: Remove obsolete translations 2023-08-09 21:52:11 -04:00
417725801c base,deps,src: Replace qr submodule by prefix/system install 2023-07-15 16:58:18 -07:00
93713c438e docs: Fix URL in docs README 2023-05-29 13:20:53 -07:00
6db08f960e docs(ci): Update generated docs - 6434c42 [skip ci] 2023-05-28 05:54:49 +00:00
6434c42155 websocketserver: Retry listen on IPv4 if IPv6 is not available
Fixes #1311
2023-05-27 22:54:02 -07:00
ac00465565 requesthandler: Add SetRecordDirectory
I've admittedly done a pretty bad job of communicating the intention of
having `SetProfileParameter` be the go-to method of configuring the
record directory. In hindsight, such a commonly needed feature should
not be locked behind an arguably complex request.

Closes #1142
Closes #1062
Closes #1035
2023-05-27 22:30:08 -07:00
2606f262e6 docs: Add big text to README in the docs directory linking protocol.md
I bet people have been getting confused here
2023-05-27 22:14:16 -07:00
2caecf6c01 README: A few minor tweaks 2023-05-27 22:14:05 -07:00
19170fe6d9 WebSocketApi: Add missing GPL license headers 2023-05-27 22:06:46 -07:00
1fc7900b1c Config: Move default values to header file
Just to make the code style align with other places
2023-05-27 22:00:51 -07:00
53d7596160 base: Various random code nitpicks 2023-05-27 22:00:26 -07:00
886738547a websocketserver: Clean up WebSocketSession class implementation
Makes it header-only with inlines, so there's theoretically some very
small performance improvements too.
2023-05-27 21:50:55 -07:00
c11874eb17 eventhandler: Use OBS_FRONTEND_EVENT_SCRIPTING_SHUTDOWN for exit
Fixes #1136
2023-05-09 22:53:43 -07:00
a0ffe16e91 base: Pause requests and events during start, SC change, and shutdown
This implements the functionality described by the new NotReady request
status. Behavior should now be *much* more reliable.
2023-05-09 22:53:43 -07:00
e3d0751385 docs(ci): Update generated docs - d518541 [skip ci] 2023-05-10 01:38:50 +00:00
d5185417ec requesthandler: Add NotReady request status
During scene collection change and OBS exit, performing requests
constitutes undefined behavior. Previously, we attempted to help this
by providing the `SceneCollectionChanging` event for any clients to
pause requests client-side, but this method has proven to not be
adequate to fix the issue. As such, this allows us to tell clients
explicitly that a request cannot be fulfilled reliably, and they
may decide whether or not to retry.
2023-05-09 18:26:25 -07:00
f7637250f1 cmake: Silences Qt warnings emitted by clang with default Xcode settings 2023-05-09 15:01:45 -07:00
57a9c19f2c Update translations from Crowdin 2023-05-01 23:11:11 +00:00
6633144ce8 README: Prevent Firefox from flagging Macro Deck as a security risk
Removes the 'www․' in the Macro Deck link in README.md to Prevent
Firefox from flagging the Macro Deck website as a potential security
risk.
2023-04-19 12:06:36 -07:00
6ef055a369 base: Update version to 5.2.2
- Various minor build process cleanups
2023-04-04 15:13:15 -04:00
a4ee9c03ea base: Remove unneeded include directories
Asio and WebSocket++ are no longer added as submodules.
They are now included in obs-deps.
2023-04-04 12:15:33 -04:00
9912c9963c base: Remove unnecessary entries in .gitignore
the commit 21886adb3 moves the destination of the generated files into
the build directory so that it is unnecessary to hide the generated
files by .gitignore.
2023-04-04 12:14:11 -04:00
21886adb32 base: Fix generated header inclusion 2023-03-27 12:59:23 -04:00
c85d9143a9 Update translations from Crowdin 2023-03-27 13:39:01 +00:00
7ca8d5fc2b base: Update version to 5.2.0
- Fixed a crash caused if `authentication` payload field was not a
string
- Allow empty vendor request data
- Minor documentation fixes
- Replace submodules with obs-deps or system versions where possible
  - asio
  - websocketpp
  - nlohmann/json
- Refactor CMake to allow uplift to new obs-studio CMake
2023-03-26 19:30:00 -04:00
db2c251189 base: Re-add version CMake variables
Make sure that non-legacy builds have these version variables populated.
2023-03-26 19:09:51 -04:00
dd248faecb cmake: Add changes for CMake build framework 3.0
New code path only taken if OBS_CMAKE_VERSION is set to 3.0.0 or
greater, old functionality remains unchanged.
2023-03-26 18:21:05 -04:00
68d79b22af base: Disable Qt RCC timestamps only on Windows 2023-03-24 12:29:19 -04:00
b06da5fa63 base: Disable Qt RCC timestamps 2023-03-23 18:20:34 -04:00
78a1b54a47 base,deps: Replace submodules by prefix/system install
nlohmann JSON, WebSocket++ and Asio are moved from sudmodules to
prefix (obs-deps) or system-wide install (Linux).
2023-03-23 17:37:51 -04:00
bf277011f9 base: Refactor CMake Qt properties
- Allow obs-deps to be used by not changing CMAKE_PREFIX_PATH.
- Move Qt AUTO properties to the target.
2023-03-23 17:37:51 -04:00
96032e0e8c requesthandler: Allow empty vendor request data 2023-02-08 10:10:44 -08:00
ddd139255b Update translations from Crowdin 2023-01-08 04:10:35 +00:00
edf29e828c docs(ci): Update generated docs - 079ab31 [skip ci] 2022-12-31 22:55:24 +00:00
079ab31f88 docs: Fix small typo in introduction.md
- Corrected 'compatability' to 'compatibility' in docs/docs/partials/introduction.md
2022-12-31 14:55:04 -08:00
e797a3fb34 websocketserver: Validate data type of authentication payload field
Can cause crash if field is not a string

Reported by @tyami94
2022-12-31 14:54:11 -08:00
a792c59699 docs(ci): Update generated docs - 31f9845 [skip ci] 2022-11-18 10:29:29 +00:00
31f9845b61 base: Update version to 5.1.0
- Renamed the tools menu button title to `WebSocket Server Settings`
- WebSocket session disconnects are now logged with the close code and
reason
- Fixed a few UI formatting issues
- Fixed the `ObsOutputState` enum not being shown in protocol.md
- Implemented new reconnect output states to the stream output
  - `OBS_WEBSOCKET_OUTPUT_RECONNECTING`
  - `OBS_WEBSOCKET_OUTPUT_RECONNECTED`
- Added the `ScreenshotSaved` event for the screenshot hotkey
- Fixed a bug where `GetLastReplayBufferFileName` could return an empty
string
- Documented `CustomEvent`
- Various other documentation fixes
- Added the following new software and libraries to the README:
  - Macro Deck
  - Bitfocus Companion
  - Kruiz Control
  - Aitum
  - OBS Blade
  - Deckboard
  - Streamer.bot
  - OBS-web
  - obws (Rust)
  - goobs
  - obsws-python
2022-11-18 02:29:10 -08:00
cb6f0b8986 docs(ci): Update generated docs - 9959acb [skip ci] 2022-11-18 10:10:12 +00:00
9959acb0e8 forms: Various UI improvements 2022-11-18 02:09:48 -08:00
8b1ef17c25 docs: Fix initial version for reconnect enum fields 2022-11-18 02:09:48 -08:00
a254172c12 eventhandler: Add reconnecting and reconnected stream output states
Closes #1050
2022-11-18 02:09:48 -08:00
57a9e23f16 docs: Document ObsOutputState enum 2022-11-18 02:09:48 -08:00
4c3660c08d docs: Enable ObsMediaInputAction enum documentation
It should now show up in protocol.md
2022-11-18 02:09:48 -08:00
323b5d0b5d eventhandler, utils: Implement missing output states 2022-11-18 02:09:48 -08:00
23f883d906 eventhandler: Split some handling code into multi handlers
Code cleanup
2022-11-18 02:09:48 -08:00
60dbcc1b66 docs(ci): Update generated docs - 8cabe24 [skip ci] 2022-11-18 06:20:26 +00:00
8cabe24b77 eventhandler: Add ScreenshotSaved event
No, this does not trigger with `Get/SaveScreenshot`. I've tried to make
that super clear in the docs. Hopefully people don't get too confused.
2022-11-17 22:19:12 -08:00
9cfca3c7d1 utils: Use new method to get last replay
Uses the newer obs-frontend-api function instead of our original
method. It was cool, but is no longer necessary.
2022-11-17 22:18:18 -08:00
cfa0b4363e utils: Add function to get last screenshot file name 2022-11-17 22:16:59 -08:00
815d47e2ff README: Add Macro Deck software link 2022-11-17 18:40:27 -08:00
9bdf560bf8 utils: Fix use-after-free in GetLastReplayBufferFileName 2022-11-17 18:36:25 -08:00
47f9beb095 docs(ci): Update generated docs - 32d0834 [skip ci] 2022-11-13 00:00:45 +00:00
32d0834c3f docs: Fix description of "mul" volume notation 2022-11-12 16:00:28 -08:00
9722ed3df4 Add CustomEvent docs entry
Resolves #1031
2022-11-12 15:56:03 -08:00
9f72852588 doc: Update README to add Java library 2022-11-12 15:51:05 -08:00
6e0220ac7b Update translations from Crowdin 2022-10-25 22:32:12 +00:00
6d4b7c786e docs(ci): Update generated docs - 290e042 [skip ci] 2022-10-22 22:22:39 +00:00
290e042612 fix: Sleep request fields are exclusive so both optional fixes #1042 2022-10-22 15:22:20 -07:00
7e4c9529eb docs(ci): Update generated docs - bc18401 [skip ci] 2022-10-18 20:11:17 +00:00
bc18401fb0 docs: Fix ouputPaused typo 2022-10-18 13:10:58 -07:00
265899f76f docs(ci): Update generated docs - 9e1a41f [skip ci] 2022-09-19 01:02:32 +00:00
9e1a41f219 docs: Clarify that nested scenes are recommended instead of groups
Seems like it would be obvious, but apparently not
2022-09-18 18:02:13 -07:00
7893ae5caa docs: Add top-level headings to main TOC
It may be worth having the entire TOC up here, but this way, at least
it's possible to jump to the other TOCs.
2022-09-16 04:54:42 -07:00
a715639302 docs(ci): Update generated docs - 6038fe9 [skip ci] 2022-09-07 19:43:58 +00:00
6038fe9a0a docs: Start list of known propertyName values for common buttons 2022-09-07 12:43:29 -07:00
6fba48929a README: Add second contributor to obsws-python 2022-09-05 15:33:30 -07:00
7eb4eb101c README: Add Bitfocus Companion to client software 2022-09-05 15:32:51 -07:00
f2e595e1ab README: Add Kruiz Control and obsws-python to list 2022-09-04 17:11:30 -07:00
c1ffbf0111 README: Add Aitum 2022-09-03 15:16:30 -07:00
f08d3225ad README: Add OBS Blade to supported client software 2022-09-03 07:06:10 -07:00
84542e1ed5 README: Add deckboard to supported client software list 2022-09-03 06:53:41 -07:00
bb9371b0dc locale: Rename plugin settings title to match other plugins
Closes obsproject/obs-studio#7231
2022-09-02 00:11:59 -07:00
ab918faea8 README: Add streamer.bot to list of supported client software 2022-09-01 03:12:56 -07:00
136 changed files with 4700 additions and 1603 deletions

View File

@ -1,6 +1,6 @@
# please use clang-format version 8 or later # please use clang-format version 16 or later
Standard: Cpp11 Standard: c++17
AccessModifierOffset: -8 AccessModifierOffset: -8
AlignAfterOpenBracket: Align AlignAfterOpenBracket: Align
AlignConsecutiveAssignments: false AlignConsecutiveAssignments: false
@ -8,14 +8,14 @@ AlignConsecutiveDeclarations: false
AlignEscapedNewlines: Left AlignEscapedNewlines: Left
AlignOperands: true AlignOperands: true
AlignTrailingComments: true AlignTrailingComments: true
#AllowAllArgumentsOnNextLine: false # requires clang-format 9 AllowAllArgumentsOnNextLine: false
#AllowAllConstructorInitializersOnNextLine: false # requires clang-format 9 AllowAllConstructorInitializersOnNextLine: false
AllowAllParametersOfDeclarationOnNextLine: false AllowAllParametersOfDeclarationOnNextLine: false
AllowShortBlocksOnASingleLine: false AllowShortBlocksOnASingleLine: false
AllowShortCaseLabelsOnASingleLine: false AllowShortCaseLabelsOnASingleLine: false
AllowShortFunctionsOnASingleLine: Inline AllowShortFunctionsOnASingleLine: Inline
AllowShortIfStatementsOnASingleLine: false AllowShortIfStatementsOnASingleLine: false
#AllowShortLambdasOnASingleLine: Inline # requires clang-format 9 AllowShortLambdasOnASingleLine: Inline
AllowShortLoopsOnASingleLine: false AllowShortLoopsOnASingleLine: false
AlwaysBreakAfterDefinitionReturnType: None AlwaysBreakAfterDefinitionReturnType: None
AlwaysBreakAfterReturnType: None AlwaysBreakAfterReturnType: None
@ -57,6 +57,7 @@ ForEachMacros:
- 'json_object_foreach' - 'json_object_foreach'
- 'json_object_foreach_safe' - 'json_object_foreach_safe'
- 'json_array_foreach' - 'json_array_foreach'
- 'HASH_ITER'
IncludeBlocks: Preserve IncludeBlocks: Preserve
IndentCaseLabels: false IndentCaseLabels: false
IndentPPDirectives: None IndentPPDirectives: None
@ -65,7 +66,7 @@ IndentWrappedFunctionNames: false
KeepEmptyLinesAtTheStartOfBlocks: true KeepEmptyLinesAtTheStartOfBlocks: true
MaxEmptyLinesToKeep: 1 MaxEmptyLinesToKeep: 1
NamespaceIndentation: All NamespaceIndentation: All
#ObjCBinPackProtocolList: Auto # requires clang-format 7 ObjCBinPackProtocolList: Auto
ObjCBlockIndentWidth: 8 ObjCBlockIndentWidth: 8
ObjCSpaceAfterProperty: true ObjCSpaceAfterProperty: true
ObjCSpaceBeforeProtocolList: true ObjCSpaceBeforeProtocolList: true
@ -83,13 +84,13 @@ ReflowComments: false
SortIncludes: false SortIncludes: false
SortUsingDeclarations: false SortUsingDeclarations: false
SpaceAfterCStyleCast: false SpaceAfterCStyleCast: false
#SpaceAfterLogicalNot: false # requires clang-format 9 SpaceAfterLogicalNot: false
SpaceAfterTemplateKeyword: false SpaceAfterTemplateKeyword: false
SpaceBeforeAssignmentOperators: true SpaceBeforeAssignmentOperators: true
#SpaceBeforeCtorInitializerColon: true # requires clang-format 7 SpaceBeforeCtorInitializerColon: true
#SpaceBeforeInheritanceColon: true # requires clang-format 7 SpaceBeforeInheritanceColon: true
SpaceBeforeParens: ControlStatements SpaceBeforeParens: ControlStatements
#SpaceBeforeRangeBasedForLoopColon: true # requires clang-format 7 SpaceBeforeRangeBasedForLoopColon: true
SpaceInEmptyParentheses: false SpaceInEmptyParentheses: false
SpacesBeforeTrailingComments: 1 SpacesBeforeTrailingComments: 1
SpacesInAngles: false SpacesInAngles: false
@ -97,11 +98,111 @@ SpacesInCStyleCastParentheses: false
SpacesInContainerLiterals: false SpacesInContainerLiterals: false
SpacesInParentheses: false SpacesInParentheses: false
SpacesInSquareBrackets: false SpacesInSquareBrackets: false
#StatementMacros: # requires clang-format 8 StatementMacros:
# - 'Q_OBJECT' - 'Q_OBJECT'
TabWidth: 8 TabWidth: 8
#TypenameMacros: # requires clang-format 9 TypenameMacros:
# - 'DARRAY' - 'DARRAY'
UseTab: ForContinuationAndIndentation UseTab: ForContinuationAndIndentation
--- ---
Language: ObjC Language: ObjC
AccessModifierOffset: 2
AlignArrayOfStructures: Right
AlignConsecutiveAssignments: None
AlignConsecutiveBitFields: None
AlignConsecutiveDeclarations: None
AlignConsecutiveMacros:
Enabled: true
AcrossEmptyLines: false
AcrossComments: true
AllowShortBlocksOnASingleLine: Never
AllowShortEnumsOnASingleLine: false
AllowShortFunctionsOnASingleLine: Empty
AllowShortIfStatementsOnASingleLine: Never
AllowShortLambdasOnASingleLine: None
AttributeMacros: ['__unused', '__autoreleasing', '_Nonnull', '__bridge']
BitFieldColonSpacing: Both
#BreakBeforeBraces: Webkit
BreakBeforeBraces: Custom
BraceWrapping:
AfterCaseLabel: false
AfterClass: true
AfterControlStatement: Never
AfterEnum: false
AfterFunction: true
AfterNamespace: false
AfterObjCDeclaration: false
AfterStruct: false
AfterUnion: false
AfterExternBlock: false
BeforeCatch: false
BeforeElse: false
BeforeLambdaBody: false
BeforeWhile: false
IndentBraces: false
SplitEmptyFunction: false
SplitEmptyRecord: false
SplitEmptyNamespace: true
BreakAfterAttributes: Never
BreakArrays: false
BreakBeforeConceptDeclarations: Allowed
BreakBeforeInlineASMColon: OnlyMultiline
BreakConstructorInitializers: AfterColon
BreakInheritanceList: AfterComma
ColumnLimit: 120
ConstructorInitializerIndentWidth: 4
ContinuationIndentWidth: 4
EmptyLineAfterAccessModifier: Never
EmptyLineBeforeAccessModifier: LogicalBlock
ExperimentalAutoDetectBinPacking: false
FixNamespaceComments: true
IndentAccessModifiers: false
IndentCaseBlocks: false
IndentCaseLabels: true
IndentExternBlock: Indent
IndentGotoLabels: false
IndentRequiresClause: true
IndentWidth: 4
IndentWrappedFunctionNames: true
InsertBraces: false
InsertNewlineAtEOF: true
KeepEmptyLinesAtTheStartOfBlocks: false
LambdaBodyIndentation: Signature
NamespaceIndentation: All
ObjCBinPackProtocolList: Auto
ObjCBlockIndentWidth: 4
ObjCBreakBeforeNestedBlockParam: false
ObjCSpaceAfterProperty: true
ObjCSpaceBeforeProtocolList: true
PPIndentWidth: -1
PackConstructorInitializers: NextLine
QualifierAlignment: Leave
ReferenceAlignment: Right
RemoveSemicolon: false
RequiresClausePosition: WithPreceding
RequiresExpressionIndentation: OuterScope
SeparateDefinitionBlocks: Always
ShortNamespaceLines: 1
SortIncludes: false
#SortUsingDeclarations: LexicographicNumeric
SortUsingDeclarations: true
SpaceAfterCStyleCast: true
SpaceAfterLogicalNot: false
SpaceAroundPointerQualifiers: Default
SpaceBeforeCaseColon: false
SpaceBeforeCpp11BracedList: true
SpaceBeforeCtorInitializerColon: true
SpaceBeforeInheritanceColon: true
SpaceBeforeParens: ControlStatements
SpaceBeforeRangeBasedForLoopColon: true
SpaceBeforeSquareBrackets: false
SpaceInEmptyBlock: false
SpaceInEmptyParentheses: false
SpacesBeforeTrailingComments: 2
SpacesInConditionalStatement: false
SpacesInLineCommentPrefix:
Minimum: 1
Maximum: -1
Standard: c++17
TabWidth: 4
UseTab: Never

View File

@ -1,4 +1,10 @@
{ {
"format": {
"line_width": 120,
"tab_size": 2,
"enable_sort": true,
"autosort": true
},
"additional_commands": { "additional_commands": {
"find_qt": { "find_qt": {
"flags": [], "flags": [],
@ -8,6 +14,33 @@
"COMPONENTS_MACOS": "+", "COMPONENTS_MACOS": "+",
"COMPONENTS_LINUX": "+" "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
}
}
}
} }
} }
} }

View File

@ -28,10 +28,8 @@ body:
- macOS 10.14 - macOS 10.14
- macOS 10.13 - macOS 10.13
- Ubuntu 22.04 LTS - Ubuntu 22.04 LTS
- Ubuntu 21.04
- Ubuntu 20.10 - Ubuntu 20.10
- Ubuntu 20.04 LTS - Ubuntu 20.04 LTS
- Ubuntu 18.04 LTS
- Other - Other
validations: validations:
required: true required: true
@ -49,16 +47,10 @@ body:
label: OBS Studio Version label: OBS Studio Version
description: What version of OBS Studio are you using? description: What version of OBS Studio are you using?
options: options:
- 28.0.0 - 29.0.x
- 28.1.x
- 28.0.x
- 27.2.4 - 27.2.4
- 27.2.3
- 27.2.2
- 27.2.1
- 27.2.0
- 27.1.3
- 27.1.1
- 27.1.0
- 27.0.1
- Git - Git
- Other - Other
validations: validations:
@ -76,9 +68,9 @@ body:
label: obs-websocket Version label: obs-websocket Version
description: What version of obs-websocket are you using? description: What version of obs-websocket are you using?
options: options:
- 5.1.0
- 5.0.1 - 5.0.1
- 5.0.0 - 5.0.0
- 5.0.0-beta1
- Git - Git
validations: validations:
required: true required: true

22
.github/workflows/crowdin_upload.yml vendored Normal file
View File

@ -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@v4
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

View File

@ -18,7 +18,7 @@ jobs:
IS_CI: "true" IS_CI: "true"
steps: steps:
- name: 'Checkout' - name: 'Checkout'
uses: actions/checkout@v2 uses: actions/checkout@v4
with: with:
path: ${{ github.workspace }}/obs-websocket path: ${{ github.workspace }}/obs-websocket
- name: 'Generate docs' - name: 'Generate docs'

View File

@ -15,7 +15,7 @@ jobs:
if: contains(github.event.head_commit.message, '[skip ci]') != true if: contains(github.event.head_commit.message, '[skip ci]') != true
steps: steps:
- name: Checkout repository - name: Checkout repository
uses: actions/checkout@v2 uses: actions/checkout@v4
- name: Generate docs - name: Generate docs
run: cd docs && ./build_docs.sh run: cd docs && ./build_docs.sh
- name: Run markdownlint-cli - name: Run markdownlint-cli

2
.gitignore vendored
View File

@ -2,7 +2,6 @@
.DS_Store .DS_Store
.idea .idea
.vscode .vscode
**.generated.h
/build/ /build/
/build32/ /build32/
/build64/ /build64/
@ -10,5 +9,4 @@
/package/ /package/
/installer/Output/ /installer/Output/
/docs/node_modules/ /docs/node_modules/
/installer/installer-windows.generated.iss
/cmake-build-debug/ /cmake-build-debug/

12
.gitmodules vendored
View File

@ -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

View File

@ -1,174 +1,185 @@
project(obs-websocket VERSION 5.0.1) cmake_minimum_required(VERSION 3.16...3.25)
legacy_check()
set(obs-websocket_VERSION 5.5.2)
set(OBS_WEBSOCKET_RPC_VERSION 1) set(OBS_WEBSOCKET_RPC_VERSION 1)
option(ENABLE_WEBSOCKET "Enable building OBS with websocket plugin" ON) include(cmake/obs-websocket-api.cmake)
if(NOT ENABLE_WEBSOCKET OR NOT ENABLE_UI) option(ENABLE_WEBSOCKET "Enable building OBS with websocket plugin" ON)
message(STATUS "OBS: DISABLED obs-websocket") if(NOT ENABLE_WEBSOCKET)
target_disable(obs-websocket)
return() return()
endif() 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
find_qt(COMPONENTS Core Widgets Svg Network) find_package(Qt6 REQUIRED Core Widgets Svg Network)
# Find nlohmann # Find nlohmann JSON
set(JSON_BuildTests find_package(nlohmann_json 3 REQUIRED)
OFF
CACHE INTERNAL "")
add_subdirectory(deps/json)
# Tell websocketpp not to use system boost # Find qrcodegencpp
add_definitions(-DASIO_STANDALONE) set(CMAKE_FIND_PACKAGE_PREFER_CONFIG ON)
find_package(qrcodegencpp REQUIRED)
set(CMAKE_FIND_PACKAGE_PREFER_CONFIG OFF)
# Configure files # Find WebSocket++
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/src/plugin-macros.h.in find_package(Websocketpp 0.8 REQUIRED)
${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 MODULE)
add_library(OBS::websocket ALIAS obs-websocket) add_library(OBS::websocket ALIAS obs-websocket)
target_sources( target_sources(
obs-websocket obs-websocket
PRIVATE src/obs-websocket.cpp PRIVATE # cmake-format: sortable
src/obs-websocket.h
src/Config.cpp src/Config.cpp
src/Config.h src/Config.h
lib/obs-websocket-api.h
src/forms/SettingsDialog.cpp
src/forms/SettingsDialog.h
src/forms/ConnectInfo.cpp src/forms/ConnectInfo.cpp
src/forms/ConnectInfo.h src/forms/ConnectInfo.h
src/forms/resources.qrc 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.cpp
src/WebSocketApi.h src/WebSocketApi.h)
src/websocketserver/WebSocketServer.cpp
src/websocketserver/WebSocketServer_Protocol.cpp target_sources(
src/websocketserver/WebSocketServer.h obs-websocket
src/websocketserver/rpc/WebSocketSession.cpp PRIVATE # cmake-format: sortable
src/websocketserver/rpc/WebSocketSession.h src/websocketserver/rpc/WebSocketSession.h
src/websocketserver/types/WebSocketCloseCode.h src/websocketserver/types/WebSocketCloseCode.h
src/websocketserver/types/WebSocketOpCode.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.cpp
src/eventhandler/EventHandler_General.cpp src/eventhandler/EventHandler.h
src/eventhandler/EventHandler_Config.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_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_Outputs.cpp
src/eventhandler/EventHandler_SceneItems.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_Ui.cpp
src/eventhandler/EventHandler.h src/eventhandler/types/EventSubscription.h)
src/eventhandler/types/EventSubscription.h
src/requesthandler/RequestHandler.cpp target_sources(
src/requesthandler/RequestHandler_General.cpp obs-websocket
src/requesthandler/RequestHandler_Config.cpp PRIVATE # cmake-format: sortable
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.cpp
src/requesthandler/RequestBatchHandler.h src/requesthandler/RequestBatchHandler.h
src/requesthandler/RequestHandler.cpp
src/requesthandler/RequestHandler.h
src/requesthandler/RequestHandler_Config.cpp
src/requesthandler/RequestHandler_Filters.cpp
src/requesthandler/RequestHandler_General.cpp
src/requesthandler/RequestHandler_Inputs.cpp
src/requesthandler/RequestHandler_MediaInputs.cpp
src/requesthandler/RequestHandler_Outputs.cpp
src/requesthandler/RequestHandler_Record.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/rpc/Request.cpp src/requesthandler/rpc/Request.cpp
src/requesthandler/rpc/Request.h src/requesthandler/rpc/Request.h
src/requesthandler/rpc/RequestBatchRequest.cpp src/requesthandler/rpc/RequestBatchRequest.cpp
src/requesthandler/rpc/RequestBatchRequest.h src/requesthandler/rpc/RequestBatchRequest.h
src/requesthandler/rpc/RequestResult.cpp src/requesthandler/rpc/RequestResult.cpp
src/requesthandler/rpc/RequestResult.h src/requesthandler/rpc/RequestResult.h
src/requesthandler/types/RequestStatus.h
src/requesthandler/types/RequestBatchExecutionType.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.cpp
src/utils/Crypto.h src/utils/Crypto.h
src/utils/Json.cpp src/utils/Json.cpp
src/utils/Json.h src/utils/Json.h
src/utils/Obs.cpp src/utils/Obs.cpp
src/utils/Obs_StringHelper.cpp src/utils/Obs.h
src/utils/Obs_NumberHelper.cpp src/utils/Obs_ActionHelper.cpp
src/utils/Obs_ArrayHelper.cpp src/utils/Obs_ArrayHelper.cpp
src/utils/Obs_NumberHelper.cpp
src/utils/Obs_ObjectHelper.cpp src/utils/Obs_ObjectHelper.cpp
src/utils/Obs_SearchHelper.cpp src/utils/Obs_SearchHelper.cpp
src/utils/Obs_ActionHelper.cpp src/utils/Obs_StringHelper.cpp
src/utils/Obs.h
src/utils/Obs_VolumeMeter.cpp src/utils/Obs_VolumeMeter.cpp
src/utils/Obs_VolumeMeter.h src/utils/Obs_VolumeMeter.h
src/utils/Obs_VolumeMeter_Helpers.h src/utils/Obs_VolumeMeter_Helpers.h
src/utils/Platform.cpp src/utils/Platform.cpp
src/utils/Platform.h src/utils/Platform.h
src/utils/Compat.cpp src/utils/Utils.h)
src/utils/Compat.h
src/utils/Utils.h
deps/qr/cpp/QrCode.cpp
deps/qr/cpp/QrCode.hpp)
target_include_directories( 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 $<$<BOOL:${PLUGIN_TESTS}>:PLUGIN_TESTS>
$<$<PLATFORM_ID:Windows>:_WEBSOCKETPP_CPP11_STL_> $<$<PLATFORM_ID:Windows>:_WIN32_WINNT=0x0603>)
target_compile_options(
obs-websocket obs-websocket
PRIVATE ${Qt5Core_INCLUDES} ${Qt5Widgets_INCLUDES} ${Qt5Svg_INCLUDES} PRIVATE $<$<PLATFORM_ID:Windows>:/wd4267>
${Qt5Network_INCLUDES} "deps/asio/asio/include" "deps/websocketpp") $<$<PLATFORM_ID:Windows>:/wd4996>
$<$<COMPILE_LANG_AND_ID:CXX,GNU,AppleClang,Clang>:-Wall>
$<$<COMPILE_LANG_AND_ID:CXX,GNU,AppleClang,Clang>:-Wno-error=float-conversion>
$<$<COMPILE_LANG_AND_ID:CXX,GNU,AppleClang,Clang>:-Wno-error=shadow>
$<$<COMPILE_LANG_AND_ID:CXX,GNU>:-Wno-error=format-overflow>
$<$<COMPILE_LANG_AND_ID:CXX,GNU>:-Wno-error=int-conversion>
$<$<COMPILE_LANG_AND_ID:CXX,GNU>:-Wno-error=comment>
$<$<COMPILE_LANG_AND_ID:CXX,GNU>:-Wno-error=deprecated-declarations>
$<$<COMPILE_LANG_AND_ID:CXX,AppleClang,Clang>:-Wno-error=null-pointer-subtraction>
$<$<COMPILE_LANG_AND_ID:CXX,AppleClang,Clang>:-Wno-error=deprecated-declarations>
$<$<COMPILE_LANG_AND_ID:CXX,AppleClang,Clang>:-Wno-error=implicit-int-conversion>
$<$<COMPILE_LANG_AND_ID:CXX,AppleClang,Clang>:-Wno-error=shorten-64-to-32>
$<$<COMPILE_LANG_AND_ID:CXX,AppleClang,Clang>:-Wno-comma>
$<$<COMPILE_LANG_AND_ID:CXX,AppleClang,Clang>:-Wno-quoted-include-in-framework-header>)
target_link_libraries( target_link_libraries(
obs-websocket obs-websocket
PRIVATE OBS::libobs PRIVATE OBS::libobs
OBS::frontend-api OBS::frontend-api
OBS::websocket-api
Qt::Core Qt::Core
Qt::Widgets Qt::Widgets
Qt::Svg Qt::Svg
Qt::Network Qt::Network
nlohmann_json::nlohmann_json) nlohmann_json::nlohmann_json
Websocketpp::Websocketpp
Asio::Asio
qrcodegencpp::qrcodegencpp)
target_compile_features(obs-websocket PRIVATE cxx_std_17) target_link_options(obs-websocket PRIVATE $<$<PLATFORM_ID:Windows>:/IGNORE:4099>)
set_target_properties(obs-websocket PROPERTIES FOLDER "plugins/obs-websocket") set_target_properties_obs(
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)
else()
target_compile_options(
obs-websocket obs-websocket
PRIVATE PROPERTIES FOLDER plugins
-Wall PREFIX ""
"$<$<COMPILE_LANG_AND_ID:CXX,GNU>:-Wno-error=format-overflow>" AUTOMOC ON
"$<$<COMPILE_LANG_AND_ID:CXX,AppleClang,Clang>:-Wno-error=null-pointer-subtraction;-Wno-error=deprecated-declarations>" AUTOUIC ON
) AUTORCC ON)
endif()
# Final CMake helpers if(OS_WINDOWS)
setup_plugin_target(obs-websocket) set_property(
setup_target_resources(obs-websocket "obs-plugins/obs-websocket") TARGET obs-websocket
APPEND
PROPERTY AUTORCC_OPTIONS --format-version 1)
endif()

View File

@ -13,7 +13,7 @@ WebSocket API for OBS Studio.
## Downloads ## 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. 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,21 +31,32 @@ It is **highly recommended** to keep obs-websocket protected with a password aga
### Client software ### Client software
- [Macro Deck](https://macrodeck.org/)
- [Touch Portal](https://www.touch-portal.com/) - [Touch Portal](https://www.touch-portal.com/)
- [Twitchat](https://twitchat.fr/) - [Twitchat](https://twitchat.fr/)
- [OBS-web](https://github.com/Niek/obs-web) - hosted client at [obs-web.niek.tv/](http://obs-web.niek.tv/) - [OBS-web](https://github.com/Niek/obs-web) - hosted client at [obs-web.niek.tv/](http://obs-web.niek.tv/)
- [Streamer.bot](https://streamer.bot/)
- [Deckboard](https://deckboard.app/)
- [OBS Blade](https://github.com/Kounex/obs_blade)
- [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/)
### Client libraries (for developers) ### Client libraries (for developers)
Here's a list of available language APIs for obs-websocket: 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.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 - 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 - 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) - 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 - Go: [goobs](https://github.com/andreykaipov/goobs) by andreykaipov
- Dart/Flutter (can target all supported platforms): [obs_websocket](https://github.com/faithoflifedev/obs_websocket) by faithoflifedev - Dart/Flutter (can target all supported platforms): [obs_websocket](https://github.com/faithoflifedev/obs_websocket) by faithoflifedev
- Java: [obs-websocket-java](https://github.com/obs-websocket-community-projects/obs-websocket-java) by OBS Websocket Community
The 5.x server is a typical WebSocket server running by default on port 4455 (the port number can be changed in the Settings dialog under `Tools`). The 5.x server is a typical WebSocket server running by default on port 4455 (the port number can be changed in the Settings dialog under `Tools`).
The protocol we use is documented in [PROTOCOL.md](docs/generated/protocol.md). The protocol we use is documented in [PROTOCOL.md](docs/generated/protocol.md).
@ -56,12 +67,11 @@ We'd like to know what you're building with obs-websocket! If you do something i
### Code Contributors ### 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).
<a href="https://github.com/obsproject/obs-websocket/graphs/contributors"><img src="https://opencollective.com/obs-websocket-dev/contributors.svg?width=890&button=false" /></a>
### Financial Contributors ### 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 #### Individuals

188
cmake/legacy.cmake Normal file
View File

@ -0,0 +1,188 @@
project(obs-websocket VERSION 5.5.2)
set(OBS_WEBSOCKET_RPC_VERSION 1)
option(ENABLE_WEBSOCKET "Enable building OBS with websocket plugin" ON)
add_library(obs-websocket-api INTERFACE)
add_library(OBS::websocket-api ALIAS obs-websocket-api)
target_sources(obs-websocket-api INTERFACE $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/lib/obs-websocket-api.h>
$<INSTALL_INTERFACE:${OBS_INCLUDE_DESTINATION}/obs-websocket-api.h>)
target_link_libraries(obs-websocket-api INTERFACE OBS::libobs)
target_include_directories(obs-websocket-api INTERFACE $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/lib>
$<INSTALL_INTERFACE:${OBS_INCLUDE_DESTINATION}>)
set_target_properties(obs-websocket-api PROPERTIES PUBLIC_HEADER lib/obs-websocket-api.h)
export_target(obs-websocket-api)
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
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
OBS::websocket-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
"$<$<COMPILE_LANG_AND_ID:CXX,GNU>:-Wno-error=format-overflow>"
"$<$<COMPILE_LANG_AND_ID:CXX,AppleClang,Clang>:-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")

28
cmake/macos/Info.plist.in Normal file
View File

@ -0,0 +1,28 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>CFBundleName</key>
<string>obs-websocket</string>
<key>CFBundleIdentifier</key>
<string>com.obsproject.obs-websocket</string>
<key>CFBundleVersion</key>
<string>${MACOSX_BUNDLE_BUNDLE_VERSION}</string>
<key>CFBundleShortVersionString</key>
<string>${MACOSX_BUNDLE_SHORT_VERSION_STRING}</string>
<key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string>
<key>CFBundleExecutable</key>
<string>obs-websocket</string>
<key>CFBundlePackageType</key>
<string>BNDL</string>
<key>CFBundleSupportedPlatforms</key>
<array>
<string>MacOSX</string>
</array>
<key>LSMinimumSystemVersion</key>
<string>${CMAKE_OSX_DEPLOYMENT_TARGET}</string>
<key>NSHumanReadableCopyright</key>
<string>(c) 2016-${CURRENT_YEAR} Stéphane Lepin, Kyle Manning</string>
</dict>
</plist>

View File

@ -0,0 +1,14 @@
add_library(obs-websocket-api INTERFACE)
add_library(OBS::websocket-api ALIAS obs-websocket-api)
target_sources(obs-websocket-api INTERFACE $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/lib/obs-websocket-api.h>
$<INSTALL_INTERFACE:${OBS_INCLUDE_DESTINATION}/obs-websocket-api.h>)
target_link_libraries(obs-websocket-api INTERFACE OBS::libobs)
target_include_directories(obs-websocket-api INTERFACE "$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/lib>"
"$<INSTALL_INTERFACE:${OBS_INCLUDE_DESTINATION}>")
set_target_properties(obs-websocket-api PROPERTIES PREFIX "" PUBLIC_HEADER lib/obs-websocket-api.h)
target_export(obs-websocket-api)

View File

@ -0,0 +1,8 @@
@PACKAGE_INIT@
include(CMakeFindDependencyMacro)
find_dependency(libobs REQUIRED)
include("${CMAKE_CURRENT_LIST_DIR}/@TARGETS_EXPORT_NAME@.cmake")
check_required_components("@PROJECT_NAME@")

35
data/locale/af-ZA.ini Normal file
View File

@ -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."

View File

@ -1,5 +1,5 @@
OBSWebSocket.Plugin.Description="التحكم عن بعد في استوديو OBS من خلال WebSocket" OBSWebSocket.Plugin.Description="التحكم عن بعد في استوديو OBS من خلال WebSocket"
OBSWebSocket.Settings.DialogTitle="إعدادات obs-websocket" OBSWebSocket.Settings.DialogTitle="إعدادات خادم WebSocket"
OBSWebSocket.Settings.PluginSettingsTitle="إعدادات الإضافات" OBSWebSocket.Settings.PluginSettingsTitle="إعدادات الإضافات"
OBSWebSocket.Settings.ServerEnable="تمكين خادم WebSocket" OBSWebSocket.Settings.ServerEnable="تمكين خادم WebSocket"
OBSWebSocket.Settings.AlertsEnable="تمكين تنبيهات شريط النظام" OBSWebSocket.Settings.AlertsEnable="تمكين تنبيهات شريط النظام"
@ -39,5 +39,3 @@ OBSWebSocket.TrayNotification.AuthenticationFailed.Title="فشل مصادقة We
OBSWebSocket.TrayNotification.AuthenticationFailed.Body="فشل العميل %1 في المصادقة." OBSWebSocket.TrayNotification.AuthenticationFailed.Body="فشل العميل %1 في المصادقة."
OBSWebSocket.TrayNotification.Disconnected.Title="تم قطع اتصال عميل WebSocket" OBSWebSocket.TrayNotification.Disconnected.Title="تم قطع اتصال عميل WebSocket"
OBSWebSocket.TrayNotification.Disconnected.Body="العميل %1 قطع الاتصال." OBSWebSocket.TrayNotification.Disconnected.Body="العميل %1 قطع الاتصال."
OBSWebSocket.Server.StartFailed.Title="فشل خادم WebSocket"
OBSWebSocket.Server.StartFailed.Message="فشل تشغيل خادم WebSocket. قد يكون منفذ TCP %1 قيد الاستخدام في تطبيق آخر على هذا النظام. حاول تعيين منفذ TCP مختلف في إعدادات خادم WebSocket، أو إيقاف أي تطبيق يمكن أن يستخدم هذا المنفذ.\n رسالة الخطأ: %2"

41
data/locale/be-BY.ini Normal file
View File

@ -0,0 +1,41 @@
OBSWebSocket.Plugin.Description="Аддаленае кіраванне OBS Studio праз 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.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="Паведамленні I/O"
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 адключаны."

View File

@ -1,10 +1,10 @@
OBSWebSocket.Plugin.Description="Control remot de l'OBS Studio mitjançant un servidor web" OBSWebSocket.Plugin.Description="Control remot de l'OBS Studio mitjançant WebSocket"
OBSWebSocket.Settings.DialogTitle="Configuració del servidor web de l'OBS" OBSWebSocket.Settings.DialogTitle="Configuració del servidor WebSocket"
OBSWebSocket.Settings.PluginSettingsTitle="Configuració del complement" 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.AlertsEnable="Habilita les notificacions a la barra de tasques"
OBSWebSocket.Settings.DebugEnable="Habilita l'informe de depuració" 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.ServerSettingsTitle="Configuració del servidor"
OBSWebSocket.Settings.AuthRequired="Habilita l'autenticació" OBSWebSocket.Settings.AuthRequired="Habilita l'autenticació"
OBSWebSocket.Settings.Password="Contrasenya del servidor" 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.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.ShowConnectInfoWarningInfoText="Segur que voleu mostrar la vostra informació de connexió?"
OBSWebSocket.Settings.Save.UserPasswordWarningTitle="Atenció: Risc potencial de seguretat" 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.UserPasswordWarningInfoText="Segur que voleu utilitzar la vostra contrasenya?"
OBSWebSocket.Settings.Save.PasswordInvalidErrorTitle="Error: Configuració no vàlida" OBSWebSocket.Settings.Save.PasswordInvalidErrorTitle="Error: Configuració no vàlida"
OBSWebSocket.Settings.Save.PasswordInvalidErrorMessage="Utilitzeu una contrasenya de 6 o més caràcters." 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.RemoteAddressColumnTitle="Adreça remota"
OBSWebSocket.SessionTable.SessionDurationColumnTitle="Durada de la sessió" OBSWebSocket.SessionTable.SessionDurationColumnTitle="Durada de la sessió"
OBSWebSocket.SessionTable.MessagesInOutColumnTitle="Missatges d'entrada/sortida" OBSWebSocket.SessionTable.MessagesInOutColumnTitle="Missatges d'entrada/sortida"
OBSWebSocket.SessionTable.IdentifiedTitle="Identificat" OBSWebSocket.SessionTable.IdentifiedTitle="Identificat"
OBSWebSocket.SessionTable.KickButtonColumnTitle="Expuls?" OBSWebSocket.SessionTable.KickButtonColumnTitle="Expulsar?"
OBSWebSocket.SessionTable.KickButtonText="Expulsa" 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.CopyText="Copia"
OBSWebSocket.ConnectInfo.ServerIp="Adreça IP (més acurada)" OBSWebSocket.ConnectInfo.ServerIp="Adreça IP (més acurada)"
OBSWebSocket.ConnectInfo.ServerPort="Port" OBSWebSocket.ConnectInfo.ServerPort="Port"
OBSWebSocket.ConnectInfo.ServerPassword="Contrasenya" OBSWebSocket.ConnectInfo.ServerPassword="Contrasenya"
OBSWebSocket.ConnectInfo.ServerPasswordPlaceholderText="[Autenticació inhabilitada]" OBSWebSocket.ConnectInfo.ServerPasswordPlaceholderText="[Autenticació inhabilitada]"
OBSWebSocket.ConnectInfo.QrTitle="QR de la connexió" 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.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.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.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"

View File

@ -1,5 +1,5 @@
OBSWebSocket.Plugin.Description="Vzdálené ovládání OBS Studia přes WebSocket" 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.PluginSettingsTitle="Nastavení pluginu"
OBSWebSocket.Settings.ServerEnable="Povolit WebSocketový server" OBSWebSocket.Settings.ServerEnable="Povolit WebSocketový server"
OBSWebSocket.Settings.AlertsEnable="Povolit upozornění v systémové liště" 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.AuthenticationFailed.Body="Klient %1 nebyl přihlášen"
OBSWebSocket.TrayNotification.Disconnected.Title="WebSocket klient se odpojil" OBSWebSocket.TrayNotification.Disconnected.Title="WebSocket klient se odpojil"
OBSWebSocket.TrayNotification.Disconnected.Body="Klient %1 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"

View File

@ -1,5 +1,5 @@
OBSWebSocket.Plugin.Description="Fjernstyring af OBS Studio via WebSocket" OBSWebSocket.Plugin.Description="Fjernstyring af OBS Studio via WebSocket"
OBSWebSocket.Settings.DialogTitle="obs-websocket Indstillinger" OBSWebSocket.Settings.DialogTitle="WebSocket-serverindstillinger"
OBSWebSocket.Settings.PluginSettingsTitle="Plugin-indstillinger" OBSWebSocket.Settings.PluginSettingsTitle="Plugin-indstillinger"
OBSWebSocket.Settings.ServerEnable="Aktivér WebSocket-server" OBSWebSocket.Settings.ServerEnable="Aktivér WebSocket-server"
OBSWebSocket.Settings.AlertsEnable="Aktivér Systembakke Alarmer" OBSWebSocket.Settings.AlertsEnable="Aktivér Systembakke Alarmer"
@ -39,5 +39,3 @@ OBSWebSocket.TrayNotification.AuthenticationFailed.Title="WebSocket godkendelses
OBSWebSocket.TrayNotification.AuthenticationFailed.Body="Klienten %1 kunne ikke godkendes." OBSWebSocket.TrayNotification.AuthenticationFailed.Body="Klienten %1 kunne ikke godkendes."
OBSWebSocket.TrayNotification.Disconnected.Title="WebSocket-klient frakoblet" OBSWebSocket.TrayNotification.Disconnected.Title="WebSocket-klient frakoblet"
OBSWebSocket.TrayNotification.Disconnected.Body="Klient %1 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"

View File

@ -1,10 +1,10 @@
OBSWebSocket.Plugin.Description="OBS Studio per WebSocket fernsteuern" 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.PluginSettingsTitle="Plugineinstellungen"
OBSWebSocket.Settings.ServerEnable="WebSocket-Server aktivieren" OBSWebSocket.Settings.ServerEnable="WebSocket-Server aktivieren"
OBSWebSocket.Settings.AlertsEnable="Warnungen im Infobereich aktivieren" OBSWebSocket.Settings.AlertsEnable="Warnungen im Infobereich aktivieren"
OBSWebSocket.Settings.DebugEnable="Debug-Logging 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.ServerSettingsTitle="Servereinstellungen"
OBSWebSocket.Settings.AuthRequired="Authentifizierung aktivieren" OBSWebSocket.Settings.AuthRequired="Authentifizierung aktivieren"
OBSWebSocket.Settings.Password="Serverpasswort" OBSWebSocket.Settings.Password="Serverpasswort"
@ -28,7 +28,7 @@ OBSWebSocket.SessionTable.KickButtonColumnTitle="Entfernen?"
OBSWebSocket.SessionTable.KickButtonText="Entfernen" OBSWebSocket.SessionTable.KickButtonText="Entfernen"
OBSWebSocket.ConnectInfo.DialogTitle="WebSocket-Verbindungsinformationen" OBSWebSocket.ConnectInfo.DialogTitle="WebSocket-Verbindungsinformationen"
OBSWebSocket.ConnectInfo.CopyText="Kopieren" OBSWebSocket.ConnectInfo.CopyText="Kopieren"
OBSWebSocket.ConnectInfo.ServerIp="Server-IP (geschätzt)" OBSWebSocket.ConnectInfo.ServerIp="Server-IP (Geschätzt)"
OBSWebSocket.ConnectInfo.ServerPort="Serverport" OBSWebSocket.ConnectInfo.ServerPort="Serverport"
OBSWebSocket.ConnectInfo.ServerPassword="Serverpasswort" OBSWebSocket.ConnectInfo.ServerPassword="Serverpasswort"
OBSWebSocket.ConnectInfo.ServerPasswordPlaceholderText="Authentifizierung deaktiviert" 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.AuthenticationFailed.Body="Client %1 konnte sich nicht authentifizieren."
OBSWebSocket.TrayNotification.Disconnected.Title="WebSocket-Client getrennt" OBSWebSocket.TrayNotification.Disconnected.Title="WebSocket-Client getrennt"
OBSWebSocket.TrayNotification.Disconnected.Body="Client %1 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"

41
data/locale/el-GR.ini Normal file
View File

@ -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 αποσυνδέθηκε."

1
data/locale/en-GB.ini Normal file
View File

@ -0,0 +1 @@
#

View File

@ -1,6 +1,6 @@
OBSWebSocket.Plugin.Description="Remote-control of OBS Studio through WebSocket" OBSWebSocket.Plugin.Description="Remote-control of OBS Studio through WebSocket"
OBSWebSocket.Settings.DialogTitle="obs-websocket Settings" OBSWebSocket.Settings.DialogTitle="WebSocket Server Settings"
OBSWebSocket.Settings.PluginSettingsTitle="Plugin Settings" OBSWebSocket.Settings.PluginSettingsTitle="Plugin Settings"
OBSWebSocket.Settings.ServerEnable="Enable WebSocket server" OBSWebSocket.Settings.ServerEnable="Enable WebSocket server"
@ -45,6 +45,3 @@ OBSWebSocket.TrayNotification.AuthenticationFailed.Title="WebSocket Authenticati
OBSWebSocket.TrayNotification.AuthenticationFailed.Body="Client %1 failed to authenticate." OBSWebSocket.TrayNotification.AuthenticationFailed.Body="Client %1 failed to authenticate."
OBSWebSocket.TrayNotification.Disconnected.Title="WebSocket Client Disconnected" OBSWebSocket.TrayNotification.Disconnected.Title="WebSocket Client Disconnected"
OBSWebSocket.TrayNotification.Disconnected.Body="Client %1 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"

View File

@ -1,5 +1,5 @@
OBSWebSocket.Plugin.Description="Control remoto de OBS Studio a través de WebSocket" 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.PluginSettingsTitle="Ajustes del plugin"
OBSWebSocket.Settings.ServerEnable="Habilitar servidor WebSocket" OBSWebSocket.Settings.ServerEnable="Habilitar servidor WebSocket"
OBSWebSocket.Settings.AlertsEnable="Habilitar alertas en la bandeja del sistema" 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.AuthenticationFailed.Body="El cliente %1 no se pudo autenticar."
OBSWebSocket.TrayNotification.Disconnected.Title="Cliente WebSocket desconectado" OBSWebSocket.TrayNotification.Disconnected.Title="Cliente WebSocket desconectado"
OBSWebSocket.TrayNotification.Disconnected.Body="Cliente %1 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"

View File

@ -1,5 +1,5 @@
OBSWebSocket.Plugin.Description="OBS Studio kaugjuhtimine WebSocketi kaudu" 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.PluginSettingsTitle="Plugina seaded"
OBSWebSocket.Settings.ServerEnable="Luba WebSocket server" OBSWebSocket.Settings.ServerEnable="Luba WebSocket server"
OBSWebSocket.Settings.AlertsEnable="Luba hoiatused tegumireal" 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.AuthenticationFailed.Body="Kliendi %1 autentimine ebaõnnestus."
OBSWebSocket.TrayNotification.Disconnected.Title="WebSocket kliendi ühendus katkenud" OBSWebSocket.TrayNotification.Disconnected.Title="WebSocket kliendi ühendus katkenud"
OBSWebSocket.TrayNotification.Disconnected.Body="Kliendi %1 ü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"

40
data/locale/eu-ES.ini Normal file
View File

@ -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."

View File

@ -1,3 +1,41 @@
OBSWebSocket.Plugin.Description="کنترل از راه دور OBS Studio از طریق WebSocket"
OBSWebSocket.Settings.DialogTitle="تنظیمات سرور سوکت وب"
OBSWebSocket.Settings.PluginSettingsTitle="تنظیمات پلاگین"
OBSWebSocket.Settings.ServerEnable="سرور سوکت وب را فعال کنید"
OBSWebSocket.Settings.AlertsEnable="هشدارهای سینی سیستم را فعال کنید"
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="جلسات سوکت وب متصل"
OBSWebSocket.SessionTable.RemoteAddressColumnTitle="آدرس از راه دور"
OBSWebSocket.SessionTable.SessionDurationColumnTitle="مدت زمان جلسه"
OBSWebSocket.SessionTable.MessagesInOutColumnTitle="پیام های ورودی/خارجی"
OBSWebSocket.SessionTable.IdentifiedTitle="تایید هویت شده"
OBSWebSocket.SessionTable.KickButtonColumnTitle="لگد زدن؟" OBSWebSocket.SessionTable.KickButtonColumnTitle="لگد زدن؟"
OBSWebSocket.SessionTable.KickButtonText="اخراج" OBSWebSocket.SessionTable.KickButtonText="اخراج"
OBSWebSocket.ConnectInfo.DialogTitle="اطلاعات اتصال سوکت وب"
OBSWebSocket.ConnectInfo.CopyText="رونوشت‌" OBSWebSocket.ConnectInfo.CopyText="رونوشت‌"
OBSWebSocket.ConnectInfo.ServerIp="IP سرور (بهترین حدس)"
OBSWebSocket.ConnectInfo.ServerPort="پورت سرور"
OBSWebSocket.ConnectInfo.ServerPassword="رمز سرور"
OBSWebSocket.ConnectInfo.ServerPasswordPlaceholderText="[احراز غیر فعال]"
OBSWebSocket.ConnectInfo.QrTitle="QR را وصل کنید"
OBSWebSocket.TrayNotification.Identified.Title="اتصال سوکت وب جدید"
OBSWebSocket.TrayNotification.Identified.Body="سرویس گیرنده %1 شناسایی شد."
OBSWebSocket.TrayNotification.AuthenticationFailed.Title="خرابی تأیید اعتبار سوکت وب"
OBSWebSocket.TrayNotification.AuthenticationFailed.Body="سرویس گیرنده %1 احراز هویت نشد."
OBSWebSocket.TrayNotification.Disconnected.Title="سرویس گیرنده سوکت وب قطع شد"
OBSWebSocket.TrayNotification.Disconnected.Body="سرویس گیرنده %1 قطع شد."

View File

@ -1,5 +1,5 @@
OBSWebSocket.Plugin.Description="OBS Studion etähallinta WebSocketin kautta" 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.PluginSettingsTitle="Liitännäisen asetukset"
OBSWebSocket.Settings.ServerEnable="Ota WebSocket-palvelin käyttöön" OBSWebSocket.Settings.ServerEnable="Ota WebSocket-palvelin käyttöön"
OBSWebSocket.Settings.AlertsEnable="Ota ilmoitusalueen ilmoitukset 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.AuthenticationFailed.Body="Asiakas %1 todennus epäonnistui."
OBSWebSocket.TrayNotification.Disconnected.Title="WebSocket-asiakas katkaisi yhteyden" OBSWebSocket.TrayNotification.Disconnected.Title="WebSocket-asiakas katkaisi yhteyden"
OBSWebSocket.TrayNotification.Disconnected.Body="Asiakas %1 on katkaistu." 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"

37
data/locale/fil-PH.ini Normal file
View File

@ -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."

View File

@ -1,5 +1,5 @@
OBSWebSocket.Plugin.Description="Contrôle à distance d'OBS Studio via WebSocket" 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.PluginSettingsTitle="Paramètres du plugin"
OBSWebSocket.Settings.ServerEnable="Activer le serveur WebSocket" OBSWebSocket.Settings.ServerEnable="Activer le serveur WebSocket"
OBSWebSocket.Settings.AlertsEnable="Activer les alertes de la zone de notification" 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.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.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.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.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.Title="Sessions WebSocket connectées"
OBSWebSocket.SessionTable.RemoteAddressColumnTitle="Adresse distante" OBSWebSocket.SessionTable.RemoteAddressColumnTitle="Adresse distante"
OBSWebSocket.SessionTable.SessionDurationColumnTitle="Durée de session" OBSWebSocket.SessionTable.SessionDurationColumnTitle="Durée de session"
@ -30,7 +30,7 @@ OBSWebSocket.ConnectInfo.DialogTitle="Informations de connexion WebSocket"
OBSWebSocket.ConnectInfo.CopyText="Copier" OBSWebSocket.ConnectInfo.CopyText="Copier"
OBSWebSocket.ConnectInfo.ServerIp="IP du serveur (meilleure estimation)" OBSWebSocket.ConnectInfo.ServerIp="IP du serveur (meilleure estimation)"
OBSWebSocket.ConnectInfo.ServerPort="Port serveur" 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.ServerPasswordPlaceholderText="[Authentification désactivée]"
OBSWebSocket.ConnectInfo.QrTitle="QR code de connexion" OBSWebSocket.ConnectInfo.QrTitle="QR code de connexion"
OBSWebSocket.TrayNotification.Identified.Title="Nouvelle connexion WebSocket" 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.AuthenticationFailed.Body="Échec d'authentification du client %1."
OBSWebSocket.TrayNotification.Disconnected.Title="Client WebSocket déconnecté" OBSWebSocket.TrayNotification.Disconnected.Title="Client WebSocket déconnecté"
OBSWebSocket.TrayNotification.Disconnected.Body="Client %1 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"

6
data/locale/gl-ES.ini Normal file
View File

@ -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."

View File

@ -1,5 +1,5 @@
OBSWebSocket.Plugin.Description="שליטה מרחוק על OBS Studio באמצעות WebSocket" OBSWebSocket.Plugin.Description="שליטה מרחוק על OBS Studio באמצעות WebSocket"
OBSWebSocket.Settings.DialogTitle="הגדרות obs-websocket" OBSWebSocket.Settings.DialogTitle="הגדרות שרת WebSocket"
OBSWebSocket.Settings.PluginSettingsTitle="הגדרות תוסף" OBSWebSocket.Settings.PluginSettingsTitle="הגדרות תוסף"
OBSWebSocket.Settings.ServerEnable="הפעלת שרת WebSocket" OBSWebSocket.Settings.ServerEnable="הפעלת שרת WebSocket"
OBSWebSocket.Settings.AlertsEnable="הפעלת התראות במגש המערכת" OBSWebSocket.Settings.AlertsEnable="הפעלת התראות במגש המערכת"
@ -39,5 +39,3 @@ OBSWebSocket.TrayNotification.AuthenticationFailed.Title="אימות WebSocket
OBSWebSocket.TrayNotification.AuthenticationFailed.Body="לקוח %1 נכשל באימות" OBSWebSocket.TrayNotification.AuthenticationFailed.Body="לקוח %1 נכשל באימות"
OBSWebSocket.TrayNotification.Disconnected.Title="לקוח WebSocket התנתק" OBSWebSocket.TrayNotification.Disconnected.Title="לקוח WebSocket התנתק"
OBSWebSocket.TrayNotification.Disconnected.Body="לקוח %1 התנתק." OBSWebSocket.TrayNotification.Disconnected.Body="לקוח %1 התנתק."
OBSWebSocket.Server.StartFailed.Title="שגיאת שרת WebSocket"
OBSWebSocket.Server.StartFailed.Message="שרת ה-WebSocket נכשל בהפעלה. ייתכן שפורט TCP %1 כבר נמצא בשימוש במקום אחר במערכת זו על ידי יישום אחר. יש לנסות להגדיר פורט TCP אחר בהגדרות שרת WebSocket, או לעצור כל יישום שעשוי להשתמש בפורט זה.\nהודעת שגיאה: %2"

View File

@ -1,5 +1,5 @@
OBSWebSocket.Plugin.Description="WebSocket के माध्यम से OBS स्टूडियो का रिमोट-कंट्रोल" OBSWebSocket.Plugin.Description="WebSocket के माध्यम से OBS स्टूडियो का रिमोट-कंट्रोल"
OBSWebSocket.Settings.DialogTitle="obs-websocket सेटिंग्स" OBSWebSocket.Settings.DialogTitle="वेबसॉकेट सर्वर सेटिंग्स"
OBSWebSocket.Settings.PluginSettingsTitle="प्लगइन सेटिंग्स" OBSWebSocket.Settings.PluginSettingsTitle="प्लगइन सेटिंग्स"
OBSWebSocket.Settings.ServerEnable="WebSocket सर्वर सक्षम करें" OBSWebSocket.Settings.ServerEnable="WebSocket सर्वर सक्षम करें"
OBSWebSocket.Settings.AlertsEnable="सिस्टम ट्रे अलर्ट सक्षम करें" OBSWebSocket.Settings.AlertsEnable="सिस्टम ट्रे अलर्ट सक्षम करें"
@ -39,5 +39,3 @@ OBSWebSocket.TrayNotification.AuthenticationFailed.Title="WebSocket सत्य
OBSWebSocket.TrayNotification.AuthenticationFailed.Body="क्लाइंट %1प्रमाणित करने में विफल रहा." OBSWebSocket.TrayNotification.AuthenticationFailed.Body="क्लाइंट %1प्रमाणित करने में विफल रहा."
OBSWebSocket.TrayNotification.Disconnected.Title="वेबसॉकेट क्लाइंट डिस्कनेक्ट हो गया" OBSWebSocket.TrayNotification.Disconnected.Title="वेबसॉकेट क्लाइंट डिस्कनेक्ट हो गया"
OBSWebSocket.TrayNotification.Disconnected.Body="क्लाइंट %1 डिस्कनेक्ट हो गया." OBSWebSocket.TrayNotification.Disconnected.Body="क्लाइंट %1 डिस्कनेक्ट हो गया."
OBSWebSocket.Server.StartFailed.Title="वेबसॉकेट सर्वर विफलता"
OBSWebSocket.Server.StartFailed.Message="WebSocket सर्वर प्रारंभ करने में विफल रहा. TCP पोर्ट %1 पहले से ही इस सिस्टम पर किसी अन्य एप्लिकेशन द्वारा कहीं और उपयोग में हो सकता है. वेबसॉकेट सर्वर सेटिंग्स में एक अलग TCP पोर्ट सेट करने का प्रयास करें, या इस पोर्ट का उपयोग करने वाले किसी भी एप्लिकेशन को रोकें.\n त्रुटि संदेश : %2"

10
data/locale/hr-HR.ini Normal file
View File

@ -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"

View File

@ -1,5 +1,5 @@
OBSWebSocket.Plugin.Description="Az OBS Studio távvezérlése WebSocketen keresztül" 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.PluginSettingsTitle="Bővítménybeállítások"
OBSWebSocket.Settings.ServerEnable="WebSocket-kiszolgáló engedélyezése" OBSWebSocket.Settings.ServerEnable="WebSocket-kiszolgáló engedélyezése"
OBSWebSocket.Settings.AlertsEnable="Rendszertálca-riasztások bekapcsolása" 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.AuthenticationFailed.Body="A(z) %1 kliens hitelesítése sikertelen."
OBSWebSocket.TrayNotification.Disconnected.Title="A WebSocket-kliens bontotta a kapcsolatot" OBSWebSocket.TrayNotification.Disconnected.Title="A WebSocket-kliens bontotta a kapcsolatot"
OBSWebSocket.TrayNotification.Disconnected.Body="A(z) %1 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"

View File

@ -1,5 +1,5 @@
OBSWebSocket.Plugin.Description="OBS Studio-ի հեռակառավարումը WebSocket-ի միջոցով" OBSWebSocket.Plugin.Description="OBS Studio-ի հեռակառավարումը WebSocket-ի միջոցով"
OBSWebSocket.Settings.DialogTitle="obs-websocket կարգավորումներ" OBSWebSocket.Settings.DialogTitle="WebSocket Սպասարկչի Կարգավորումները"
OBSWebSocket.Settings.PluginSettingsTitle="Միացնիչի կարգավորումներ" OBSWebSocket.Settings.PluginSettingsTitle="Միացնիչի կարգավորումներ"
OBSWebSocket.Settings.ServerEnable="Միացնել WebSocket սերվերը" OBSWebSocket.Settings.ServerEnable="Միացնել WebSocket սերվերը"
OBSWebSocket.Settings.AlertsEnable="Միացնել սկուտեղի ծանուցումները" OBSWebSocket.Settings.AlertsEnable="Միացնել սկուտեղի ծանուցումները"
@ -39,5 +39,3 @@ OBSWebSocket.TrayNotification.AuthenticationFailed.Title="WebSocket վավերա
OBSWebSocket.TrayNotification.AuthenticationFailed.Body="%1 հաճախորդը չհաջողվեց նույնականացնել:" OBSWebSocket.TrayNotification.AuthenticationFailed.Body="%1 հաճախորդը չհաջողվեց նույնականացնել:"
OBSWebSocket.TrayNotification.Disconnected.Title="WebSocket հաճախորդն անջատված է" OBSWebSocket.TrayNotification.Disconnected.Title="WebSocket հաճախորդն անջատված է"
OBSWebSocket.TrayNotification.Disconnected.Body="%1 հաճախորդն անջատվել է:" OBSWebSocket.TrayNotification.Disconnected.Body="%1 հաճախորդն անջատվել է:"
OBSWebSocket.Server.StartFailed.Title="WebSocket սերվերի սխալ"
OBSWebSocket.Server.StartFailed.Message="Չհաջողվեց գործարկել WebSockt սերվերը: Հնարավոր է, որ TCP %1 պորտն արդեն օգտագործվում է մեկ այլ հավելվածի կողմից: Փորձեք կարգավորել այլ TCP պորտ WebSocket սերվերի կարգավորումներում կամ դադարեցնել ցանկացած ծրագիր, որը կարող է օգտագործել այս պորտը:\n Սխալի հաղորդագրություն՝ %2։"

View File

@ -1,5 +1,5 @@
OBSWebSocket.Plugin.Description="Kendali jarak jauh OBS Studio melalui WebSocket" 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.PluginSettingsTitle="Pengaturan Plugin"
OBSWebSocket.Settings.ServerEnable="Aktifkan server WebSocket" OBSWebSocket.Settings.ServerEnable="Aktifkan server WebSocket"
OBSWebSocket.Settings.AlertsEnable="Aktifkan Peringatan Baki Sistem" OBSWebSocket.Settings.AlertsEnable="Aktifkan Peringatan Baki Sistem"
@ -8,7 +8,7 @@ OBSWebSocket.Settings.DebugEnableHoverText="Aktifkan pencatatan awakutu untuk pe
OBSWebSocket.Settings.ServerSettingsTitle="Pengaturan Server" OBSWebSocket.Settings.ServerSettingsTitle="Pengaturan Server"
OBSWebSocket.Settings.AuthRequired="Aktifkan Autentikasi" OBSWebSocket.Settings.AuthRequired="Aktifkan Autentikasi"
OBSWebSocket.Settings.Password="Kata Sandi Server" OBSWebSocket.Settings.Password="Kata Sandi Server"
OBSWebSocket.Settings.GeneratePassword="Ciptakan Kata Sandi" OBSWebSocket.Settings.GeneratePassword="Buat Kata Sandi"
OBSWebSocket.Settings.ServerPort="Port Server" OBSWebSocket.Settings.ServerPort="Port Server"
OBSWebSocket.Settings.ShowConnectInfo="Tampilkan Informasi Koneksi" OBSWebSocket.Settings.ShowConnectInfo="Tampilkan Informasi Koneksi"
OBSWebSocket.Settings.ShowConnectInfoWarningTitle="Peringatan: Saat Ini Siaran Langsung" OBSWebSocket.Settings.ShowConnectInfoWarningTitle="Peringatan: Saat Ini Siaran Langsung"
@ -16,7 +16,7 @@ OBSWebSocket.Settings.ShowConnectInfoWarningMessage="Sepertinya sebuah output (s
OBSWebSocket.Settings.ShowConnectInfoWarningInfoText="Anda yakin ingin melihat informasi koneksi Anda?" OBSWebSocket.Settings.ShowConnectInfoWarningInfoText="Anda yakin ingin melihat informasi koneksi Anda?"
OBSWebSocket.Settings.Save.UserPasswordWarningTitle="Peringatan: Potensi Masalah Keamanan" OBSWebSocket.Settings.Save.UserPasswordWarningTitle="Peringatan: Potensi Masalah Keamanan"
OBSWebSocket.Settings.Save.UserPasswordWarningMessage="obs-websocket menyimpan kata sandi server sebagai teks biasa. Sangat disarankan untuk menggunakan kata sandi yang diciptakan oleh obs-websocket." OBSWebSocket.Settings.Save.UserPasswordWarningMessage="obs-websocket menyimpan kata sandi server sebagai teks biasa. Sangat disarankan untuk menggunakan kata sandi yang diciptakan oleh obs-websocket."
OBSWebSocket.Settings.Save.UserPasswordWarningInfoText="Anda yakin ingin menggunakan kata sandi Anda sendiri?" OBSWebSocket.Settings.Save.UserPasswordWarningInfoText="Apakah Anda yakin ingin menggunakan kata sandi sendiri?"
OBSWebSocket.Settings.Save.PasswordInvalidErrorTitle="Galat: Konfigurasi Tidak Berlaku" OBSWebSocket.Settings.Save.PasswordInvalidErrorTitle="Galat: Konfigurasi Tidak Berlaku"
OBSWebSocket.Settings.Save.PasswordInvalidErrorMessage="Anda harus menggunakan kata sandi yang minimal 6 karakter atau lebih." OBSWebSocket.Settings.Save.PasswordInvalidErrorMessage="Anda harus menggunakan kata sandi yang minimal 6 karakter atau lebih."
OBSWebSocket.SessionTable.Title="Sesi WebSocket yang Terhubung" OBSWebSocket.SessionTable.Title="Sesi WebSocket yang Terhubung"
@ -39,5 +39,3 @@ OBSWebSocket.TrayNotification.AuthenticationFailed.Title="Autentikasi WebSocket
OBSWebSocket.TrayNotification.AuthenticationFailed.Body="Klien %1 gagal mengautentikasi." OBSWebSocket.TrayNotification.AuthenticationFailed.Body="Klien %1 gagal mengautentikasi."
OBSWebSocket.TrayNotification.Disconnected.Title="Klien WebSocket Terputus" OBSWebSocket.TrayNotification.Disconnected.Title="Klien WebSocket Terputus"
OBSWebSocket.TrayNotification.Disconnected.Body="Klien %1 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"

View File

@ -1,5 +1,5 @@
OBSWebSocket.Plugin.Description="Controllo remoto di OBS Studio tramite WebSocket" 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.PluginSettingsTitle="Impostazioni del plugin"
OBSWebSocket.Settings.ServerEnable="Abilita il server WebSocket" OBSWebSocket.Settings.ServerEnable="Abilita il server WebSocket"
OBSWebSocket.Settings.AlertsEnable="Abilita avvisi sulla barra delle applicazioni" 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.AuthenticationFailed.Body="Il client %1 non è riuscito ad autenticarsi."
OBSWebSocket.TrayNotification.Disconnected.Title="Client WebSocket disconnesso" OBSWebSocket.TrayNotification.Disconnected.Title="Client WebSocket disconnesso"
OBSWebSocket.TrayNotification.Disconnected.Body="Client %1 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."

View File

@ -1,5 +1,5 @@
OBSWebSocket.Plugin.Description="WebSocketを介したOBS Studioのリモートコントロール" OBSWebSocket.Plugin.Description="WebSocketを介したOBS Studioのリモートコントロール"
OBSWebSocket.Settings.DialogTitle="obs-websocket設定" OBSWebSocket.Settings.DialogTitle="WebSocket サーバー設定"
OBSWebSocket.Settings.PluginSettingsTitle="プラグイン設定" OBSWebSocket.Settings.PluginSettingsTitle="プラグイン設定"
OBSWebSocket.Settings.ServerEnable="WebSocketサーバーを有効にする" OBSWebSocket.Settings.ServerEnable="WebSocketサーバーを有効にする"
OBSWebSocket.Settings.AlertsEnable="システムトレイアラートを有効にする" OBSWebSocket.Settings.AlertsEnable="システムトレイアラートを有効にする"
@ -39,5 +39,3 @@ OBSWebSocket.TrayNotification.AuthenticationFailed.Title="WebSocket認証失敗"
OBSWebSocket.TrayNotification.AuthenticationFailed.Body="クライアント %1 の認証に失敗しました。" OBSWebSocket.TrayNotification.AuthenticationFailed.Body="クライアント %1 の認証に失敗しました。"
OBSWebSocket.TrayNotification.Disconnected.Title="WebSocketクライアントが切断されました" OBSWebSocket.TrayNotification.Disconnected.Title="WebSocketクライアントが切断されました"
OBSWebSocket.TrayNotification.Disconnected.Body="クライアント %1 が切断されました。" OBSWebSocket.TrayNotification.Disconnected.Body="クライアント %1 が切断されました。"
OBSWebSocket.Server.StartFailed.Title="WebSocketサーバー障害"
OBSWebSocket.Server.StartFailed.Message="WebSocketサーバーの起動に失敗しました。TCPポート %1 はこのシステム上の他の場所で別のアプリケーションによって既に使用されている可能性があります。 WebSocketサーバーの設定で別のTCPポートを設定するか、このポートを使用している可能性のあるアプリケーションを終了してください。\n エラーメッセージ: %2"

View File

@ -1,5 +1,5 @@
OBSWebSocket.Plugin.Description="OBS Studio-ს დაშორებულად მართვა WebSocket-ით" OBSWebSocket.Plugin.Description="OBS Studio-ს დაშორებულად მართვა WebSocket-ით"
OBSWebSocket.Settings.DialogTitle="obs-websocket-პარამეტრები" OBSWebSocket.Settings.DialogTitle="WebSocket-სერვერის პარამეტრები"
OBSWebSocket.Settings.PluginSettingsTitle="მოდულის პარამეტრები" OBSWebSocket.Settings.PluginSettingsTitle="მოდულის პარამეტრები"
OBSWebSocket.Settings.ServerEnable="WebSocket-სერვერის ჩართვა" OBSWebSocket.Settings.ServerEnable="WebSocket-სერვერის ჩართვა"
OBSWebSocket.Settings.AlertsEnable="სისტემური არეში ცნობების ჩართვა" OBSWebSocket.Settings.AlertsEnable="სისტემური არეში ცნობების ჩართვა"
@ -14,7 +14,7 @@ OBSWebSocket.Settings.ShowConnectInfo="კავშირის შესახ
OBSWebSocket.Settings.ShowConnectInfoWarningTitle="გაფრთხილება: პირდაპირ ეთერშია" OBSWebSocket.Settings.ShowConnectInfoWarningTitle="გაფრთხილება: პირდაპირ ეთერშია"
OBSWebSocket.Settings.ShowConnectInfoWarningMessage="როგორც ჩანს, გამოტანა (ნაკადის, ჩანაწერის და სხვ.) ეთერში გადის." OBSWebSocket.Settings.ShowConnectInfoWarningMessage="როგორც ჩანს, გამოტანა (ნაკადის, ჩანაწერის და სხვ.) ეთერში გადის."
OBSWebSocket.Settings.ShowConnectInfoWarningInfoText="ნამდვილად გსურთ კავშირის მონაცემების გამოჩენა?" OBSWebSocket.Settings.ShowConnectInfoWarningInfoText="ნამდვილად გსურთ კავშირის მონაცემების გამოჩენა?"
OBSWebSocket.Settings.Save.UserPasswordWarningTitle="ყურადღება: უსაფრთხოების შესაძლო სისუსტე" OBSWebSocket.Settings.Save.UserPasswordWarningTitle="ყურადღება: სავარაუდო საფრთხე"
OBSWebSocket.Settings.Save.UserPasswordWarningMessage="obs-websocket სერვერის პაროლს ტექსტის სახით. დაჟინებით გირჩევთ, გამოიყენოთ obs-websocket-ით შედგენილი პაროლი." OBSWebSocket.Settings.Save.UserPasswordWarningMessage="obs-websocket სერვერის პაროლს ტექსტის სახით. დაჟინებით გირჩევთ, გამოიყენოთ obs-websocket-ით შედგენილი პაროლი."
OBSWebSocket.Settings.Save.UserPasswordWarningInfoText="ნამდვილად გსურთ საკუთარი პაროლის გამოყენება?" OBSWebSocket.Settings.Save.UserPasswordWarningInfoText="ნამდვილად გსურთ საკუთარი პაროლის გამოყენება?"
OBSWebSocket.Settings.Save.PasswordInvalidErrorTitle="შეცდომა: არასწორი გამართვა" OBSWebSocket.Settings.Save.PasswordInvalidErrorTitle="შეცდომა: არასწორი გამართვა"
@ -39,5 +39,3 @@ OBSWebSocket.TrayNotification.AuthenticationFailed.Title="WebSocket-შესვ
OBSWebSocket.TrayNotification.AuthenticationFailed.Body="კლიენტი %1 ვერ დამოწმდა." OBSWebSocket.TrayNotification.AuthenticationFailed.Body="კლიენტი %1 ვერ დამოწმდა."
OBSWebSocket.TrayNotification.Disconnected.Title="WebSocket-კლიენტი გამოითიშა" OBSWebSocket.TrayNotification.Disconnected.Title="WebSocket-კლიენტი გამოითიშა"
OBSWebSocket.TrayNotification.Disconnected.Body="კლიენტი %1 გამოთიშეულია." OBSWebSocket.TrayNotification.Disconnected.Body="კლიენტი %1 გამოთიშეულია."
OBSWebSocket.Server.StartFailed.Title="WebSocket-სერვერის ხარვეზი"
OBSWebSocket.Server.StartFailed.Message="WebSocket-სერვერი ვერ ამუშავდა. TCP-პორტი %1 შეიძლება უკვე გამოიყენება სისტემაში სხვა პროგამის მიერ. მოსინჯეთ განსხვავებული TCP-პორტი WebSocket-სერვერის პარამეტრებში ან გათიშეთ ყველა პროგრამა, რომელიც ამ პორტს უნდა იყენებდეს.\n შეცდომის აღწერა: %2"

View File

@ -1,5 +1,5 @@
OBSWebSocket.Plugin.Description="Rêveberina ji dûr ve ya OBS Studio bi riya WebSocket" 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.PluginSettingsTitle="Sazkariyên pêvekê"
OBSWebSocket.Settings.ServerEnable="Rajekarê WebSocket çalak bike" OBSWebSocket.Settings.ServerEnable="Rajekarê WebSocket çalak bike"
OBSWebSocket.Settings.AlertsEnable="Hişyariyên darika pergalê ç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.AuthenticationFailed.Body="Rastandina rajegir %1 têk çû."
OBSWebSocket.TrayNotification.Disconnected.Title="Girêdana rajegira WebSocket qut bû" OBSWebSocket.TrayNotification.Disconnected.Title="Girêdana rajegira WebSocket qut bû"
OBSWebSocket.TrayNotification.Disconnected.Body="Girêdana rajegir %1 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"

View File

@ -1,5 +1,5 @@
OBSWebSocket.Plugin.Description="WebSocket으로 OBS Studio를 원격 제어" OBSWebSocket.Plugin.Description="WebSocket으로 OBS Studio를 원격 제어"
OBSWebSocket.Settings.DialogTitle="obs-websocket 설정" OBSWebSocket.Settings.DialogTitle="WebSocket 서버 설정"
OBSWebSocket.Settings.PluginSettingsTitle="플러그인 설정" OBSWebSocket.Settings.PluginSettingsTitle="플러그인 설정"
OBSWebSocket.Settings.ServerEnable="WebSocket 서버 사용" OBSWebSocket.Settings.ServerEnable="WebSocket 서버 사용"
OBSWebSocket.Settings.AlertsEnable="시스템 트레이 알림 사용" OBSWebSocket.Settings.AlertsEnable="시스템 트레이 알림 사용"
@ -39,5 +39,3 @@ OBSWebSocket.TrayNotification.AuthenticationFailed.Title="WebSocket 인증 실
OBSWebSocket.TrayNotification.AuthenticationFailed.Body="클라이언트 %1 인증 실패." OBSWebSocket.TrayNotification.AuthenticationFailed.Body="클라이언트 %1 인증 실패."
OBSWebSocket.TrayNotification.Disconnected.Title="WebSocket 클라이언트 연결 해제됨" OBSWebSocket.TrayNotification.Disconnected.Title="WebSocket 클라이언트 연결 해제됨"
OBSWebSocket.TrayNotification.Disconnected.Body="클라이언트 %1 연결 해제됨." OBSWebSocket.TrayNotification.Disconnected.Body="클라이언트 %1 연결 해제됨."
OBSWebSocket.Server.StartFailed.Title="WebSocket 서버 기동 실패"
OBSWebSocket.Server.StartFailed.Message="WebSocket 서버를 시작하는 데 실패했습니다. %1 TCP 포트가 타 응용 프로그램에 의해 이 시스템에서 이미 사용 중일 수 있습니다. WebSocket 서버 설정에서 다른 TCP 포트로 변경하거나 이 포트를 사용하는 응용 프로그램을 종료하십시오.\n 오류 메시지: %2"

View File

@ -1,5 +1,5 @@
OBSWebSocket.Plugin.Description="Kawalan-jauh OBS Studio melalui WebSocket" 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.PluginSettingsTitle="Tetapan Pemalam"
OBSWebSocket.Settings.ServerEnable="Benarkan pelayan WebSocket" OBSWebSocket.Settings.ServerEnable="Benarkan pelayan WebSocket"
OBSWebSocket.Settings.AlertsEnable="Benarkan Amaran Talam Sistem" 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.AuthenticationFailed.Body="Klien %1 gagal disahihkan."
OBSWebSocket.TrayNotification.Disconnected.Title="Klien WebSocket Terputus" OBSWebSocket.TrayNotification.Disconnected.Title="Klien WebSocket Terputus"
OBSWebSocket.TrayNotification.Disconnected.Body="Klien %1 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"

25
data/locale/nb-NO.ini Normal file
View File

@ -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."

View File

@ -1,5 +1,5 @@
OBSWebSocket.Plugin.Description="Op afstand bediening van OBS Studio via WebSocket" 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.PluginSettingsTitle="Plugin instellingen"
OBSWebSocket.Settings.ServerEnable="WebSocket server inschakelen" OBSWebSocket.Settings.ServerEnable="WebSocket server inschakelen"
OBSWebSocket.Settings.AlertsEnable="Systeemtray meldingen inschakelen" OBSWebSocket.Settings.AlertsEnable="Systeemtray meldingen inschakelen"
@ -30,6 +30,7 @@ OBSWebSocket.ConnectInfo.DialogTitle="WebSocket verbindingsinformatie"
OBSWebSocket.ConnectInfo.CopyText="Kopiëren" OBSWebSocket.ConnectInfo.CopyText="Kopiëren"
OBSWebSocket.ConnectInfo.ServerIp="Server IP (Beste inschatting)" OBSWebSocket.ConnectInfo.ServerIp="Server IP (Beste inschatting)"
OBSWebSocket.ConnectInfo.ServerPort="Serverpoort" OBSWebSocket.ConnectInfo.ServerPort="Serverpoort"
OBSWebSocket.ConnectInfo.ServerPassword="Serverwachtwoord"
OBSWebSocket.ConnectInfo.ServerPasswordPlaceholderText="[Authenticatie Uitgeschakeld]" OBSWebSocket.ConnectInfo.ServerPasswordPlaceholderText="[Authenticatie Uitgeschakeld]"
OBSWebSocket.ConnectInfo.QrTitle="QR koppelen" OBSWebSocket.ConnectInfo.QrTitle="QR koppelen"
OBSWebSocket.TrayNotification.Identified.Title="Nieuwe WebSocket verbinding" 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.AuthenticationFailed.Body="Authenticatie van client %1 mislukt."
OBSWebSocket.TrayNotification.Disconnected.Title="WebSocket Client losgekoppeld" OBSWebSocket.TrayNotification.Disconnected.Title="WebSocket Client losgekoppeld"
OBSWebSocket.TrayNotification.Disconnected.Body="Client %1 ontkoppeld." 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"

View File

@ -1,5 +1,5 @@
OBSWebSocket.Plugin.Description="Zdalna kontrola OBS Studio przez WebSocket" 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.PluginSettingsTitle="Ustawienia wtyczki"
OBSWebSocket.Settings.ServerEnable="Włącz serwer WebSocket" OBSWebSocket.Settings.ServerEnable="Włącz serwer WebSocket"
OBSWebSocket.Settings.AlertsEnable="Włącz powiadomienia w zasobniku systemowym" OBSWebSocket.Settings.AlertsEnable="Włącz powiadomienia w zasobniku systemowym"
@ -18,7 +18,7 @@ OBSWebSocket.Settings.Save.UserPasswordWarningTitle="Ostrzeżenie: Potencjalny p
OBSWebSocket.Settings.Save.UserPasswordWarningMessage="obs-websocket przechowuje hasło serwera jako zwykły tekst. Wysoce zalecane jest użycie hasła generowanego przez obs-websocket." OBSWebSocket.Settings.Save.UserPasswordWarningMessage="obs-websocket przechowuje hasło serwera jako zwykły tekst. Wysoce zalecane jest użycie hasła generowanego przez obs-websocket."
OBSWebSocket.Settings.Save.UserPasswordWarningInfoText="Czy na pewno chcesz użyć własnego hasła?" OBSWebSocket.Settings.Save.UserPasswordWarningInfoText="Czy na pewno chcesz użyć własnego hasła?"
OBSWebSocket.Settings.Save.PasswordInvalidErrorTitle="Błąd: Nieprawidłowa konfiguracja" OBSWebSocket.Settings.Save.PasswordInvalidErrorTitle="Błąd: Nieprawidłowa konfiguracja"
OBSWebSocket.Settings.Save.PasswordInvalidErrorMessage="Musisz użyć hasła, które ma 6 lub więcej znaków." OBSWebSocket.Settings.Save.PasswordInvalidErrorMessage="Hasło musi zawierać 6 lub więcej znaków."
OBSWebSocket.SessionTable.Title="Podłączone sesje WebSocket" OBSWebSocket.SessionTable.Title="Podłączone sesje WebSocket"
OBSWebSocket.SessionTable.RemoteAddressColumnTitle="Adres zdalny" OBSWebSocket.SessionTable.RemoteAddressColumnTitle="Adres zdalny"
OBSWebSocket.SessionTable.SessionDurationColumnTitle="Czas trwania sesji" OBSWebSocket.SessionTable.SessionDurationColumnTitle="Czas trwania sesji"
@ -39,5 +39,3 @@ OBSWebSocket.TrayNotification.AuthenticationFailed.Title="Błąd uwierzytelniani
OBSWebSocket.TrayNotification.AuthenticationFailed.Body="Klient %1 nie został uwierzytelniony." OBSWebSocket.TrayNotification.AuthenticationFailed.Body="Klient %1 nie został uwierzytelniony."
OBSWebSocket.TrayNotification.Disconnected.Title="Klient WebSocket odłączony" OBSWebSocket.TrayNotification.Disconnected.Title="Klient WebSocket odłączony"
OBSWebSocket.TrayNotification.Disconnected.Body="Klient %1 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"

View File

@ -1,5 +1,5 @@
OBSWebSocket.Plugin.Description="Controle remoto do OBS Studio através de WebSocket" 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.PluginSettingsTitle="Configurações de Plugin"
OBSWebSocket.Settings.ServerEnable="Ativar servidor WebSocket" OBSWebSocket.Settings.ServerEnable="Ativar servidor WebSocket"
OBSWebSocket.Settings.AlertsEnable="Ativar Alertas da Bandeja do Sistema" OBSWebSocket.Settings.AlertsEnable="Ativar Alertas da Bandeja do Sistema"
@ -22,7 +22,7 @@ OBSWebSocket.Settings.Save.PasswordInvalidErrorMessage="Você deve usar uma senh
OBSWebSocket.SessionTable.Title="Sessões WebSocket Conectadas" OBSWebSocket.SessionTable.Title="Sessões WebSocket Conectadas"
OBSWebSocket.SessionTable.RemoteAddressColumnTitle="Endereço Remoto" OBSWebSocket.SessionTable.RemoteAddressColumnTitle="Endereço Remoto"
OBSWebSocket.SessionTable.SessionDurationColumnTitle="Duração de Sessão" OBSWebSocket.SessionTable.SessionDurationColumnTitle="Duração de Sessão"
OBSWebSocket.SessionTable.MessagesInOutColumnTitle="Mengsagens de Entrada/Saída" OBSWebSocket.SessionTable.MessagesInOutColumnTitle="Mensagens"
OBSWebSocket.SessionTable.IdentifiedTitle="Identificada" OBSWebSocket.SessionTable.IdentifiedTitle="Identificada"
OBSWebSocket.SessionTable.KickButtonColumnTitle="Expulsar?" OBSWebSocket.SessionTable.KickButtonColumnTitle="Expulsar?"
OBSWebSocket.SessionTable.KickButtonText="Expulsar" OBSWebSocket.SessionTable.KickButtonText="Expulsar"
@ -39,5 +39,3 @@ OBSWebSocket.TrayNotification.AuthenticationFailed.Title="Falha na Autenticaçã
OBSWebSocket.TrayNotification.AuthenticationFailed.Body="Cliente %1 falhou na autenticação." OBSWebSocket.TrayNotification.AuthenticationFailed.Body="Cliente %1 falhou na autenticação."
OBSWebSocket.TrayNotification.Disconnected.Title="Cliente WebSocket Desconectado" OBSWebSocket.TrayNotification.Disconnected.Title="Cliente WebSocket Desconectado"
OBSWebSocket.TrayNotification.Disconnected.Body="Cliente %1 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"

View File

@ -1,5 +1,5 @@
OBSWebSocket.Plugin.Description="Controlo remoto do OBS Studio através de WebSocket" 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.PluginSettingsTitle="Configurações do plugin"
OBSWebSocket.Settings.ServerEnable="Ativar servidor WebSocket" OBSWebSocket.Settings.ServerEnable="Ativar servidor WebSocket"
OBSWebSocket.Settings.AlertsEnable="Ativar alertas da bandeja do sistema" 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.AuthenticationFailed.Body="Cliente %1 falhou na autenticação."
OBSWebSocket.TrayNotification.Disconnected.Title="Cliente WebSocket desligado" OBSWebSocket.TrayNotification.Disconnected.Title="Cliente WebSocket desligado"
OBSWebSocket.TrayNotification.Disconnected.Body="Cliente %1 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"

View File

@ -1,22 +1,22 @@
OBSWebSocket.Plugin.Description="Control de la distanță pentru OBS Studio prin WebSocket" OBSWebSocket.Plugin.Description="Control de la distanță pentru OBS Studio prin WebSocket"
OBSWebSocket.Settings.DialogTitle="Setări obs-websocket" OBSWebSocket.Settings.DialogTitle="Setări pentru serverul WebSocket"
OBSWebSocket.Settings.PluginSettingsTitle="Setări ale plugin-ului" OBSWebSocket.Settings.PluginSettingsTitle="Setări pentru plugin"
OBSWebSocket.Settings.ServerEnable="Activează serverul WebSocket" OBSWebSocket.Settings.ServerEnable="Activează serverul WebSocket"
OBSWebSocket.Settings.AlertsEnable="Activați alertele din bara de sistem" OBSWebSocket.Settings.AlertsEnable="Activează alertele din bara de sistem"
OBSWebSocket.Settings.DebugEnable="Activează jurnalizarea de depanare" OBSWebSocket.Settings.DebugEnable="Activează jurnalizarea pentru 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.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 server" OBSWebSocket.Settings.ServerSettingsTitle="Setări pentru server"
OBSWebSocket.Settings.AuthRequired="Activează autentificarea" OBSWebSocket.Settings.AuthRequired="Activează autentificarea"
OBSWebSocket.Settings.Password="Parola serverului" OBSWebSocket.Settings.Password="Parola serverului"
OBSWebSocket.Settings.GeneratePassword="Generează parola" OBSWebSocket.Settings.GeneratePassword="Generează parola"
OBSWebSocket.Settings.ServerPort="Portul serverului" 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.ShowConnectInfoWarningTitle="Avertisment: În prezent în direct"
OBSWebSocket.Settings.ShowConnectInfoWarningMessage="Se pare că o ieșire (flux, înregistrare etc.) este activă în prezent." OBSWebSocket.Settings.ShowConnectInfoWarningMessage="Se pare că un output (stream, înregistrare etc.) este activ în prezent."
OBSWebSocket.Settings.ShowConnectInfoWarningInfoText="Ești sigur vrei să-ți arăți informațiile de conectare?" OBSWebSocket.Settings.ShowConnectInfoWarningInfoText="Sigur vrei să afișezi informațiile de conectare?"
OBSWebSocket.Settings.Save.UserPasswordWarningTitle="Avertisment: Potențială problemă de securitate" OBSWebSocket.Settings.Save.UserPasswordWarningTitle="Avertisment: Potențială problemă de securitate"
OBSWebSocket.Settings.Save.UserPasswordWarningMessage="obs-websocket stochează parola serverului ca text simplu. Este foarte recomandat să folosiți o parolă generată de obs-websocket." OBSWebSocket.Settings.Save.UserPasswordWarningMessage="obs-websocket stochează parola serverului ca text simplu. Este foarte recomandat să folosiți o parolă generată de obs-websocket."
OBSWebSocket.Settings.Save.UserPasswordWarningInfoText="Ești sigur vrei să-ți folosești propria parolă?" OBSWebSocket.Settings.Save.UserPasswordWarningInfoText="Sigur vrei să-ți folosești propria parolă?"
OBSWebSocket.Settings.Save.PasswordInvalidErrorTitle="Eroare: Configurație invalidă" OBSWebSocket.Settings.Save.PasswordInvalidErrorTitle="Eroare: Configurație invalidă"
OBSWebSocket.Settings.Save.PasswordInvalidErrorMessage="Trebuie să folosești o parolă care să aibă 6 sau mai multe caractere." OBSWebSocket.Settings.Save.PasswordInvalidErrorMessage="Trebuie să folosești o parolă care să aibă 6 sau mai multe caractere."
OBSWebSocket.SessionTable.Title="Sesiuni WebSocket conectate" OBSWebSocket.SessionTable.Title="Sesiuni WebSocket conectate"
@ -24,20 +24,18 @@ OBSWebSocket.SessionTable.RemoteAddressColumnTitle="Adresă la distanță"
OBSWebSocket.SessionTable.SessionDurationColumnTitle="Durata sesiunii" OBSWebSocket.SessionTable.SessionDurationColumnTitle="Durata sesiunii"
OBSWebSocket.SessionTable.MessagesInOutColumnTitle="Mesaje de intrare/ieșire" OBSWebSocket.SessionTable.MessagesInOutColumnTitle="Mesaje de intrare/ieșire"
OBSWebSocket.SessionTable.IdentifiedTitle="Identificat" OBSWebSocket.SessionTable.IdentifiedTitle="Identificat"
OBSWebSocket.SessionTable.KickButtonColumnTitle="Înlătură?" OBSWebSocket.SessionTable.KickButtonColumnTitle="Înlături?"
OBSWebSocket.SessionTable.KickButtonText="Înlătură" 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.CopyText="Copiază"
OBSWebSocket.ConnectInfo.ServerIp="IP-ul serverului (cea mai bună presupunere)" OBSWebSocket.ConnectInfo.ServerIp="IP-ul serverului (cea mai bună presupunere)"
OBSWebSocket.ConnectInfo.ServerPort="Portul serverului" OBSWebSocket.ConnectInfo.ServerPort="Portul serverului"
OBSWebSocket.ConnectInfo.ServerPassword="Parola serverului" OBSWebSocket.ConnectInfo.ServerPassword="Parola serverului"
OBSWebSocket.ConnectInfo.ServerPasswordPlaceholderText="[Autentificare dezactivată]" 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.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.Title="Eroare de autentificare WebSocket"
OBSWebSocket.TrayNotification.AuthenticationFailed.Body="Client %1 nu a reușit să se autentifice." OBSWebSocket.TrayNotification.AuthenticationFailed.Body="Client %1 nu a reușit să se autentifice."
OBSWebSocket.TrayNotification.Disconnected.Title="Client WebSocket deconectat" OBSWebSocket.TrayNotification.Disconnected.Title="Client WebSocket deconectat"
OBSWebSocket.TrayNotification.Disconnected.Body="Clientul %1 s-a 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"

View File

@ -1,18 +1,18 @@
OBSWebSocket.Plugin.Description="Удалённое управление OBS Studio по WebSocket" OBSWebSocket.Plugin.Description="Удалённое управление OBS Studio по WebSocket"
OBSWebSocket.Settings.DialogTitle="Настройки obs-websocket" OBSWebSocket.Settings.DialogTitle="Настройки сервера WebSocket"
OBSWebSocket.Settings.PluginSettingsTitle="Настройки плагина" OBSWebSocket.Settings.PluginSettingsTitle="Настройки плагина"
OBSWebSocket.Settings.ServerEnable="Включить сервер WebSocket" OBSWebSocket.Settings.ServerEnable="Включить сервер WebSocket"
OBSWebSocket.Settings.AlertsEnable="Включить оповещения в трее" OBSWebSocket.Settings.AlertsEnable="Включить оповещения в трее"
OBSWebSocket.Settings.DebugEnable="Включить отладочный журнал" OBSWebSocket.Settings.DebugEnable="Включить отладочный журнал"
OBSWebSocket.Settings.DebugEnableHoverText="Включает ведение журнала отладки для текущего экземпляра OBS. Не сохраняется при запуске.\nИспользуйте --websocket_debug для включения при запуске." OBSWebSocket.Settings.DebugEnableHoverText="Включает ведение журнала отладки для текущего экземпляра OBS. Не сохраняется при запуске.\nИспользуйте --websocket_debug для включения при запуске."
OBSWebSocket.Settings.ServerSettingsTitle="Настройки сервера" OBSWebSocket.Settings.ServerSettingsTitle="Настройки сервера"
OBSWebSocket.Settings.AuthRequired="Включить аутентификацию" OBSWebSocket.Settings.AuthRequired="Включить вход в аккаунт"
OBSWebSocket.Settings.Password="Пароль сервера" OBSWebSocket.Settings.Password="Пароль сервера"
OBSWebSocket.Settings.GeneratePassword="Сгенерировать пароль" OBSWebSocket.Settings.GeneratePassword="Создать пароль"
OBSWebSocket.Settings.ServerPort="Порт сервера" OBSWebSocket.Settings.ServerPort="Порт сервера"
OBSWebSocket.Settings.ShowConnectInfo="Показать сведения о подключении" OBSWebSocket.Settings.ShowConnectInfo="Показать сведения о подключении"
OBSWebSocket.Settings.ShowConnectInfoWarningTitle="Предупреждение: Сейчас в эфире" OBSWebSocket.Settings.ShowConnectInfoWarningTitle="Предупреждение: Сейчас в эфире"
OBSWebSocket.Settings.ShowConnectInfoWarningMessage="Похоже, что вывод (поток, запись и т. д.) в настоящее время активен." OBSWebSocket.Settings.ShowConnectInfoWarningMessage="Похоже, что вывод (поток, запись и т. д.) в настоящее время уже выбран."
OBSWebSocket.Settings.ShowConnectInfoWarningInfoText="Уверены, что хотите показать ваши сведения о подключении?" OBSWebSocket.Settings.ShowConnectInfoWarningInfoText="Уверены, что хотите показать ваши сведения о подключении?"
OBSWebSocket.Settings.Save.UserPasswordWarningTitle="Предупреждение: Потенциальная проблема безопасности" OBSWebSocket.Settings.Save.UserPasswordWarningTitle="Предупреждение: Потенциальная проблема безопасности"
OBSWebSocket.Settings.Save.UserPasswordWarningMessage="obs-websocket хранит пароль сервера в виде обычного текста. Настоятельно рекомендуется использовать пароль, сгенерированный obs-websock." OBSWebSocket.Settings.Save.UserPasswordWarningMessage="obs-websocket хранит пароль сервера в виде обычного текста. Настоятельно рекомендуется использовать пароль, сгенерированный obs-websock."
@ -28,16 +28,14 @@ OBSWebSocket.SessionTable.KickButtonColumnTitle="Выгнать?"
OBSWebSocket.SessionTable.KickButtonText="Выгнать" OBSWebSocket.SessionTable.KickButtonText="Выгнать"
OBSWebSocket.ConnectInfo.DialogTitle="Сведения о подключении WebSocket" OBSWebSocket.ConnectInfo.DialogTitle="Сведения о подключении WebSocket"
OBSWebSocket.ConnectInfo.CopyText="Копировать" OBSWebSocket.ConnectInfo.CopyText="Копировать"
OBSWebSocket.ConnectInfo.ServerIp="IP сервера (лучшая догадка)" OBSWebSocket.ConnectInfo.ServerIp="IP сервера (вероятный)"
OBSWebSocket.ConnectInfo.ServerPort="Порт сервера" OBSWebSocket.ConnectInfo.ServerPort="Порт сервера"
OBSWebSocket.ConnectInfo.ServerPassword="Пароль сервера" OBSWebSocket.ConnectInfo.ServerPassword="Пароль сервера"
OBSWebSocket.ConnectInfo.ServerPasswordPlaceholderText="[Авторизация отключена]" OBSWebSocket.ConnectInfo.ServerPasswordPlaceholderText="[Вход отключён]"
OBSWebSocket.ConnectInfo.QrTitle="QR-код подключения" OBSWebSocket.ConnectInfo.QrTitle="QR-код подключения"
OBSWebSocket.TrayNotification.Identified.Title="Новое подключение WebSocket" OBSWebSocket.TrayNotification.Identified.Title="Новое подключение WebSocket"
OBSWebSocket.TrayNotification.Identified.Body="Клиент %1 распознан." OBSWebSocket.TrayNotification.Identified.Body="Клиент %1 распознан."
OBSWebSocket.TrayNotification.AuthenticationFailed.Title="Ошибка аутентификации WebSocket" OBSWebSocket.TrayNotification.AuthenticationFailed.Title="Ошибка входа WebSocket"
OBSWebSocket.TrayNotification.AuthenticationFailed.Body="Клиент %1 не смог аутентифицироваться." OBSWebSocket.TrayNotification.AuthenticationFailed.Body="Клиент %1 не смог войти."
OBSWebSocket.TrayNotification.Disconnected.Title="Клиент WebSocket отключился" OBSWebSocket.TrayNotification.Disconnected.Title="Клиент WebSocket отключился"
OBSWebSocket.TrayNotification.Disconnected.Body="Клиент %1 отключился." OBSWebSocket.TrayNotification.Disconnected.Body="Клиент %1 отключился."
OBSWebSocket.Server.StartFailed.Title="Ошибка сервера WebSocket"
OBSWebSocket.Server.StartFailed.Message="Не удалось запустить сервер WebSockt. Возможно, порт TCP %1 уже используется другим приложением. Попробуйте установить другой TCP-порт в настройках сервера WebSocket или остановите любое приложение, которое может использовать этот порт.\n Сообщение ошибки: %2"

View File

@ -1,4 +1,5 @@
OBSWebSocket.Settings.PluginSettingsTitle="පේනුවේ සැකසුම්" OBSWebSocket.Settings.PluginSettingsTitle="පේනුවේ සැකසුම්"
OBSWebSocket.Settings.DebugEnable="නිදොස්කරණ සටහන් තැබීම සබල කරන්න"
OBSWebSocket.Settings.ServerSettingsTitle="සේවාදායකයේ සැකසුම්" OBSWebSocket.Settings.ServerSettingsTitle="සේවාදායකයේ සැකසුම්"
OBSWebSocket.Settings.AuthRequired="සත්‍යාපනය සබල කරන්න" OBSWebSocket.Settings.AuthRequired="සත්‍යාපනය සබල කරන්න"
OBSWebSocket.Settings.Password="සේවාදායකයේ මුරපදය" OBSWebSocket.Settings.Password="සේවාදායකයේ මුරපදය"
@ -11,6 +12,7 @@ OBSWebSocket.SessionTable.SessionDurationColumnTitle="වාරයේ පරා
OBSWebSocket.SessionTable.MessagesInOutColumnTitle="පණිවිඩ එන/යන" OBSWebSocket.SessionTable.MessagesInOutColumnTitle="පණිවිඩ එන/යන"
OBSWebSocket.SessionTable.IdentifiedTitle="හඳුනා ගැනිණි" OBSWebSocket.SessionTable.IdentifiedTitle="හඳුනා ගැනිණි"
OBSWebSocket.ConnectInfo.CopyText="පිටපතක්" OBSWebSocket.ConnectInfo.CopyText="පිටපතක්"
OBSWebSocket.ConnectInfo.ServerIp="සේවාදායකයේ අ.ජා.කෙ. (අනුමානය)"
OBSWebSocket.ConnectInfo.ServerPort="සේවාදායකයේ තොට" OBSWebSocket.ConnectInfo.ServerPort="සේවාදායකයේ තොට"
OBSWebSocket.ConnectInfo.ServerPassword="සේවාදායකයේ මුරපදය" OBSWebSocket.ConnectInfo.ServerPassword="සේවාදායකයේ මුරපදය"
OBSWebSocket.ConnectInfo.ServerPasswordPlaceholderText="[සත්‍යාපනය අබලයි]" OBSWebSocket.ConnectInfo.ServerPasswordPlaceholderText="[සත්‍යාපනය අබලයි]"

View File

@ -1,5 +1,5 @@
OBSWebSocket.Plugin.Description="Vzdialené ovládanie OBS Štúdia cez WebSocket" 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.PluginSettingsTitle="Nastavenia pluginu"
OBSWebSocket.Settings.ServerEnable="Zapnúť WebSocket server" OBSWebSocket.Settings.ServerEnable="Zapnúť WebSocket server"
OBSWebSocket.Settings.AlertsEnable="Zapnúť notifikácie zo systémovej lišty" 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.AuthenticationFailed.Body="Klientovi %1 sa nepodarilo autentifikovať."
OBSWebSocket.TrayNotification.Disconnected.Title="WebSocket klient odpojený" OBSWebSocket.TrayNotification.Disconnected.Title="WebSocket klient odpojený"
OBSWebSocket.TrayNotification.Disconnected.Body="Klient %1 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"

View File

@ -1,5 +1,5 @@
OBSWebSocket.Plugin.Description="Oddaljeni nadzor OBS Studia prek WebSocketa" 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.PluginSettingsTitle="Nastavitve vtičnika"
OBSWebSocket.Settings.ServerEnable="Omogoči strežnik WebSocket" OBSWebSocket.Settings.ServerEnable="Omogoči strežnik WebSocket"
OBSWebSocket.Settings.AlertsEnable="Omogoči opozorila v sistemskem pladnju" 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.AuthenticationFailed.Body="Odjemalec %1 ni prestal overjanja."
OBSWebSocket.TrayNotification.Disconnected.Title="Odjemalec WebSocket je prekinil povezavo" OBSWebSocket.TrayNotification.Disconnected.Title="Odjemalec WebSocket je prekinil povezavo"
OBSWebSocket.TrayNotification.Disconnected.Body="Odjemalec %1 ni več povezan." 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"

View File

@ -1,6 +1,6 @@
OBSWebSocket.Plugin.Description="Fjärrkontroll av OBS Studio via WebSocket" 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.PluginSettingsTitle="Insticksprogramsinställningar"
OBSWebSocket.Settings.ServerEnable="Aktivera WebSocket-server" OBSWebSocket.Settings.ServerEnable="Aktivera WebSocket-server"
OBSWebSocket.Settings.AlertsEnable="Aktivera systemfältsmeddelanden" OBSWebSocket.Settings.AlertsEnable="Aktivera systemfältsmeddelanden"
OBSWebSocket.Settings.DebugEnable="Aktivera felsökningsloggning" OBSWebSocket.Settings.DebugEnable="Aktivera felsökningsloggning"
@ -11,7 +11,7 @@ OBSWebSocket.Settings.Password="Serverlösenord"
OBSWebSocket.Settings.GeneratePassword="Generera lösenord" OBSWebSocket.Settings.GeneratePassword="Generera lösenord"
OBSWebSocket.Settings.ServerPort="Serverport" OBSWebSocket.Settings.ServerPort="Serverport"
OBSWebSocket.Settings.ShowConnectInfo="Visa anslutningsinformation" OBSWebSocket.Settings.ShowConnectInfo="Visa anslutningsinformation"
OBSWebSocket.Settings.ShowConnectInfoWarningTitle="Varning: Sänder för närvarande" OBSWebSocket.Settings.ShowConnectInfoWarningTitle="Varning: Direktsändning pågår"
OBSWebSocket.Settings.ShowConnectInfoWarningMessage="Det verkar som om en utmatning (ström, inspelning, etc.) är för närvarande aktiv." OBSWebSocket.Settings.ShowConnectInfoWarningMessage="Det verkar som om en utmatning (ström, inspelning, etc.) är för närvarande aktiv."
OBSWebSocket.Settings.ShowConnectInfoWarningInfoText="Är du säker på att du vill visa din anslutningsinformation?" OBSWebSocket.Settings.ShowConnectInfoWarningInfoText="Är du säker på att du vill visa din anslutningsinformation?"
OBSWebSocket.Settings.Save.UserPasswordWarningTitle="Varning: Potentiellt säkerhetsproblem" OBSWebSocket.Settings.Save.UserPasswordWarningTitle="Varning: Potentiellt säkerhetsproblem"
@ -39,5 +39,3 @@ OBSWebSocket.TrayNotification.AuthenticationFailed.Title="Autentisering av WebSo
OBSWebSocket.TrayNotification.AuthenticationFailed.Body="Klient %1 misslyckades att autentiseras." OBSWebSocket.TrayNotification.AuthenticationFailed.Body="Klient %1 misslyckades att autentiseras."
OBSWebSocket.TrayNotification.Disconnected.Title="WebSocket-klient frånkopplades" OBSWebSocket.TrayNotification.Disconnected.Title="WebSocket-klient frånkopplades"
OBSWebSocket.TrayNotification.Disconnected.Body="Klient %1 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"

View File

@ -1,5 +1,5 @@
OBSWebSocket.Plugin.Description="WebSocket aracılığıyla uzaktan OBS Studio" 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.PluginSettingsTitle="Eklenti Ayarları"
OBSWebSocket.Settings.ServerEnable="WebSocket sunucuyu etkinleştir" OBSWebSocket.Settings.ServerEnable="WebSocket sunucuyu etkinleştir"
OBSWebSocket.Settings.AlertsEnable="Sistem Tepsi Uyarılarını 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.DialogTitle="WebSocket Bağlanma Bilgileri"
OBSWebSocket.ConnectInfo.CopyText="Kopyala" OBSWebSocket.ConnectInfo.CopyText="Kopyala"
OBSWebSocket.ConnectInfo.ServerIp="Sunucu IP (En İyi Tahmin)" 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.ServerPassword="Sunucu Parolası"
OBSWebSocket.ConnectInfo.ServerPasswordPlaceholderText="[Doğrulama Devre Dışı]" OBSWebSocket.ConnectInfo.ServerPasswordPlaceholderText="[Doğrulama Devre Dışı]"
OBSWebSocket.ConnectInfo.QrTitle="Kare Kod ile Bağlan" 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.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.Title="WebSocket İstemcisinin Bağlantısı Kesildi"
OBSWebSocket.TrayNotification.Disconnected.Body="%1 istemcisinin 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"

9
data/locale/tt-RU.ini Normal file
View File

@ -0,0 +1,9 @@
OBSWebSocket.Settings.ServerSettingsTitle="Сервер көйләүләре"
OBSWebSocket.Settings.Password="Сервер серсүзе"
OBSWebSocket.Settings.GeneratePassword="Серсүзне ясау"
OBSWebSocket.Settings.ServerPort="Сервер порты"
OBSWebSocket.SessionTable.KickButtonColumnTitle="Чыгарыргамы?"
OBSWebSocket.SessionTable.KickButtonText="Чыгару"
OBSWebSocket.ConnectInfo.CopyText="Күчермә алу"
OBSWebSocket.ConnectInfo.ServerPort="Сервер порты"
OBSWebSocket.ConnectInfo.ServerPassword="Сервер серсүзе"

2
data/locale/ug-CN.ini Normal file
View File

@ -0,0 +1,2 @@
OBSWebSocket.Settings.GeneratePassword="ئىم ھاسىللا"
OBSWebSocket.ConnectInfo.CopyText="كۆچۈر"

View File

@ -1,5 +1,5 @@
OBSWebSocket.Plugin.Description="Віддалене керування OBS Studio через WebSocket" OBSWebSocket.Plugin.Description="Віддалене керування OBS Studio через WebSocket"
OBSWebSocket.Settings.DialogTitle="Налаштування obs-websocket" OBSWebSocket.Settings.DialogTitle="Налаштування WebSocket сервера"
OBSWebSocket.Settings.PluginSettingsTitle="Налаштування плагіна" OBSWebSocket.Settings.PluginSettingsTitle="Налаштування плагіна"
OBSWebSocket.Settings.ServerEnable="Увімкнути сервер WebSocket" OBSWebSocket.Settings.ServerEnable="Увімкнути сервер WebSocket"
OBSWebSocket.Settings.AlertsEnable="Увімкнути сповіщення у системному лотку" OBSWebSocket.Settings.AlertsEnable="Увімкнути сповіщення у системному лотку"
@ -39,5 +39,3 @@ OBSWebSocket.TrayNotification.AuthenticationFailed.Title="Помилка авт
OBSWebSocket.TrayNotification.AuthenticationFailed.Body="Клієнт %1 не зміг автентифікуватися." OBSWebSocket.TrayNotification.AuthenticationFailed.Body="Клієнт %1 не зміг автентифікуватися."
OBSWebSocket.TrayNotification.Disconnected.Title="Клієнт WebSocket від'єднаний" OBSWebSocket.TrayNotification.Disconnected.Title="Клієнт WebSocket від'єднаний"
OBSWebSocket.TrayNotification.Disconnected.Body="Клієнт %1 від'єднаний." OBSWebSocket.TrayNotification.Disconnected.Body="Клієнт %1 від'єднаний."
OBSWebSocket.Server.StartFailed.Title="Помилка сервера WebSocket"
OBSWebSocket.Server.StartFailed.Message="Не вдалося запустити сервер WebSocket. Порт TCP %1 може вже використовуватися в іншому місці цим системним інтерфейсом. Спробуйте встановити інший TCP порт в налаштуваннях WebSocket сервера або зупинити будь-які застосунки, які можуть використовувати цей порт.\n Повідомлення про помилку: %2"

37
data/locale/vi-VN.ini Normal file
View File

@ -0,0 +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."

View File

@ -1,28 +1,28 @@
OBSWebSocket.Plugin.Description="通过 WebSocket 远程控制 OBS Studio" OBSWebSocket.Plugin.Description="通过 WebSocket 远程控制 OBS Studio"
OBSWebSocket.Settings.DialogTitle="obs-websocket 设置" OBSWebSocket.Settings.DialogTitle="WebSocket 服务器设置"
OBSWebSocket.Settings.PluginSettingsTitle="插件设置" OBSWebSocket.Settings.PluginSettingsTitle="插件设置"
OBSWebSocket.Settings.ServerEnable="开启 WebSocket 服务器" OBSWebSocket.Settings.ServerEnable="开启 WebSocket 服务器"
OBSWebSocket.Settings.AlertsEnable="开启系统托盘提醒" OBSWebSocket.Settings.AlertsEnable="开启系统托盘提醒"
OBSWebSocket.Settings.DebugEnable="开启调试日志" OBSWebSocket.Settings.DebugEnable="开启调试日志"
OBSWebSocket.Settings.DebugEnableHoverText="启当前 OBS 实例的调试日志。下次启动时需重新设置。\n使用 --websocket_debug 在启动 OBS 时启日志。" OBSWebSocket.Settings.DebugEnableHoverText="启当前 OBS 实例的调试日志。下次启动时需重新设置。\n使用 --websocket_debug 在启动 OBS 时启日志。"
OBSWebSocket.Settings.ServerSettingsTitle="服务器设置" OBSWebSocket.Settings.ServerSettingsTitle="服务器设置"
OBSWebSocket.Settings.AuthRequired="开启鉴权" OBSWebSocket.Settings.AuthRequired="开启身份认证"
OBSWebSocket.Settings.Password="服务器密码" OBSWebSocket.Settings.Password="服务器密码"
OBSWebSocket.Settings.GeneratePassword="生成密码" OBSWebSocket.Settings.GeneratePassword="生成密码"
OBSWebSocket.Settings.ServerPort="服务器端口" OBSWebSocket.Settings.ServerPort="服务器端口"
OBSWebSocket.Settings.ShowConnectInfo="显示连接信息" OBSWebSocket.Settings.ShowConnectInfo="显示连接信息"
OBSWebSocket.Settings.ShowConnectInfoWarningTitle="警告:正在直播" OBSWebSocket.Settings.ShowConnectInfoWarningTitle="警告:正在直播"
OBSWebSocket.Settings.ShowConnectInfoWarningMessage="似乎正在输出(串流、录像等)。" OBSWebSocket.Settings.ShowConnectInfoWarningMessage="似乎输出(串流、录像等)正在进行。"
OBSWebSocket.Settings.ShowConnectInfoWarningInfoText="您确定要显示您的连接信息吗?" OBSWebSocket.Settings.ShowConnectInfoWarningInfoText="您确定要显示您的连接信息吗?"
OBSWebSocket.Settings.Save.UserPasswordWarningTitle="警告:潜在安全问题" OBSWebSocket.Settings.Save.UserPasswordWarningTitle="警告:潜在安全问题"
OBSWebSocket.Settings.Save.UserPasswordWarningMessage="obs-websocket 会以明文形式储存服务器密码。强烈建议使用 obs-websocket 生成的密码。" OBSWebSocket.Settings.Save.UserPasswordWarningMessage="obs-websocket 会以明文形式储存服务器密码。强烈建议使用 obs-websocket 生成的密码。"
OBSWebSocket.Settings.Save.UserPasswordWarningInfoText="您确定要使用自定义密码吗?" OBSWebSocket.Settings.Save.UserPasswordWarningInfoText="您确定要使用自定义密码吗?"
OBSWebSocket.Settings.Save.PasswordInvalidErrorTitle="错误:配置无效" OBSWebSocket.Settings.Save.PasswordInvalidErrorTitle="错误:无效的配置"
OBSWebSocket.Settings.Save.PasswordInvalidErrorMessage="您的密码必须包含 6 个或以上的字符。" OBSWebSocket.Settings.Save.PasswordInvalidErrorMessage="您的密码必须包含 6 个或以上的字符。"
OBSWebSocket.SessionTable.Title="已连接的 WebSocket 会话" OBSWebSocket.SessionTable.Title="已连接的 WebSocket 会话"
OBSWebSocket.SessionTable.RemoteAddressColumnTitle="远程地址" OBSWebSocket.SessionTable.RemoteAddressColumnTitle="远程地址"
OBSWebSocket.SessionTable.SessionDurationColumnTitle="会话持续时间" OBSWebSocket.SessionTable.SessionDurationColumnTitle="会话持续时间"
OBSWebSocket.SessionTable.MessagesInOutColumnTitle="消息传入/出" OBSWebSocket.SessionTable.MessagesInOutColumnTitle="消息传入/出"
OBSWebSocket.SessionTable.IdentifiedTitle="已识别" OBSWebSocket.SessionTable.IdentifiedTitle="已识别"
OBSWebSocket.SessionTable.KickButtonColumnTitle="踢出?" OBSWebSocket.SessionTable.KickButtonColumnTitle="踢出?"
OBSWebSocket.SessionTable.KickButtonText="踢出" OBSWebSocket.SessionTable.KickButtonText="踢出"
@ -31,13 +31,11 @@ OBSWebSocket.ConnectInfo.CopyText="复制"
OBSWebSocket.ConnectInfo.ServerIp="服务器 IP最佳猜测" OBSWebSocket.ConnectInfo.ServerIp="服务器 IP最佳猜测"
OBSWebSocket.ConnectInfo.ServerPort="服务器端口" OBSWebSocket.ConnectInfo.ServerPort="服务器端口"
OBSWebSocket.ConnectInfo.ServerPassword="服务器密码" OBSWebSocket.ConnectInfo.ServerPassword="服务器密码"
OBSWebSocket.ConnectInfo.ServerPasswordPlaceholderText="[鉴权已停用]" OBSWebSocket.ConnectInfo.ServerPasswordPlaceholderText="[身份认证已停用]"
OBSWebSocket.ConnectInfo.QrTitle="连接 QR 码" OBSWebSocket.ConnectInfo.QrTitle="连接 QR 码"
OBSWebSocket.TrayNotification.Identified.Title="新 WebSocket 连接" OBSWebSocket.TrayNotification.Identified.Title="新 WebSocket 连接"
OBSWebSocket.TrayNotification.Identified.Body="已识别 %1 客户端。" OBSWebSocket.TrayNotification.Identified.Body="客户端%1已识别 。"
OBSWebSocket.TrayNotification.AuthenticationFailed.Title="WebSocket 鉴权失败" OBSWebSocket.TrayNotification.AuthenticationFailed.Title="WebSocket 认证失败"
OBSWebSocket.TrayNotification.AuthenticationFailed.Body="%1 客户端认证失败。" OBSWebSocket.TrayNotification.AuthenticationFailed.Body="%1 客户端认证失败。"
OBSWebSocket.TrayNotification.Disconnected.Title="WebSocket 客户端已断开" OBSWebSocket.TrayNotification.Disconnected.Title="WebSocket 客户端已断开"
OBSWebSocket.TrayNotification.Disconnected.Body="%1 客户端已断开。" OBSWebSocket.TrayNotification.Disconnected.Body="%1 客户端已断开。"
OBSWebSocket.Server.StartFailed.Title="WebSocket 服务器启动失败"
OBSWebSocket.Server.StartFailed.Message="WebSocket 服务器启动失败。TCP 端口 %1 可能已被其它程序占用。请尝试在 WebSocket 服务器设置中更改不同的 TCP 端口号,或者结束其它任何可能占用此端口的程序。\n错误信息%2"

View File

@ -1,5 +1,5 @@
OBSWebSocket.Plugin.Description="透過 WebSocket 遠端控制 OBS Studio" OBSWebSocket.Plugin.Description="透過 WebSocket 遠端控制 OBS Studio"
OBSWebSocket.Settings.DialogTitle="obs-websocket 設定" OBSWebSocket.Settings.DialogTitle="WebSocket 伺服器設定"
OBSWebSocket.Settings.PluginSettingsTitle="外掛程式設定" OBSWebSocket.Settings.PluginSettingsTitle="外掛程式設定"
OBSWebSocket.Settings.ServerEnable="啟用 WebSocket 伺服器" OBSWebSocket.Settings.ServerEnable="啟用 WebSocket 伺服器"
OBSWebSocket.Settings.AlertsEnable="啟用系統匣通知" OBSWebSocket.Settings.AlertsEnable="啟用系統匣通知"
@ -39,5 +39,3 @@ OBSWebSocket.TrayNotification.AuthenticationFailed.Title="WebSocket 認證失敗
OBSWebSocket.TrayNotification.AuthenticationFailed.Body="%1 用戶端無法進行認證。" OBSWebSocket.TrayNotification.AuthenticationFailed.Body="%1 用戶端無法進行認證。"
OBSWebSocket.TrayNotification.Disconnected.Title="WebSocket 用戶端已斷線" OBSWebSocket.TrayNotification.Disconnected.Title="WebSocket 用戶端已斷線"
OBSWebSocket.TrayNotification.Disconnected.Body="%1 用戶端已斷線。" OBSWebSocket.TrayNotification.Disconnected.Body="%1 用戶端已斷線。"
OBSWebSocket.Server.StartFailed.Title="WebSocket 伺服器錯誤"
OBSWebSocket.Server.StartFailed.Message="無法啟動 WebSocket 伺服器。可能 TCP 連線埠 %1 已經被系統中的某個應用程式佔用。請嘗試在 WebSocket 伺服器設定更改不同的 TCP 連線埠,或停止任何可能正在使用這個連線埠的應用程式。\n錯誤訊息%2"

1
deps/asio vendored

Submodule deps/asio deleted from b73dc1d2c0

1
deps/json vendored

Submodule deps/json deleted from a34e011e24

1
deps/qr vendored

Submodule deps/qr deleted from 8518684c0f

1
deps/websocketpp vendored

Submodule deps/websocketpp deleted from 56123c8759

View File

@ -1,5 +1,7 @@
# obs-websocket documentation # 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: 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. - `comments/comments.js`: Generates the `work/comments.json` file from the code comments in the src directory.

View File

@ -9,7 +9,9 @@ enumTypeOrder = [
'WebSocketCloseCode', 'WebSocketCloseCode',
'RequestBatchExecutionType', 'RequestBatchExecutionType',
'RequestStatus', 'RequestStatus',
'EventSubscription' 'EventSubscription',
'ObsMediaInputAction',
'ObsOutputState'
] ]
categoryOrder = [ categoryOrder = [

View File

@ -1,5 +1,5 @@
# obs-websocket 5.0.1 Protocol # obs-websocket 5.x.x Protocol
## Main Table of Contents ## Main Table of Contents
@ -19,6 +19,9 @@
- [RequestResponse (OpCode 7)](#requestresponse-opcode-7) - [RequestResponse (OpCode 7)](#requestresponse-opcode-7)
- [RequestBatch (OpCode 8)](#requestbatch-opcode-8) - [RequestBatch (OpCode 8)](#requestbatch-opcode-8)
- [RequestBatchResponse (OpCode 9)](#requestbatchresponse-opcode-9) - [RequestBatchResponse (OpCode 9)](#requestbatchresponse-opcode-9)
- [Enumerations](#enums)
- [Events](#events)
- [Requests](#requests)
## General Intro ## General Intro
@ -58,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. - 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 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. - 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). - Once identification is processed on the server, the server responds to the client with an [OpCode 2 `Identified`](#identified-opcode-2).
@ -143,7 +146,7 @@ Authentication is required
{ {
"op": 0, "op": 0,
"d": { "d": {
"obsWebSocketVersion": "5.0.1", "obsWebSocketVersion": "5.1.0",
"rpcVersion": 1, "rpcVersion": 1,
"authentication": { "authentication": {
"challenge": "+IxH4CnCiqpX1rM9scsNynZzbOe4KhDeYcTNS3PDaeY=", "challenge": "+IxH4CnCiqpX1rM9scsNynZzbOe4KhDeYcTNS3PDaeY=",
@ -159,7 +162,7 @@ Authentication is not required
{ {
"op": 0, "op": 0,
"d": { "d": {
"obsWebSocketVersion": "5.0.1", "obsWebSocketVersion": "5.1.0",
"rpcVersion": 1 "rpcVersion": 1
} }
} }

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -22,7 +22,7 @@ with this program. If not, see <https://www.gnu.org/licenses/>
#include <obs.h> #include <obs.h>
#define OBS_WEBSOCKET_API_VERSION 2 #define OBS_WEBSOCKET_API_VERSION 3
#ifdef __cplusplus #ifdef __cplusplus
extern "C" { extern "C" {
@ -30,6 +30,7 @@ extern "C" {
typedef void *obs_websocket_vendor; typedef void *obs_websocket_vendor;
typedef void (*obs_websocket_request_callback_function)(obs_data_t *, obs_data_t *, void *); typedef void (*obs_websocket_request_callback_function)(obs_data_t *, obs_data_t *, void *);
typedef void (*obs_websocket_event_callback_function)(uint64_t, const char *, const char *, void *);
struct obs_websocket_request_response { struct obs_websocket_request_response {
unsigned int status_code; unsigned int status_code;
@ -44,7 +45,12 @@ struct obs_websocket_request_callback {
void *priv_data; void *priv_data;
}; };
inline proc_handler_t *_ph; struct obs_websocket_event_callback {
obs_websocket_event_callback_function callback;
void *priv_data;
};
static proc_handler_t *_ph;
/* ==================== INTERNAL API FUNCTIONS ==================== */ /* ==================== INTERNAL API FUNCTIONS ==================== */
@ -53,7 +59,7 @@ static inline proc_handler_t *obs_websocket_get_ph(void)
proc_handler_t *global_ph = obs_get_proc_handler(); proc_handler_t *global_ph = obs_get_proc_handler();
assert(global_ph != NULL); 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)) 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?"); 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"); proc_handler_t *ret = (proc_handler_t *)calldata_ptr(&cd, "ph");
@ -91,7 +97,7 @@ static inline unsigned int obs_websocket_get_api_version(void)
if (!obs_websocket_ensure_ph()) if (!obs_websocket_ensure_ph())
return 0; return 0;
calldata_t cd = {0}; calldata_t cd = {0, 0, 0, 0};
if (!proc_handler_call(_ph, "get_api_version", &cd)) if (!proc_handler_call(_ph, "get_api_version", &cd))
return 1; // API v1 does not include get_api_version return 1; // API v1 does not include get_api_version
@ -104,7 +110,11 @@ static inline unsigned int obs_websocket_get_api_version(void)
} }
// Calls an obs-websocket request. Free response with `obs_websocket_request_response_free()` // 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()) if (!obs_websocket_ensure_ph())
return NULL; return NULL;
@ -113,14 +123,13 @@ static inline obs_websocket_request_response *obs_websocket_call_request(const c
if (request_data) if (request_data)
request_data_string = obs_data_get_json(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_type", request_type);
calldata_set_string(&cd, "request_data", request_data_string); calldata_set_string(&cd, "request_data", request_data_string);
proc_handler_call(_ph, "call_request", &cd); 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); calldata_free(&cd);
@ -140,6 +149,46 @@ static inline void obs_websocket_request_response_free(struct obs_websocket_requ
bfree(response); bfree(response);
} }
// Register an event handler to receive obs-websocket events
static inline bool obs_websocket_register_event_callback(obs_websocket_event_callback_function event_callback, void *priv_data)
{
if (!obs_websocket_ensure_ph())
return false;
struct obs_websocket_event_callback cb = {event_callback, priv_data};
calldata_t cd = {0, 0, 0, 0};
calldata_set_ptr(&cd, "callback", &cb);
proc_handler_call(_ph, "register_event_callback", &cd);
bool ret = calldata_bool(&cd, "success");
calldata_free(&cd);
return ret;
}
// Unregister an existing event handler
static inline bool obs_websocket_unregister_event_callback(obs_websocket_event_callback_function event_callback, void *priv_data)
{
if (!obs_websocket_ensure_ph())
return false;
struct obs_websocket_event_callback cb = {event_callback, priv_data};
calldata_t cd = {0, 0, 0, 0};
calldata_set_ptr(&cd, "callback", &cb);
proc_handler_call(_ph, "unregister_event_callback", &cd);
bool ret = calldata_bool(&cd, "success");
calldata_free(&cd);
return ret;
}
/* ==================== VENDOR API FUNCTIONS ==================== */ /* ==================== VENDOR API FUNCTIONS ==================== */
// ALWAYS CALL ONLY VIA `obs_module_post_load()` CALLBACK! // ALWAYS CALL ONLY VIA `obs_module_post_load()` CALLBACK!
@ -149,8 +198,7 @@ static inline obs_websocket_vendor obs_websocket_register_vendor(const char *ven
if (!obs_websocket_ensure_ph()) if (!obs_websocket_ensure_ph())
return NULL; return NULL;
calldata_t cd = {0}; calldata_t cd = {0, 0, 0, 0};
calldata_set_string(&cd, "name", vendor_name); calldata_set_string(&cd, "name", vendor_name);
proc_handler_call(_ph, "vendor_register", &cd); proc_handler_call(_ph, "vendor_register", &cd);
@ -164,12 +212,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, 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) obs_websocket_request_callback_function request_callback, void *priv_data)
{ {
calldata_t cd = {0}; struct obs_websocket_request_callback cb = {request_callback, priv_data};
struct obs_websocket_request_callback cb = {};
cb.callback = request_callback;
cb.priv_data = priv_data;
calldata_t cd = {0, 0, 0, 0};
calldata_set_string(&cd, "type", request_type); calldata_set_string(&cd, "type", request_type);
calldata_set_ptr(&cd, "callback", &cb); calldata_set_ptr(&cd, "callback", &cb);
@ -182,8 +227,7 @@ static inline bool obs_websocket_vendor_register_request(obs_websocket_vendor ve
// Unregisters an existing vendor request // Unregisters an existing vendor request
static inline bool obs_websocket_vendor_unregister_request(obs_websocket_vendor vendor, const char *request_type) 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); calldata_set_string(&cd, "type", request_type);
bool success = obs_websocket_vendor_run_simple_proc(vendor, "vendor_request_unregister", &cd); bool success = obs_websocket_vendor_run_simple_proc(vendor, "vendor_request_unregister", &cd);
@ -196,8 +240,7 @@ static inline bool obs_websocket_vendor_unregister_request(obs_websocket_vendor
// Emits an event under the vendor's name // 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) 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_string(&cd, "type", event_name);
calldata_set_ptr(&cd, "data", (void *)event_data); calldata_set_ptr(&cd, "data", (void *)event_data);

View File

@ -17,70 +17,80 @@ You should have received a copy of the GNU General Public License along
with this program. If not, see <https://www.gnu.org/licenses/> with this program. If not, see <https://www.gnu.org/licenses/>
*/ */
#include <filesystem>
#include <obs-frontend-api.h> #include <obs-frontend-api.h>
#include "Config.h" #include "Config.h"
#include "utils/Crypto.h" #include "utils/Crypto.h"
#include "utils/Platform.h" #include "utils/Platform.h"
#include "utils/Obs.h"
#define CONFIG_SECTION_NAME "OBSWebSocket" #define CONFIG_SECTION_NAME "OBSWebSocket"
#define CONFIG_PARAM_FIRSTLOAD "FirstLoad"
#define CONFIG_PARAM_ENABLED "ServerEnabled"
#define CONFIG_PARAM_PORT "ServerPort"
#define CONFIG_PARAM_ALERTS "AlertsEnabled"
#define CONFIG_PARAM_AUTHREQUIRED "AuthRequired"
#define CONFIG_PARAM_PASSWORD "ServerPassword"
#define PARAM_FIRSTLOAD "FirstLoad" #define CONFIG_FILE_NAME "config.json"
#define PARAM_ENABLED "ServerEnabled" #define PARAM_FIRSTLOAD "first_load"
#define PARAM_PORT "ServerPort" #define PARAM_ENABLED "server_enabled"
#define PARAM_ALERTS "AlertsEnabled" #define PARAM_PORT "server_port"
#define PARAM_AUTHREQUIRED "AuthRequired" #define PARAM_ALERTS "alerts_enabled"
#define PARAM_PASSWORD "ServerPassword" #define PARAM_AUTHREQUIRED "auth_required"
#define PARAM_PASSWORD "server_password"
#define CMDLINE_WEBSOCKET_PORT "websocket_port" #define CMDLINE_WEBSOCKET_PORT "websocket_port"
#define CMDLINE_WEBSOCKET_IPV4_ONLY "websocket_ipv4_only" #define CMDLINE_WEBSOCKET_IPV4_ONLY "websocket_ipv4_only"
#define CMDLINE_WEBSOCKET_PASSWORD "websocket_password" #define CMDLINE_WEBSOCKET_PASSWORD "websocket_password"
#define CMDLINE_WEBSOCKET_DEBUG "websocket_debug" #define CMDLINE_WEBSOCKET_DEBUG "websocket_debug"
Config::Config() void Config::Load(json config)
: PortOverridden(false),
PasswordOverridden(false),
FirstLoad(true),
ServerEnabled(false),
ServerPort(4455),
Ipv4Only(false),
DebugEnabled(false),
AlertsEnabled(false),
AuthRequired(true),
ServerPassword("")
{ {
SetDefaultsToGlobalStore(); // Only load from plugin config directory if there hasn't been a migration
} if (config.is_null()) {
std::string configFilePath = Utils::Obs::StringHelper::GetModuleConfigPath(CONFIG_FILE_NAME);
void Config::Load() Utils::Json::GetJsonFileContent(configFilePath, config); // Fetch the existing config, which may not exist
{
config_t *obsConfig = GetConfigStore();
if (!obsConfig) {
blog(LOG_ERROR, "[Config::Load] Unable to fetch OBS config!");
return;
} }
FirstLoad = config_get_bool(obsConfig, CONFIG_SECTION_NAME, PARAM_FIRSTLOAD); if (!config.is_object()) {
ServerEnabled = config_get_bool(obsConfig, CONFIG_SECTION_NAME, PARAM_ENABLED); blog(LOG_INFO, "[Config::Load] Existing configuration not found, using defaults.");
AlertsEnabled = config_get_bool(obsConfig, CONFIG_SECTION_NAME, PARAM_ALERTS); config = json::object();
ServerPort = config_get_uint(obsConfig, CONFIG_SECTION_NAME, PARAM_PORT); }
AuthRequired = config_get_bool(obsConfig, CONFIG_SECTION_NAME, PARAM_AUTHREQUIRED);
ServerPassword = config_get_string(obsConfig, CONFIG_SECTION_NAME, PARAM_PASSWORD); if (config.contains(PARAM_FIRSTLOAD) && config[PARAM_FIRSTLOAD].is_boolean())
FirstLoad = config[PARAM_FIRSTLOAD];
if (config.contains(PARAM_ENABLED) && config[PARAM_ENABLED].is_boolean())
ServerEnabled = config[PARAM_ENABLED];
if (config.contains(PARAM_ALERTS) && config[PARAM_ALERTS].is_boolean())
AlertsEnabled = config[PARAM_ALERTS];
if (config.contains(PARAM_PORT) && config[PARAM_PORT].is_number_unsigned())
ServerPort = config[PARAM_PORT];
if (config.contains(PARAM_AUTHREQUIRED) && config[PARAM_AUTHREQUIRED].is_boolean())
AuthRequired = config[PARAM_AUTHREQUIRED];
if (config.contains(PARAM_PASSWORD) && config[PARAM_PASSWORD].is_string())
ServerPassword = config[PARAM_PASSWORD];
// Set server password and save it to the config before processing overrides, // Set server password and save it to the config before processing overrides,
// so that there is always a true configured password regardless of if // so that there is always a true configured password regardless of if
// future loads use the override flag. // future loads use the override flag.
if (FirstLoad) { if (FirstLoad) {
FirstLoad = false; FirstLoad = false;
if (ServerPassword.isEmpty()) { if (ServerPassword.empty()) {
blog(LOG_INFO, "[Config::Load] (FirstLoad) Generating new server password."); blog(LOG_INFO, "[Config::Load] (FirstLoad) Generating new server password.");
ServerPassword = QString::fromStdString(Utils::Crypto::GeneratePassword()); ServerPassword = Utils::Crypto::GeneratePassword();
} else { } else {
blog(LOG_INFO, "[Config::Load] (FirstLoad) Not generating new password since one is already configured."); blog(LOG_INFO, "[Config::Load] (FirstLoad) Not generating new password since one is already configured.");
} }
Save(); Save();
} }
// If there are migrated settings, write them to disk before processing arguments.
if (!config.empty())
Save();
// Process `--websocket_port` override // Process `--websocket_port` override
QString portArgument = Utils::Platform::GetCommandLineArgument(CMDLINE_WEBSOCKET_PORT); QString portArgument = Utils::Platform::GetCommandLineArgument(CMDLINE_WEBSOCKET_PORT);
if (portArgument != "") { if (portArgument != "") {
@ -107,7 +117,7 @@ void Config::Load()
blog(LOG_INFO, "[Config::Load] --websocket_password passed. Overriding WebSocket password."); blog(LOG_INFO, "[Config::Load] --websocket_password passed. Overriding WebSocket password.");
PasswordOverridden = true; PasswordOverridden = true;
AuthRequired = true; AuthRequired = true;
ServerPassword = passwordArgument; ServerPassword = passwordArgument.toStdString();
} }
// Process `--websocket_debug` override // Process `--websocket_debug` override
@ -120,43 +130,98 @@ void Config::Load()
void Config::Save() void Config::Save()
{ {
config_t *obsConfig = GetConfigStore(); json config;
if (!obsConfig) {
blog(LOG_ERROR, "[Config::Save] Unable to fetch OBS config!");
return;
}
config_set_bool(obsConfig, CONFIG_SECTION_NAME, PARAM_FIRSTLOAD, FirstLoad); std::string configFilePath = Utils::Obs::StringHelper::GetModuleConfigPath(CONFIG_FILE_NAME);
config_set_bool(obsConfig, CONFIG_SECTION_NAME, PARAM_ENABLED, ServerEnabled); Utils::Json::GetJsonFileContent(configFilePath, config); // Fetch the existing config, which may not exist
if (!PortOverridden) {
config_set_uint(obsConfig, CONFIG_SECTION_NAME, PARAM_PORT, ServerPort); config[PARAM_FIRSTLOAD] = FirstLoad.load();
} config[PARAM_ENABLED] = ServerEnabled.load();
config_set_bool(obsConfig, CONFIG_SECTION_NAME, PARAM_ALERTS, AlertsEnabled); if (!PortOverridden)
config[PARAM_PORT] = ServerPort.load();
config[PARAM_ALERTS] = AlertsEnabled.load();
if (!PasswordOverridden) { if (!PasswordOverridden) {
config_set_bool(obsConfig, CONFIG_SECTION_NAME, PARAM_AUTHREQUIRED, AuthRequired); config[PARAM_AUTHREQUIRED] = AuthRequired.load();
config_set_string(obsConfig, CONFIG_SECTION_NAME, PARAM_PASSWORD, QT_TO_UTF8(ServerPassword)); config[PARAM_PASSWORD] = ServerPassword;
} }
config_save(obsConfig); if (Utils::Json::SetJsonFileContent(configFilePath, config))
blog(LOG_DEBUG, "[Config::Save] Saved config.");
else
blog(LOG_ERROR, "[Config::Save] Failed to write config file!");
} }
void Config::SetDefaultsToGlobalStore() // Finds any old values in global.ini and removes them, then returns the values as JSON
json MigrateGlobalConfigData()
{ {
config_t *obsConfig = GetConfigStore(); // Get existing global config
if (!obsConfig) { config_t *config = obs_frontend_get_global_config();
blog(LOG_ERROR, "[Config::SetDefaultsToGlobalStore] Unable to fetch OBS config!"); json ret;
return;
// Move values to temporary JSON blob
if (config_has_user_value(config, CONFIG_SECTION_NAME, CONFIG_PARAM_FIRSTLOAD)) {
ret[PARAM_FIRSTLOAD] = config_get_bool(config, CONFIG_SECTION_NAME, CONFIG_PARAM_FIRSTLOAD);
config_remove_value(config, CONFIG_SECTION_NAME, CONFIG_PARAM_FIRSTLOAD);
}
if (config_has_user_value(config, CONFIG_SECTION_NAME, CONFIG_PARAM_ENABLED)) {
ret[PARAM_ENABLED] = config_get_bool(config, CONFIG_SECTION_NAME, CONFIG_PARAM_ENABLED);
config_remove_value(config, CONFIG_SECTION_NAME, CONFIG_PARAM_ENABLED);
}
if (config_has_user_value(config, CONFIG_SECTION_NAME, CONFIG_PARAM_PORT)) {
ret[PARAM_PORT] = config_get_uint(config, CONFIG_SECTION_NAME, CONFIG_PARAM_PORT);
config_remove_value(config, CONFIG_SECTION_NAME, CONFIG_PARAM_PORT);
}
if (config_has_user_value(config, CONFIG_SECTION_NAME, CONFIG_PARAM_ALERTS)) {
ret[PARAM_ALERTS] = config_get_bool(config, CONFIG_SECTION_NAME, CONFIG_PARAM_ALERTS);
config_remove_value(config, CONFIG_SECTION_NAME, CONFIG_PARAM_ALERTS);
}
if (config_has_user_value(config, CONFIG_SECTION_NAME, CONFIG_PARAM_AUTHREQUIRED)) {
ret[PARAM_AUTHREQUIRED] = config_get_bool(config, CONFIG_SECTION_NAME, CONFIG_PARAM_AUTHREQUIRED);
config_remove_value(config, CONFIG_SECTION_NAME, CONFIG_PARAM_AUTHREQUIRED);
}
if (config_has_user_value(config, CONFIG_SECTION_NAME, CONFIG_PARAM_PASSWORD)) {
ret[PARAM_PASSWORD] = config_get_string(config, CONFIG_SECTION_NAME, CONFIG_PARAM_PASSWORD);
config_remove_value(config, CONFIG_SECTION_NAME, CONFIG_PARAM_PASSWORD);
} }
config_set_default_bool(obsConfig, CONFIG_SECTION_NAME, PARAM_FIRSTLOAD, FirstLoad); if (!ret.is_null()) {
config_set_default_bool(obsConfig, CONFIG_SECTION_NAME, PARAM_ENABLED, ServerEnabled); blog(LOG_INFO, "[MigrateGlobalConfigData] Some configurations have been migrated from old config");
config_set_default_uint(obsConfig, CONFIG_SECTION_NAME, PARAM_PORT, ServerPort); config_save(config);
config_set_default_bool(obsConfig, CONFIG_SECTION_NAME, PARAM_ALERTS, AlertsEnabled); }
config_set_default_bool(obsConfig, CONFIG_SECTION_NAME, PARAM_AUTHREQUIRED, AuthRequired);
config_set_default_string(obsConfig, CONFIG_SECTION_NAME, PARAM_PASSWORD, QT_TO_UTF8(ServerPassword)); return ret;
} }
config_t *Config::GetConfigStore() // Migration from storing persistent data in obsWebSocketPersistentData.json to the module config directory
// This will overwrite any persistent data in the destination. People doing manual OBS config modification be warned!
bool MigratePersistentData()
{ {
return obs_frontend_get_global_config(); std::error_code ec;
// Ensure module config directory exists
auto moduleConfigDirectory = std::filesystem::u8path(Utils::Obs::StringHelper::GetModuleConfigPath(""));
if (!std::filesystem::exists(moduleConfigDirectory, ec))
std::filesystem::create_directories(moduleConfigDirectory, ec);
if (ec) {
blog(LOG_ERROR, "[MigratePersistentData] Failed to create directory `%s`: %s", moduleConfigDirectory.c_str(),
ec.message().c_str());
return false;
}
// Move any existing persistent data to module config directory, then delete old file
auto oldPersistentDataPath = std::filesystem::u8path(Utils::Obs::StringHelper::GetCurrentProfilePath() +
"/../../../obsWebSocketPersistentData.json");
if (std::filesystem::exists(oldPersistentDataPath, ec)) {
auto persistentDataPath =
std::filesystem::u8path(Utils::Obs::StringHelper::GetModuleConfigPath("persistent_data.json"));
std::filesystem::copy_file(oldPersistentDataPath, persistentDataPath, ec);
std::filesystem::remove(oldPersistentDataPath, ec);
blog(LOG_INFO, "[MigratePersistentData] Persistent data migrated to new path");
}
if (ec) {
blog(LOG_ERROR, "[MigratePersistentData] Failed to move persistent data: %s", ec.message().c_str());
return false;
}
return true;
} }

View File

@ -23,24 +23,25 @@ with this program. If not, see <https://www.gnu.org/licenses/>
#include <QString> #include <QString>
#include <util/config-file.h> #include <util/config-file.h>
#include "utils/Json.h"
#include "plugin-macros.generated.h" #include "plugin-macros.generated.h"
struct Config { struct Config {
Config(); void Load(json config = nullptr);
void Load();
void Save(); void Save();
void SetDefaultsToGlobalStore();
config_t *GetConfigStore();
std::atomic<bool> PortOverridden; std::atomic<bool> PortOverridden = false;
std::atomic<bool> PasswordOverridden; std::atomic<bool> PasswordOverridden = false;
std::atomic<bool> FirstLoad; std::atomic<bool> FirstLoad = true;
std::atomic<bool> ServerEnabled; std::atomic<bool> ServerEnabled = false;
std::atomic<uint16_t> ServerPort; std::atomic<uint16_t> ServerPort = 4455;
std::atomic<bool> Ipv4Only; std::atomic<bool> Ipv4Only = false;
std::atomic<bool> DebugEnabled; std::atomic<bool> DebugEnabled = false;
std::atomic<bool> AlertsEnabled; std::atomic<bool> AlertsEnabled = false;
std::atomic<bool> AuthRequired; std::atomic<bool> AuthRequired = true;
QString ServerPassword; std::string ServerPassword;
}; };
json MigrateGlobalConfigData();
bool MigratePersistentData();

View File

@ -1,6 +1,23 @@
/*
obs-websocket
Copyright (C) 2020-2023 Kyle Manning <tt2468@gmail.com>
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 <https://www.gnu.org/licenses/>
*/
#include "WebSocketApi.h" #include "WebSocketApi.h"
#include "requesthandler/RequestHandler.h" #include "requesthandler/RequestHandler.h"
#include "obs-websocket.h"
#include "utils/Json.h" #include "utils/Json.h"
#define RETURN_STATUS(status) \ #define RETURN_STATUS(status) \
@ -30,14 +47,19 @@ WebSocketApi::WebSocketApi()
proc_handler_add(_procHandler, "bool get_api_version(out int version)", &get_api_version, nullptr); proc_handler_add(_procHandler, "bool get_api_version(out int version)", &get_api_version, nullptr);
proc_handler_add(_procHandler, "bool call_request(in string request_type, in string request_data, out ptr response)", proc_handler_add(_procHandler, "bool call_request(in string request_type, in string request_data, out ptr response)",
&call_request, nullptr); &call_request, this);
proc_handler_add(_procHandler, "bool vendor_register(in string name, out ptr vendor)", &vendor_register_cb, this); proc_handler_add(_procHandler, "bool register_event_callback(in ptr callback, out bool success)", &register_event_callback,
proc_handler_add(_procHandler, "bool vendor_request_register(in ptr vendor, in string type, in ptr callback)",
&vendor_request_register_cb, this);
proc_handler_add(_procHandler, "bool vendor_request_unregister(in ptr vendor, in string type)",
&vendor_request_unregister_cb, this);
proc_handler_add(_procHandler, "bool vendor_event_emit(in ptr vendor, in string type, in ptr data)", &vendor_event_emit_cb,
this); this);
proc_handler_add(_procHandler, "bool unregister_event_callback(in ptr callback, out bool success)",
&unregister_event_callback, this);
proc_handler_add(_procHandler, "bool vendor_register(in string name, out ptr vendor)", &vendor_register_cb, this);
proc_handler_add(_procHandler,
"bool vendor_request_register(in ptr vendor, in string type, in ptr callback, out bool success)",
&vendor_request_register_cb, this);
proc_handler_add(_procHandler, "bool vendor_request_unregister(in ptr vendor, in string type, out bool success)",
&vendor_request_unregister_cb, this);
proc_handler_add(_procHandler, "bool vendor_event_emit(in ptr vendor, in string type, in ptr data, out bool success)",
&vendor_event_emit_cb, this);
proc_handler_t *ph = obs_get_proc_handler(); proc_handler_t *ph = obs_get_proc_handler();
assert(ph != NULL); assert(ph != NULL);
@ -53,6 +75,10 @@ WebSocketApi::~WebSocketApi()
proc_handler_destroy(_procHandler); proc_handler_destroy(_procHandler);
size_t numEventCallbacks = _eventCallbacks.size();
_eventCallbacks.clear();
blog_debug("[WebSocketApi::~WebSocketApi] Deleted %ld event callbacks", numEventCallbacks);
for (auto vendor : _vendors) { for (auto vendor : _vendors) {
blog_debug("[WebSocketApi::~WebSocketApi] Deleting vendor: %s", vendor.first.c_str()); blog_debug("[WebSocketApi::~WebSocketApi] Deleting vendor: %s", vendor.first.c_str());
delete vendor.second; delete vendor.second;
@ -61,9 +87,21 @@ WebSocketApi::~WebSocketApi()
blog_debug("[WebSocketApi::~WebSocketApi] Finished."); blog_debug("[WebSocketApi::~WebSocketApi] Finished.");
} }
void WebSocketApi::SetEventCallback(EventCallback cb) void WebSocketApi::BroadcastEvent(uint64_t requiredIntent, const std::string &eventType, const json &eventData, uint8_t rpcVersion)
{ {
_eventCallback = cb; if (!_obsReady)
return;
// Only broadcast events applicable to the latest RPC version
if (rpcVersion && rpcVersion != CURRENT_RPC_VERSION)
return;
std::string eventDataString = eventData.dump();
std::shared_lock l(_mutex);
for (auto &cb : _eventCallbacks)
cb.callback(requiredIntent, eventType.c_str(), eventDataString.c_str(), cb.priv_data);
} }
enum WebSocketApi::RequestReturnCode WebSocketApi::PerformVendorRequest(std::string vendorName, std::string requestType, enum WebSocketApi::RequestReturnCode WebSocketApi::PerformVendorRequest(std::string vendorName, std::string requestType,
@ -108,14 +146,27 @@ void WebSocketApi::get_api_version(void *, calldata_t *cd)
RETURN_SUCCESS(); RETURN_SUCCESS();
} }
void WebSocketApi::call_request(void *, calldata_t *cd) void WebSocketApi::call_request(void *priv_data, calldata_t *cd)
{ {
auto c = static_cast<WebSocketApi *>(priv_data);
#if !defined(PLUGIN_TESTS)
if (!c->_obsReady)
RETURN_FAILURE();
#endif
const char *request_type = calldata_string(cd, "request_type"); const char *request_type = calldata_string(cd, "request_type");
const char *request_data = calldata_string(cd, "request_data"); const char *request_data = calldata_string(cd, "request_data");
if (!request_type) if (!request_type)
RETURN_FAILURE(); RETURN_FAILURE();
#ifdef PLUGIN_TESTS
// Allow plugin tests to complete, even though OBS wouldn't be ready at the time of the test
if (!c->_obsReady && std::string(request_type) != "GetVersion")
RETURN_FAILURE();
#endif
auto response = static_cast<obs_websocket_request_response *>(bzalloc(sizeof(struct obs_websocket_request_response))); auto response = static_cast<obs_websocket_request_response *>(bzalloc(sizeof(struct obs_websocket_request_response)));
if (!response) if (!response)
RETURN_FAILURE(); RETURN_FAILURE();
@ -144,6 +195,52 @@ void WebSocketApi::call_request(void *, calldata_t *cd)
RETURN_SUCCESS(); RETURN_SUCCESS();
} }
void WebSocketApi::register_event_callback(void *priv_data, calldata_t *cd)
{
auto c = static_cast<WebSocketApi *>(priv_data);
void *voidCallback;
if (!calldata_get_ptr(cd, "callback", &voidCallback) || !voidCallback) {
blog(LOG_WARNING, "[WebSocketApi::register_event_callback] Failed due to missing `callback` pointer.");
RETURN_FAILURE();
}
auto cb = static_cast<obs_websocket_event_callback *>(voidCallback);
std::unique_lock l(c->_mutex);
int64_t foundIndex = c->GetEventCallbackIndex(*cb);
if (foundIndex != -1)
RETURN_FAILURE();
c->_eventCallbacks.push_back(*cb);
RETURN_SUCCESS();
}
void WebSocketApi::unregister_event_callback(void *priv_data, calldata_t *cd)
{
auto c = static_cast<WebSocketApi *>(priv_data);
void *voidCallback;
if (!calldata_get_ptr(cd, "callback", &voidCallback) || !voidCallback) {
blog(LOG_WARNING, "[WebSocketApi::register_event_callback] Failed due to missing `callback` pointer.");
RETURN_FAILURE();
}
auto cb = static_cast<obs_websocket_event_callback *>(voidCallback);
std::unique_lock l(c->_mutex);
int64_t foundIndex = c->GetEventCallbackIndex(*cb);
if (foundIndex == -1)
RETURN_FAILURE();
c->_eventCallbacks.erase(c->_eventCallbacks.begin() + foundIndex);
RETURN_SUCCESS();
}
void WebSocketApi::vendor_register_cb(void *priv_data, calldata_t *cd) void WebSocketApi::vendor_register_cb(void *priv_data, calldata_t *cd)
{ {
auto c = static_cast<WebSocketApi *>(priv_data); auto c = static_cast<WebSocketApi *>(priv_data);
@ -154,7 +251,7 @@ void WebSocketApi::vendor_register_cb(void *priv_data, calldata_t *cd)
RETURN_FAILURE(); RETURN_FAILURE();
} }
// Theoretically doesn't need a mutex, but it's good to be safe. // Theoretically doesn't need a mutex due to module load being single-thread, but it's good to be safe.
std::unique_lock l(c->_mutex); std::unique_lock l(c->_mutex);
if (c->_vendors.count(vendorName)) { if (c->_vendors.count(vendorName)) {
@ -271,10 +368,10 @@ void WebSocketApi::vendor_event_emit_cb(void *priv_data, calldata_t *cd)
auto eventData = static_cast<obs_data_t *>(voidEventData); auto eventData = static_cast<obs_data_t *>(voidEventData);
if (!c->_eventCallback) if (!c->_vendorEventCallback)
RETURN_FAILURE(); RETURN_FAILURE();
c->_eventCallback(v->_name, eventType, eventData); c->_vendorEventCallback(v->_name, eventType, eventData);
RETURN_SUCCESS(); RETURN_SUCCESS();
} }

View File

@ -1,3 +1,21 @@
/*
obs-websocket
Copyright (C) 2020-2023 Kyle Manning <tt2468@gmail.com>
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 <https://www.gnu.org/licenses/>
*/
#pragma once #pragma once
#include <functional> #include <functional>
@ -5,9 +23,12 @@
#include <map> #include <map>
#include <mutex> #include <mutex>
#include <shared_mutex> #include <shared_mutex>
#include <atomic>
#include <obs.h> #include <obs.h>
#include <obs-websocket-api.h>
#include "../lib/obs-websocket-api.h" #include "utils/Json.h"
#include "plugin-macros.generated.h"
class WebSocketApi { class WebSocketApi {
public: public:
@ -17,8 +38,6 @@ public:
NoVendorRequest, NoVendorRequest,
}; };
typedef std::function<void(std::string, std::string, obs_data_t *)> EventCallback;
struct Vendor { struct Vendor {
std::shared_mutex _mutex; std::shared_mutex _mutex;
std::string _name; std::string _name;
@ -27,23 +46,44 @@ public:
WebSocketApi(); WebSocketApi();
~WebSocketApi(); ~WebSocketApi();
void BroadcastEvent(uint64_t requiredIntent, const std::string &eventType, const json &eventData = nullptr,
void SetEventCallback(EventCallback cb); uint8_t rpcVersion = 0);
void SetObsReady(bool ready) { _obsReady = ready; }
enum RequestReturnCode PerformVendorRequest(std::string vendorName, std::string requestName, obs_data_t *requestData, enum RequestReturnCode PerformVendorRequest(std::string vendorName, std::string requestName, obs_data_t *requestData,
obs_data_t *responseData); obs_data_t *responseData);
// Callback for when a vendor emits an event
typedef std::function<void(std::string, std::string, obs_data_t *)> VendorEventCallback;
inline void SetVendorEventCallback(VendorEventCallback cb) { _vendorEventCallback = cb; }
private:
inline int64_t GetEventCallbackIndex(obs_websocket_event_callback &cb)
{
for (int64_t i = 0; i < (int64_t)_eventCallbacks.size(); i++) {
auto currentCb = _eventCallbacks[i];
if (currentCb.callback == cb.callback && currentCb.priv_data == cb.priv_data)
return i;
}
return -1;
}
// Proc handlers
static void get_ph_cb(void *priv_data, calldata_t *cd); static void get_ph_cb(void *priv_data, calldata_t *cd);
static void get_api_version(void *, calldata_t *cd); static void get_api_version(void *, calldata_t *cd);
static void call_request(void *, calldata_t *cd); static void call_request(void *, calldata_t *cd);
static void register_event_callback(void *, calldata_t *cd);
static void unregister_event_callback(void *, calldata_t *cd);
static void vendor_register_cb(void *priv_data, calldata_t *cd); static void vendor_register_cb(void *priv_data, calldata_t *cd);
static void vendor_request_register_cb(void *priv_data, calldata_t *cd); static void vendor_request_register_cb(void *priv_data, calldata_t *cd);
static void vendor_request_unregister_cb(void *priv_data, calldata_t *cd); static void vendor_request_unregister_cb(void *priv_data, calldata_t *cd);
static void vendor_event_emit_cb(void *priv_data, calldata_t *cd); static void vendor_event_emit_cb(void *priv_data, calldata_t *cd);
private:
std::shared_mutex _mutex; std::shared_mutex _mutex;
EventCallback _eventCallback;
proc_handler_t *_procHandler; proc_handler_t *_procHandler;
std::map<std::string, Vendor *> _vendors; std::map<std::string, Vendor *> _vendors;
std::vector<obs_websocket_event_callback> _eventCallbacks;
std::atomic<bool> _obsReady = false;
VendorEventCallback _vendorEventCallback;
}; };

View File

@ -20,11 +20,6 @@ with this program. If not, see <https://www.gnu.org/licenses/>
#include "EventHandler.h" #include "EventHandler.h"
EventHandler::EventHandler() EventHandler::EventHandler()
: _obsLoaded(false),
_inputVolumeMetersRef(0),
_inputActiveStateChangedRef(0),
_inputShowStateChangedRef(0),
_sceneItemTransformChangedRef(0)
{ {
blog_debug("[EventHandler::EventHandler] Setting up..."); blog_debug("[EventHandler::EventHandler] Setting up...");
@ -32,10 +27,11 @@ EventHandler::EventHandler()
signal_handler_t *coreSignalHandler = obs_get_signal_handler(); signal_handler_t *coreSignalHandler = obs_get_signal_handler();
if (coreSignalHandler) { if (coreSignalHandler) {
signal_handler_connect(coreSignalHandler, "source_create", SourceCreatedMultiHandler, this); coreSignals.emplace_back(coreSignalHandler, "source_create", SourceCreatedMultiHandler, this);
signal_handler_connect(coreSignalHandler, "source_destroy", SourceDestroyedMultiHandler, this); coreSignals.emplace_back(coreSignalHandler, "source_destroy", SourceDestroyedMultiHandler, this);
signal_handler_connect(coreSignalHandler, "source_remove", SourceRemovedMultiHandler, this); coreSignals.emplace_back(coreSignalHandler, "source_remove", SourceRemovedMultiHandler, this);
signal_handler_connect(coreSignalHandler, "source_rename", SourceRenamedMultiHandler, this); coreSignals.emplace_back(coreSignalHandler, "source_rename", SourceRenamedMultiHandler, this);
coreSignals.emplace_back(coreSignalHandler, "source_update", SourceUpdatedMultiHandler, this);
} else { } else {
blog(LOG_ERROR, "[EventHandler::EventHandler] Unable to get libobs signal handler!"); blog(LOG_ERROR, "[EventHandler::EventHandler] Unable to get libobs signal handler!");
} }
@ -49,36 +45,34 @@ EventHandler::~EventHandler()
obs_frontend_remove_event_callback(OnFrontendEvent, this); obs_frontend_remove_event_callback(OnFrontendEvent, this);
signal_handler_t *coreSignalHandler = obs_get_signal_handler(); coreSignals.clear();
if (coreSignalHandler) {
signal_handler_disconnect(coreSignalHandler, "source_create", SourceCreatedMultiHandler, this); // Revoke callbacks of all inputs and scenes, in case some still have our callbacks attached
signal_handler_disconnect(coreSignalHandler, "source_destroy", SourceDestroyedMultiHandler, this); auto enumInputs = [](void *param, obs_source_t *source) {
signal_handler_disconnect(coreSignalHandler, "source_remove", SourceRemovedMultiHandler, this); auto eventHandler = static_cast<EventHandler *>(param);
signal_handler_disconnect(coreSignalHandler, "source_rename", SourceRenamedMultiHandler, this); eventHandler->DisconnectSourceSignals(source);
} else { return true;
blog(LOG_ERROR, "[EventHandler::~EventHandler] Unable to get libobs signal handler!"); };
} obs_enum_sources(enumInputs, this);
auto enumScenes = [](void *param, obs_source_t *source) {
auto eventHandler = static_cast<EventHandler *>(param);
eventHandler->DisconnectSourceSignals(source);
return true;
};
obs_enum_scenes(enumScenes, this);
blog_debug("[EventHandler::~EventHandler] Finished."); blog_debug("[EventHandler::~EventHandler] Finished.");
} }
void EventHandler::SetBroadcastCallback(EventHandler::BroadcastCallback cb) // Function to increment or decrement refcounts for high volume event subscriptions
{ void EventHandler::ProcessSubscriptionChange(bool type, uint64_t eventSubscriptions)
_broadcastCallback = cb;
}
void EventHandler::SetObsLoadedCallback(EventHandler::ObsLoadedCallback cb)
{
_obsLoadedCallback = cb;
}
// Function to increment refcounts for high volume event subscriptions
void EventHandler::ProcessSubscription(uint64_t eventSubscriptions)
{ {
if (type) {
if ((eventSubscriptions & EventSubscription::InputVolumeMeters) != 0) { if ((eventSubscriptions & EventSubscription::InputVolumeMeters) != 0) {
if (_inputVolumeMetersRef.fetch_add(1) == 0) { if (_inputVolumeMetersRef.fetch_add(1) == 0) {
if (_inputVolumeMetersHandler) if (_inputVolumeMetersHandler)
blog(LOG_WARNING, "[EventHandler::ProcessSubscription] Input volume meter handler already exists!"); blog(LOG_WARNING,
"[EventHandler::ProcessSubscription] Input volume meter handler already exists!");
else else
_inputVolumeMetersHandler = std::make_unique<Utils::Obs::VolumeMeter::Handler>( _inputVolumeMetersHandler = std::make_unique<Utils::Obs::VolumeMeter::Handler>(
std::bind(&EventHandler::HandleInputVolumeMeters, this, std::placeholders::_1)); std::bind(&EventHandler::HandleInputVolumeMeters, this, std::placeholders::_1));
@ -90,11 +84,7 @@ void EventHandler::ProcessSubscription(uint64_t eventSubscriptions)
_inputShowStateChangedRef++; _inputShowStateChangedRef++;
if ((eventSubscriptions & EventSubscription::SceneItemTransformChanged) != 0) if ((eventSubscriptions & EventSubscription::SceneItemTransformChanged) != 0)
_sceneItemTransformChangedRef++; _sceneItemTransformChangedRef++;
} } else {
// Function to decrement refcounts for high volume event subscriptions
void EventHandler::ProcessUnsubscription(uint64_t eventSubscriptions)
{
if ((eventSubscriptions & EventSubscription::InputVolumeMeters) != 0) { if ((eventSubscriptions & EventSubscription::InputVolumeMeters) != 0) {
if (_inputVolumeMetersRef.fetch_sub(1) == 1) if (_inputVolumeMetersRef.fetch_sub(1) == 1)
_inputVolumeMetersHandler.reset(); _inputVolumeMetersHandler.reset();
@ -105,15 +95,16 @@ void EventHandler::ProcessUnsubscription(uint64_t eventSubscriptions)
_inputShowStateChangedRef--; _inputShowStateChangedRef--;
if ((eventSubscriptions & EventSubscription::SceneItemTransformChanged) != 0) if ((eventSubscriptions & EventSubscription::SceneItemTransformChanged) != 0)
_sceneItemTransformChangedRef--; _sceneItemTransformChangedRef--;
}
} }
// Function required in order to use default arguments // Function required in order to use default arguments
void EventHandler::BroadcastEvent(uint64_t requiredIntent, std::string eventType, json eventData, uint8_t rpcVersion) void EventHandler::BroadcastEvent(uint64_t requiredIntent, std::string eventType, json eventData, uint8_t rpcVersion)
{ {
if (!_broadcastCallback) if (!_eventCallback)
return; return;
_broadcastCallback(requiredIntent, eventType, eventData, rpcVersion); _eventCallback(requiredIntent, eventType, eventData, rpcVersion);
} }
// Connect source signals for Inputs, Scenes, and Transitions. Filters are automatically connected. // Connect source signals for Inputs, Scenes, and Transitions. Filters are automatically connected.
@ -261,103 +252,13 @@ void EventHandler::OnFrontendEvent(enum obs_frontend_event event, void *private_
{ {
auto eventHandler = static_cast<EventHandler *>(private_data); auto eventHandler = static_cast<EventHandler *>(private_data);
if (!eventHandler->_obsLoaded.load() && event != OBS_FRONTEND_EVENT_FINISHED_LOADING)
return;
switch (event) { switch (event) {
// General // General
case OBS_FRONTEND_EVENT_FINISHED_LOADING: case OBS_FRONTEND_EVENT_FINISHED_LOADING:
blog_debug( eventHandler->FrontendFinishedLoadingMultiHandler();
"[EventHandler::OnFrontendEvent] 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).
eventHandler->_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<EventHandler *>(param);
eventHandler->ConnectSourceSignals(source);
return true;
};
obs_enum_sources(enumInputs, private_data);
}
// Enumerate scenes and connect each one
{
auto enumScenes = [](void *param, obs_source_t *source) {
auto eventHandler = static_cast<EventHandler *>(param);
eventHandler->ConnectSourceSignals(source);
return true;
};
obs_enum_scenes(enumScenes, private_data);
}
// Enumerate all scene transitions and connect each one
{
obs_frontend_source_list transitions = {};
obs_frontend_get_transitions(&transitions);
for (size_t i = 0; i < transitions.sources.num; i++) {
obs_source_t *transition = transitions.sources.array[i];
eventHandler->ConnectSourceSignals(transition);
}
obs_frontend_source_list_free(&transitions);
}
blog_debug("[EventHandler::OnFrontendEvent] Finished.");
if (eventHandler->_obsLoadedCallback)
eventHandler->_obsLoadedCallback();
break; break;
case OBS_FRONTEND_EVENT_EXIT: case OBS_FRONTEND_EVENT_SCRIPTING_SHUTDOWN:
eventHandler->HandleExitStarted(); eventHandler->FrontendExitMultiHandler();
blog_debug("[EventHandler::OnFrontendEvent] OBS is unloading. Disabling events...");
// Disconnect source signals and disable events when OBS starts unloading (to reduce extra logging).
eventHandler->_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<EventHandler *>(param);
eventHandler->DisconnectSourceSignals(source);
return true;
};
obs_enum_sources(enumInputs, private_data);
}
// Enumerate scenes and disconnect each one
{
auto enumScenes = [](void *param, obs_source_t *source) {
auto eventHandler = static_cast<EventHandler *>(param);
eventHandler->DisconnectSourceSignals(source);
return true;
};
obs_enum_scenes(enumScenes, private_data);
}
// Enumerate all scene transitions and disconnect each one
{
obs_frontend_source_list transitions = {};
obs_frontend_get_transitions(&transitions);
for (size_t i = 0; i < transitions.sources.num; i++) {
obs_source_t *transition = transitions.sources.array[i];
eventHandler->DisconnectSourceSignals(transition);
}
obs_frontend_source_list_free(&transitions);
}
blog_debug("[EventHandler::OnFrontendEvent] Finished.");
break;
case OBS_FRONTEND_EVENT_STUDIO_MODE_ENABLED:
eventHandler->HandleStudioModeStateChanged(true);
break;
case OBS_FRONTEND_EVENT_STUDIO_MODE_DISABLED:
eventHandler->HandleStudioModeStateChanged(false);
break; break;
// Config // Config
@ -370,7 +271,11 @@ void EventHandler::OnFrontendEvent(enum obs_frontend_event event, void *private_
} }
obs_frontend_source_list_free(&transitions); obs_frontend_source_list_free(&transitions);
} }
// Before ready update to allow event to broadcast
eventHandler->HandleCurrentSceneCollectionChanging(); eventHandler->HandleCurrentSceneCollectionChanging();
eventHandler->_obsReady = false;
if (eventHandler->_obsReadyCallback)
eventHandler->_obsReadyCallback(false);
break; break;
case OBS_FRONTEND_EVENT_SCENE_COLLECTION_CHANGED: { case OBS_FRONTEND_EVENT_SCENE_COLLECTION_CHANGED: {
obs_frontend_source_list transitions = {}; obs_frontend_source_list transitions = {};
@ -381,6 +286,9 @@ void EventHandler::OnFrontendEvent(enum obs_frontend_event event, void *private_
} }
obs_frontend_source_list_free(&transitions); obs_frontend_source_list_free(&transitions);
} }
eventHandler->_obsReady = true;
if (eventHandler->_obsReadyCallback)
eventHandler->_obsReadyCallback(true);
eventHandler->HandleCurrentSceneCollectionChanged(); eventHandler->HandleCurrentSceneCollectionChanged();
break; break;
case OBS_FRONTEND_EVENT_SCENE_COLLECTION_LIST_CHANGED: case OBS_FRONTEND_EVENT_SCENE_COLLECTION_LIST_CHANGED:
@ -427,12 +335,31 @@ void EventHandler::OnFrontendEvent(enum obs_frontend_event event, void *private_
// Outputs // Outputs
case OBS_FRONTEND_EVENT_STREAMING_STARTING: case OBS_FRONTEND_EVENT_STREAMING_STARTING:
eventHandler->HandleStreamStateChanged(OBS_WEBSOCKET_OUTPUT_STARTING); eventHandler->HandleStreamStateChanged(OBS_WEBSOCKET_OUTPUT_STARTING);
{
// Connect signals for stream output reconnects (hacky)
OBSOutputAutoRelease streamOutput = obs_frontend_get_streaming_output();
if (streamOutput) {
signal_handler_t *sh = obs_output_get_signal_handler(streamOutput);
signal_handler_connect(sh, "reconnect", StreamOutputReconnectHandler, private_data);
signal_handler_connect(sh, "reconnect_success", StreamOutputReconnectSuccessHandler, private_data);
}
}
break; break;
case OBS_FRONTEND_EVENT_STREAMING_STARTED: case OBS_FRONTEND_EVENT_STREAMING_STARTED:
eventHandler->HandleStreamStateChanged(OBS_WEBSOCKET_OUTPUT_STARTED); eventHandler->HandleStreamStateChanged(OBS_WEBSOCKET_OUTPUT_STARTED);
break; break;
case OBS_FRONTEND_EVENT_STREAMING_STOPPING: case OBS_FRONTEND_EVENT_STREAMING_STOPPING:
eventHandler->HandleStreamStateChanged(OBS_WEBSOCKET_OUTPUT_STOPPING); eventHandler->HandleStreamStateChanged(OBS_WEBSOCKET_OUTPUT_STOPPING);
{
// Disconnect signals for stream output reconnects
OBSOutputAutoRelease streamOutput = obs_frontend_get_streaming_output();
if (streamOutput) {
signal_handler_t *sh = obs_output_get_signal_handler(streamOutput);
signal_handler_disconnect(sh, "reconnect", StreamOutputReconnectHandler, private_data);
signal_handler_disconnect(sh, "reconnect_success", StreamOutputReconnectSuccessHandler,
private_data);
}
}
break; break;
case OBS_FRONTEND_EVENT_STREAMING_STOPPED: case OBS_FRONTEND_EVENT_STREAMING_STOPPED:
eventHandler->HandleStreamStateChanged(OBS_WEBSOCKET_OUTPUT_STOPPED); eventHandler->HandleStreamStateChanged(OBS_WEBSOCKET_OUTPUT_STOPPED);
@ -442,12 +369,21 @@ void EventHandler::OnFrontendEvent(enum obs_frontend_event event, void *private_
break; break;
case OBS_FRONTEND_EVENT_RECORDING_STARTED: case OBS_FRONTEND_EVENT_RECORDING_STARTED:
eventHandler->HandleRecordStateChanged(OBS_WEBSOCKET_OUTPUT_STARTED); eventHandler->HandleRecordStateChanged(OBS_WEBSOCKET_OUTPUT_STARTED);
{
OBSOutputAutoRelease recordOutput = obs_frontend_get_recording_output();
if (recordOutput) {
signal_handler_t *sh = obs_output_get_signal_handler(recordOutput);
eventHandler->recordFileChangedSignal.Connect(sh, "file_changed", HandleRecordFileChanged,
private_data);
}
}
break; break;
case OBS_FRONTEND_EVENT_RECORDING_STOPPING: case OBS_FRONTEND_EVENT_RECORDING_STOPPING:
eventHandler->HandleRecordStateChanged(OBS_WEBSOCKET_OUTPUT_STOPPING); eventHandler->HandleRecordStateChanged(OBS_WEBSOCKET_OUTPUT_STOPPING);
break; break;
case OBS_FRONTEND_EVENT_RECORDING_STOPPED: case OBS_FRONTEND_EVENT_RECORDING_STOPPED:
eventHandler->HandleRecordStateChanged(OBS_WEBSOCKET_OUTPUT_STOPPED); eventHandler->HandleRecordStateChanged(OBS_WEBSOCKET_OUTPUT_STOPPED);
eventHandler->recordFileChangedSignal.Disconnect();
break; break;
case OBS_FRONTEND_EVENT_RECORDING_PAUSED: case OBS_FRONTEND_EVENT_RECORDING_PAUSED:
eventHandler->HandleRecordStateChanged(OBS_WEBSOCKET_OUTPUT_PAUSED); eventHandler->HandleRecordStateChanged(OBS_WEBSOCKET_OUTPUT_PAUSED);
@ -477,20 +413,75 @@ void EventHandler::OnFrontendEvent(enum obs_frontend_event event, void *private_
eventHandler->HandleReplayBufferSaved(); eventHandler->HandleReplayBufferSaved();
break; break;
// Ui
case OBS_FRONTEND_EVENT_STUDIO_MODE_ENABLED:
eventHandler->HandleStudioModeStateChanged(true);
break;
case OBS_FRONTEND_EVENT_STUDIO_MODE_DISABLED:
eventHandler->HandleStudioModeStateChanged(false);
break;
case OBS_FRONTEND_EVENT_SCREENSHOT_TAKEN:
eventHandler->HandleScreenshotSaved();
break;
default: default:
break; break;
} }
} }
void EventHandler::FrontendFinishedLoadingMultiHandler()
{
blog_debug(
"[EventHandler::FrontendFinishedLoadingMultiHandler] OBS has finished loading. Connecting final handlers and enabling events...");
// Enumerate all scene transitions and connect each one
{
obs_frontend_source_list transitions = {};
obs_frontend_get_transitions(&transitions);
for (size_t i = 0; i < transitions.sources.num; i++) {
obs_source_t *transition = transitions.sources.array[i];
ConnectSourceSignals(transition);
}
obs_frontend_source_list_free(&transitions);
}
_obsReady = true;
if (_obsReadyCallback)
_obsReadyCallback(true);
blog_debug("[EventHandler::FrontendFinishedLoadingMultiHandler] Finished.");
}
void EventHandler::FrontendExitMultiHandler()
{
blog_debug("[EventHandler::FrontendExitMultiHandler] OBS is unloading. Disabling events...");
HandleExitStarted();
// 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
{
obs_frontend_source_list transitions = {};
obs_frontend_get_transitions(&transitions);
for (size_t i = 0; i < transitions.sources.num; i++) {
obs_source_t *transition = transitions.sources.array[i];
DisconnectSourceSignals(transition);
}
obs_frontend_source_list_free(&transitions);
}
blog_debug("[EventHandler::FrontendExitMultiHandler] Finished.");
}
// Only called for creation of a public source // Only called for creation of a public source
void EventHandler::SourceCreatedMultiHandler(void *param, calldata_t *data) void EventHandler::SourceCreatedMultiHandler(void *param, calldata_t *data)
{ {
auto eventHandler = static_cast<EventHandler *>(param); auto eventHandler = static_cast<EventHandler *>(param);
// Don't react to signals until OBS has finished loading
if (!eventHandler->_obsLoaded.load())
return;
obs_source_t *source = GetCalldataPointer<obs_source_t>(data, "source"); obs_source_t *source = GetCalldataPointer<obs_source_t>(data, "source");
if (!source) if (!source)
return; return;
@ -523,10 +514,6 @@ void EventHandler::SourceDestroyedMultiHandler(void *param, calldata_t *data)
// Disconnect all signals from the source // Disconnect all signals from the source
eventHandler->DisconnectSourceSignals(source); eventHandler->DisconnectSourceSignals(source);
// Don't react to signals if OBS is unloading
if (!eventHandler->_obsLoaded.load())
return;
switch (obs_source_get_type(source)) { switch (obs_source_get_type(source)) {
case OBS_SOURCE_TYPE_INPUT: 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. // Only emit removed if the input has not already been removed. This is the case when removing the last scene item of an input.
@ -549,9 +536,6 @@ void EventHandler::SourceRemovedMultiHandler(void *param, calldata_t *data)
{ {
auto eventHandler = static_cast<EventHandler *>(param); auto eventHandler = static_cast<EventHandler *>(param);
if (!eventHandler->_obsLoaded.load())
return;
obs_source_t *source = GetCalldataPointer<obs_source_t>(data, "source"); obs_source_t *source = GetCalldataPointer<obs_source_t>(data, "source");
if (!source) if (!source)
return; return;
@ -572,9 +556,6 @@ void EventHandler::SourceRenamedMultiHandler(void *param, calldata_t *data)
{ {
auto eventHandler = static_cast<EventHandler *>(param); auto eventHandler = static_cast<EventHandler *>(param);
if (!eventHandler->_obsLoaded.load())
return;
obs_source_t *source = GetCalldataPointer<obs_source_t>(data, "source"); obs_source_t *source = GetCalldataPointer<obs_source_t>(data, "source");
if (!source) if (!source)
return; return;
@ -597,3 +578,37 @@ void EventHandler::SourceRenamedMultiHandler(void *param, calldata_t *data)
break; break;
} }
} }
void EventHandler::SourceUpdatedMultiHandler(void *param, calldata_t *data)
{
auto eventHandler = static_cast<EventHandler *>(param);
obs_source_t *source = GetCalldataPointer<obs_source_t>(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<EventHandler *>(param);
eventHandler->HandleStreamStateChanged(OBS_WEBSOCKET_OUTPUT_RECONNECTING);
}
void EventHandler::StreamOutputReconnectSuccessHandler(void *param, calldata_t *)
{
auto eventHandler = static_cast<EventHandler *>(param);
eventHandler->HandleStreamStateChanged(OBS_WEBSOCKET_OUTPUT_RECONNECTED);
}

View File

@ -27,32 +27,38 @@ with this program. If not, see <https://www.gnu.org/licenses/>
#include "../obs-websocket.h" #include "../obs-websocket.h"
#include "../utils/Obs.h" #include "../utils/Obs.h"
#include "../utils/Obs_VolumeMeter.h" #include "../utils/Obs_VolumeMeter.h"
#include "../plugin-macros.generated.h" #include "plugin-macros.generated.h"
class EventHandler { class EventHandler {
public: public:
EventHandler(); EventHandler();
~EventHandler(); ~EventHandler();
typedef std::function<void(uint64_t, std::string, json, uint8_t)> BroadcastCallback; void ProcessSubscriptionChange(bool type, uint64_t eventSubscriptions);
void SetBroadcastCallback(BroadcastCallback cb);
typedef std::function<void()> ObsLoadedCallback;
void SetObsLoadedCallback(ObsLoadedCallback cb);
void ProcessSubscription(uint64_t eventSubscriptions); // Callback when an event fires
void ProcessUnsubscription(uint64_t eventSubscriptions); typedef std::function<void(uint64_t, std::string, json, uint8_t)>
EventCallback; // uint64_t requiredIntent, std::string eventType, json eventData, uint8_t rpcVersion
inline void SetEventCallback(EventCallback cb) { _eventCallback = cb; }
// Callback when OBS becomes ready or non-ready
typedef std::function<void(bool)> ObsReadyCallback; // bool ready
inline void SetObsReadyCallback(ObsReadyCallback cb) { _obsReadyCallback = cb; }
private: private:
BroadcastCallback _broadcastCallback; EventCallback _eventCallback;
ObsLoadedCallback _obsLoadedCallback; ObsReadyCallback _obsReadyCallback;
std::atomic<bool> _obsLoaded; std::atomic<bool> _obsReady = false;
std::vector<OBSSignal> coreSignals;
OBSSignal recordFileChangedSignal;
std::unique_ptr<Utils::Obs::VolumeMeter::Handler> _inputVolumeMetersHandler; std::unique_ptr<Utils::Obs::VolumeMeter::Handler> _inputVolumeMetersHandler;
std::atomic<uint64_t> _inputVolumeMetersRef; std::atomic<uint64_t> _inputVolumeMetersRef = 0;
std::atomic<uint64_t> _inputActiveStateChangedRef; std::atomic<uint64_t> _inputActiveStateChangedRef = 0;
std::atomic<uint64_t> _inputShowStateChangedRef; std::atomic<uint64_t> _inputShowStateChangedRef = 0;
std::atomic<uint64_t> _sceneItemTransformChangedRef; std::atomic<uint64_t> _sceneItemTransformChangedRef = 0;
void ConnectSourceSignals(obs_source_t *source); void ConnectSourceSignals(obs_source_t *source);
void DisconnectSourceSignals(obs_source_t *source); void DisconnectSourceSignals(obs_source_t *source);
@ -61,14 +67,17 @@ private:
// Signal handler: frontend // Signal handler: frontend
static void OnFrontendEvent(enum obs_frontend_event event, void *private_data); static void OnFrontendEvent(enum obs_frontend_event event, void *private_data);
void FrontendFinishedLoadingMultiHandler();
void FrontendExitMultiHandler();
// Signal handler: libobs // Signal handler: libobs
static void SourceCreatedMultiHandler(void *param, calldata_t *data); static void SourceCreatedMultiHandler(void *param, calldata_t *data);
static void SourceDestroyedMultiHandler(void *param, calldata_t *data); static void SourceDestroyedMultiHandler(void *param, calldata_t *data);
static void SourceRemovedMultiHandler(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 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 SourceMediaPauseMultiHandler(void *param, calldata_t *data);
static void SourceMediaPlayMultiHandler(void *param, calldata_t *data); static void SourceMediaPlayMultiHandler(void *param, calldata_t *data);
static void SourceMediaRestartMultiHandler(void *param, calldata_t *data); static void SourceMediaRestartMultiHandler(void *param, calldata_t *data);
@ -76,9 +85,12 @@ private:
static void SourceMediaNextMultiHandler(void *param, calldata_t *data); static void SourceMediaNextMultiHandler(void *param, calldata_t *data);
static void SourceMediaPreviousMultiHandler(void *param, calldata_t *data); static void SourceMediaPreviousMultiHandler(void *param, calldata_t *data);
// Signal handler: output
static void StreamOutputReconnectHandler(void *param, calldata_t *data);
static void StreamOutputReconnectSuccessHandler(void *param, calldata_t *data);
// General // General
void HandleExitStarted(); void HandleExitStarted();
void HandleStudioModeStateChanged(bool enabled);
// Config // Config
void HandleCurrentSceneCollectionChanging(); void HandleCurrentSceneCollectionChanging();
@ -100,7 +112,7 @@ private:
void HandleInputCreated(obs_source_t *source); void HandleInputCreated(obs_source_t *source);
void HandleInputRemoved(obs_source_t *source); void HandleInputRemoved(obs_source_t *source);
void HandleInputNameChanged(obs_source_t *source, std::string oldInputName, std::string inputName); void HandleInputNameChanged(obs_source_t *source, std::string oldInputName, std::string inputName);
void HandleInputVolumeMeters(std::vector<json> inputs); // AudioMeter::Handler callback void HandleInputSettingsChanged(obs_source_t *source);
static void HandleInputActiveStateChanged(void *param, static void HandleInputActiveStateChanged(void *param,
calldata_t *data); // Direct callback calldata_t *data); // Direct callback
static void HandleInputShowStateChanged(void *param, static void HandleInputShowStateChanged(void *param,
@ -117,6 +129,7 @@ private:
calldata_t *data); // Direct callback calldata_t *data); // Direct callback
static void HandleInputAudioMonitorTypeChanged(void *param, static void HandleInputAudioMonitorTypeChanged(void *param,
calldata_t *data); // Direct callback calldata_t *data); // Direct callback
void HandleInputVolumeMeters(std::vector<json> inputs); // AudioMeter::Handler callback
// Transitions // Transitions
void HandleCurrentSceneTransitionChanged(); void HandleCurrentSceneTransitionChanged();
@ -139,11 +152,13 @@ private:
void HandleSourceFilterRemoved(obs_source_t *source, obs_source_t *filter); void HandleSourceFilterRemoved(obs_source_t *source, obs_source_t *filter);
static void HandleSourceFilterNameChanged(void *param, static void HandleSourceFilterNameChanged(void *param,
calldata_t *data); // Direct callback calldata_t *data); // Direct callback
void HandleSourceFilterSettingsChanged(obs_source_t *source);
static void HandleSourceFilterEnableStateChanged(void *param, calldata_t *data); // Direct callback static void HandleSourceFilterEnableStateChanged(void *param, calldata_t *data); // Direct callback
// Outputs // Outputs
void HandleStreamStateChanged(ObsOutputState state); void HandleStreamStateChanged(ObsOutputState state);
void HandleRecordStateChanged(ObsOutputState state); void HandleRecordStateChanged(ObsOutputState state);
static void HandleRecordFileChanged(void *param, calldata_t *data); // Direct callback
void HandleReplayBufferStateChanged(ObsOutputState state); void HandleReplayBufferStateChanged(ObsOutputState state);
void HandleVirtualcamStateChanged(ObsOutputState state); void HandleVirtualcamStateChanged(ObsOutputState state);
void HandleReplayBufferSaved(); void HandleReplayBufferSaved();
@ -170,4 +185,8 @@ private:
static void HandleMediaInputPlaybackEnded(void *param, static void HandleMediaInputPlaybackEnded(void *param,
calldata_t *data); // Direct callback calldata_t *data); // Direct callback
void HandleMediaInputActionTriggered(obs_source_t *source, ObsMediaInputAction action); void HandleMediaInputActionTriggered(obs_source_t *source, ObsMediaInputAction action);
// Ui
void HandleStudioModeStateChanged(bool enabled);
void HandleScreenshotSaved();
}; };

View File

@ -163,6 +163,32 @@ void EventHandler::HandleSourceFilterNameChanged(void *param, calldata_t *data)
eventHandler->BroadcastEvent(EventSubscription::Filters, "SourceFilterNameChanged", eventData); 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. * A source filter's enable state has changed.
* *

View File

@ -23,6 +23,7 @@ with this program. If not, see <https://www.gnu.org/licenses/>
* An input has been created. * An input has been created.
* *
* @dataField inputName | String | Name of the input * @dataField inputName | String | Name of the input
* @dataField inputUuid | String | UUID of the input
* @dataField inputKind | String | The kind of the input * @dataField inputKind | String | The kind of the input
* @dataField unversionedInputKind | String | The unversioned kind of input (aka no `_v2` stuff) * @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 * @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; json eventData;
eventData["inputName"] = obs_source_get_name(source); eventData["inputName"] = obs_source_get_name(source);
eventData["inputUuid"] = obs_source_get_uuid(source);
eventData["inputKind"] = inputKind; eventData["inputKind"] = inputKind;
eventData["unversionedInputKind"] = obs_source_get_unversioned_id(source); eventData["unversionedInputKind"] = obs_source_get_unversioned_id(source);
eventData["inputSettings"] = Utils::Json::ObsDataToJson(inputSettings); eventData["inputSettings"] = Utils::Json::ObsDataToJson(inputSettings);
@ -55,6 +57,7 @@ void EventHandler::HandleInputCreated(obs_source_t *source)
* An input has been removed. * An input has been removed.
* *
* @dataField inputName | String | Name of the input * @dataField inputName | String | Name of the input
* @dataField inputUuid | String | UUID of the input
* *
* @eventType InputRemoved * @eventType InputRemoved
* @eventSubscription Inputs * @eventSubscription Inputs
@ -68,12 +71,14 @@ void EventHandler::HandleInputRemoved(obs_source_t *source)
{ {
json eventData; json eventData;
eventData["inputName"] = obs_source_get_name(source); eventData["inputName"] = obs_source_get_name(source);
eventData["inputUuid"] = obs_source_get_uuid(source);
BroadcastEvent(EventSubscription::Inputs, "InputRemoved", eventData); BroadcastEvent(EventSubscription::Inputs, "InputRemoved", eventData);
} }
/** /**
* The name of an input has changed. * The name of an input has changed.
* *
* @dataField inputUuid | String | UUID of the input
* @dataField oldInputName | String | Old name of the input * @dataField oldInputName | String | Old name of the input
* @dataField inputName | String | New 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 * @api events
* @category inputs * @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; json eventData;
eventData["inputUuid"] = obs_source_get_uuid(source);
eventData["oldInputName"] = oldInputName; eventData["oldInputName"] = oldInputName;
eventData["inputName"] = inputName; eventData["inputName"] = inputName;
BroadcastEvent(EventSubscription::Inputs, "InputNameChanged", eventData); 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. * An input's active state has changed.
* *
* When an input is active, it means it's being shown by the program feed. * When an input is active, it means it's being shown by the program feed.
* *
* @dataField inputName | String | Name of the input * @dataField inputName | String | Name of the input
* @dataField inputUuid | String | UUID of the input
* @dataField videoActive | Boolean | Whether the input is active * @dataField videoActive | Boolean | Whether the input is active
* *
* @eventType InputActiveStateChanged * @eventType InputActiveStateChanged
@ -125,6 +160,7 @@ void EventHandler::HandleInputActiveStateChanged(void *param, calldata_t *data)
json eventData; json eventData;
eventData["inputName"] = obs_source_get_name(source); eventData["inputName"] = obs_source_get_name(source);
eventData["inputUuid"] = obs_source_get_uuid(source);
eventData["videoActive"] = obs_source_active(source); eventData["videoActive"] = obs_source_active(source);
eventHandler->BroadcastEvent(EventSubscription::InputActiveStateChanged, "InputActiveStateChanged", eventData); 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. * 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 inputName | String | Name of the input
* @dataField inputUuid | String | UUID of the input
* @dataField videoShowing | Boolean | Whether the input is showing * @dataField videoShowing | Boolean | Whether the input is showing
* *
* @eventType InputShowStateChanged * @eventType InputShowStateChanged
@ -161,6 +198,7 @@ void EventHandler::HandleInputShowStateChanged(void *param, calldata_t *data)
json eventData; json eventData;
eventData["inputName"] = obs_source_get_name(source); eventData["inputName"] = obs_source_get_name(source);
eventData["inputUuid"] = obs_source_get_uuid(source);
eventData["videoShowing"] = obs_source_showing(source); eventData["videoShowing"] = obs_source_showing(source);
eventHandler->BroadcastEvent(EventSubscription::InputShowStateChanged, "InputShowStateChanged", eventData); 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. * An input's mute state has changed.
* *
* @dataField inputName | String | Name of the input * @dataField inputName | String | Name of the input
* @dataField inputUuid | String | UUID of the input
* @dataField inputMuted | Boolean | Whether the input is muted * @dataField inputMuted | Boolean | Whether the input is muted
* *
* @eventType InputMuteStateChanged * @eventType InputMuteStateChanged
@ -192,6 +231,7 @@ void EventHandler::HandleInputMuteStateChanged(void *param, calldata_t *data)
json eventData; json eventData;
eventData["inputName"] = obs_source_get_name(source); eventData["inputName"] = obs_source_get_name(source);
eventData["inputUuid"] = obs_source_get_uuid(source);
eventData["inputMuted"] = obs_source_muted(source); eventData["inputMuted"] = obs_source_muted(source);
eventHandler->BroadcastEvent(EventSubscription::Inputs, "InputMuteStateChanged", eventData); eventHandler->BroadcastEvent(EventSubscription::Inputs, "InputMuteStateChanged", eventData);
} }
@ -200,7 +240,8 @@ void EventHandler::HandleInputMuteStateChanged(void *param, calldata_t *data)
* An input's volume level has changed. * An input's volume level has changed.
* *
* @dataField inputName | String | Name of the input * @dataField inputName | String | Name of the input
* @dataField inputVolumeMul | Number | New volume level in multimap * @dataField inputUuid | String | UUID of the input
* @dataField inputVolumeMul | Number | New volume level multiplier
* @dataField inputVolumeDb | Number | New volume level in dB * @dataField inputVolumeDb | Number | New volume level in dB
* *
* @eventType InputVolumeChanged * @eventType InputVolumeChanged
@ -231,6 +272,7 @@ void EventHandler::HandleInputVolumeChanged(void *param, calldata_t *data)
json eventData; json eventData;
eventData["inputName"] = obs_source_get_name(source); eventData["inputName"] = obs_source_get_name(source);
eventData["inputUuid"] = obs_source_get_uuid(source);
eventData["inputVolumeMul"] = inputVolumeMul; eventData["inputVolumeMul"] = inputVolumeMul;
eventData["inputVolumeDb"] = inputVolumeDb; eventData["inputVolumeDb"] = inputVolumeDb;
eventHandler->BroadcastEvent(EventSubscription::Inputs, "InputVolumeChanged", eventData); 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. * 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 * @dataField inputAudioBalance | Number | New audio balance value of the input
* *
* @eventType InputAudioBalanceChanged * @eventType InputAudioBalanceChanged
@ -265,6 +308,7 @@ void EventHandler::HandleInputAudioBalanceChanged(void *param, calldata_t *data)
json eventData; json eventData;
eventData["inputName"] = obs_source_get_name(source); eventData["inputName"] = obs_source_get_name(source);
eventData["inputUuid"] = obs_source_get_uuid(source);
eventData["inputAudioBalance"] = inputAudioBalance; eventData["inputAudioBalance"] = inputAudioBalance;
eventHandler->BroadcastEvent(EventSubscription::Inputs, "InputAudioBalanceChanged", eventData); 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. * The sync offset of an input has changed.
* *
* @dataField inputName | String | Name of the input * @dataField inputName | String | Name of the input
* @dataField inputUuid | String | UUID of the input
* @dataField inputAudioSyncOffset | Number | New sync offset in milliseconds * @dataField inputAudioSyncOffset | Number | New sync offset in milliseconds
* *
* @eventType InputAudioSyncOffsetChanged * @eventType InputAudioSyncOffsetChanged
@ -298,6 +343,7 @@ void EventHandler::HandleInputAudioSyncOffsetChanged(void *param, calldata_t *da
json eventData; json eventData;
eventData["inputName"] = obs_source_get_name(source); eventData["inputName"] = obs_source_get_name(source);
eventData["inputUuid"] = obs_source_get_uuid(source);
eventData["inputAudioSyncOffset"] = inputAudioSyncOffset / 1000000; eventData["inputAudioSyncOffset"] = inputAudioSyncOffset / 1000000;
eventHandler->BroadcastEvent(EventSubscription::Inputs, "InputAudioSyncOffsetChanged", eventData); 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. * The audio tracks of an input have changed.
* *
* @dataField inputName | String | Name of the input * @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 * @dataField inputAudioTracks | Object | Object of audio tracks along with their associated enable states
* *
* @eventType InputAudioTracksChanged * @eventType InputAudioTracksChanged
@ -336,6 +383,7 @@ void EventHandler::HandleInputAudioTracksChanged(void *param, calldata_t *data)
json eventData; json eventData;
eventData["inputName"] = obs_source_get_name(source); eventData["inputName"] = obs_source_get_name(source);
eventData["inputUuid"] = obs_source_get_uuid(source);
eventData["inputAudioTracks"] = inputAudioTracks; eventData["inputAudioTracks"] = inputAudioTracks;
eventHandler->BroadcastEvent(EventSubscription::Inputs, "InputAudioTracksChanged", eventData); eventHandler->BroadcastEvent(EventSubscription::Inputs, "InputAudioTracksChanged", eventData);
} }
@ -350,6 +398,7 @@ void EventHandler::HandleInputAudioTracksChanged(void *param, calldata_t *data)
* - `OBS_MONITORING_TYPE_MONITOR_AND_OUTPUT` * - `OBS_MONITORING_TYPE_MONITOR_AND_OUTPUT`
* *
* @dataField inputName | String | Name of the input * @dataField inputName | String | Name of the input
* @dataField inputUuid | String | UUID of the input
* @dataField monitorType | String | New monitor type of the input * @dataField monitorType | String | New monitor type of the input
* *
* @eventType InputAudioMonitorTypeChanged * @eventType InputAudioMonitorTypeChanged
@ -375,6 +424,7 @@ void EventHandler::HandleInputAudioMonitorTypeChanged(void *param, calldata_t *d
json eventData; json eventData;
eventData["inputName"] = obs_source_get_name(source); eventData["inputName"] = obs_source_get_name(source);
eventData["inputUuid"] = obs_source_get_uuid(source);
eventData["monitorType"] = monitorType; eventData["monitorType"] = monitorType;
eventHandler->BroadcastEvent(EventSubscription::Inputs, "InputAudioMonitorTypeChanged", eventData); eventHandler->BroadcastEvent(EventSubscription::Inputs, "InputAudioMonitorTypeChanged", eventData);
} }

View File

@ -124,6 +124,7 @@ void EventHandler::SourceMediaPreviousMultiHandler(void *param, calldata_t *data
* A media input has started playing. * A media input has started playing.
* *
* @dataField inputName | String | Name of the input * @dataField inputName | String | Name of the input
* @dataField inputUuid | String | UUID of the input
* *
* @eventType MediaInputPlaybackStarted * @eventType MediaInputPlaybackStarted
* @eventSubscription MediaInputs * @eventSubscription MediaInputs
@ -146,6 +147,7 @@ void EventHandler::HandleMediaInputPlaybackStarted(void *param, calldata_t *data
json eventData; json eventData;
eventData["inputName"] = obs_source_get_name(source); eventData["inputName"] = obs_source_get_name(source);
eventData["inputUuid"] = obs_source_get_uuid(source);
eventHandler->BroadcastEvent(EventSubscription::MediaInputs, "MediaInputPlaybackStarted", eventData); eventHandler->BroadcastEvent(EventSubscription::MediaInputs, "MediaInputPlaybackStarted", eventData);
} }
@ -153,6 +155,7 @@ void EventHandler::HandleMediaInputPlaybackStarted(void *param, calldata_t *data
* A media input has finished playing. * A media input has finished playing.
* *
* @dataField inputName | String | Name of the input * @dataField inputName | String | Name of the input
* @dataField inputUuid | String | UUID of the input
* *
* @eventType MediaInputPlaybackEnded * @eventType MediaInputPlaybackEnded
* @eventSubscription MediaInputs * @eventSubscription MediaInputs
@ -175,6 +178,7 @@ void EventHandler::HandleMediaInputPlaybackEnded(void *param, calldata_t *data)
json eventData; json eventData;
eventData["inputName"] = obs_source_get_name(source); eventData["inputName"] = obs_source_get_name(source);
eventData["inputUuid"] = obs_source_get_uuid(source);
eventHandler->BroadcastEvent(EventSubscription::MediaInputs, "MediaInputPlaybackEnded", eventData); 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. * An action has been performed on an input.
* *
* @dataField inputName | String | Name of the 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 * @dataField mediaAction | String | Action performed on the input. See `ObsMediaInputAction` enum
* *
* @eventType MediaInputActionTriggered * @eventType MediaInputActionTriggered
@ -196,6 +201,7 @@ void EventHandler::HandleMediaInputActionTriggered(obs_source_t *source, ObsMedi
{ {
json eventData; json eventData;
eventData["inputName"] = obs_source_get_name(source); eventData["inputName"] = obs_source_get_name(source);
eventData["inputUuid"] = obs_source_get_uuid(source);
eventData["mediaAction"] = GetMediaInputActionString(action); eventData["mediaAction"] = GetMediaInputActionString(action);
BroadcastEvent(EventSubscription::MediaInputs, "MediaInputActionTriggered", eventData); BroadcastEvent(EventSubscription::MediaInputs, "MediaInputActionTriggered", eventData);
} }

View File

@ -24,10 +24,12 @@ static bool GetOutputStateActive(ObsOutputState state)
switch (state) { switch (state) {
case OBS_WEBSOCKET_OUTPUT_STARTED: case OBS_WEBSOCKET_OUTPUT_STARTED:
case OBS_WEBSOCKET_OUTPUT_RESUMED: case OBS_WEBSOCKET_OUTPUT_RESUMED:
case OBS_WEBSOCKET_OUTPUT_RECONNECTED:
return true; return true;
case OBS_WEBSOCKET_OUTPUT_STARTING: case OBS_WEBSOCKET_OUTPUT_STARTING:
case OBS_WEBSOCKET_OUTPUT_STOPPING: case OBS_WEBSOCKET_OUTPUT_STOPPING:
case OBS_WEBSOCKET_OUTPUT_STOPPED: case OBS_WEBSOCKET_OUTPUT_STOPPED:
case OBS_WEBSOCKET_OUTPUT_RECONNECTING:
case OBS_WEBSOCKET_OUTPUT_PAUSED: case OBS_WEBSOCKET_OUTPUT_PAUSED:
return false; return false;
default: default:
@ -85,6 +87,28 @@ void EventHandler::HandleRecordStateChanged(ObsOutputState state)
BroadcastEvent(EventSubscription::Outputs, "RecordStateChanged", eventData); BroadcastEvent(EventSubscription::Outputs, "RecordStateChanged", eventData);
} }
/**
* The record output has started writing to a new file. For example, when a file split happens.
*
* @dataField newOutputPath | String | File name that the output has begun writing to
*
* @eventType RecordFileChanged
* @eventSubscription Outputs
* @complexity 2
* @rpcVersion -1
* @initialVersion 5.5.0
* @api events
* @category outputs
*/
void EventHandler::HandleRecordFileChanged(void *param, calldata_t *data)
{
auto eventHandler = static_cast<EventHandler *>(param);
json eventData;
eventData["newOutputPath"] = calldata_string(data, "next_file");
eventHandler->BroadcastEvent(EventSubscription::Outputs, "RecordFileChanged", eventData);
}
/** /**
* The state of the replay buffer output has changed. * The state of the replay buffer output has changed.
* *

View File

@ -23,7 +23,9 @@ with this program. If not, see <https://www.gnu.org/licenses/>
* A scene item has been created. * A scene item has been created.
* *
* @dataField sceneName | String | Name of the scene the item was added to * @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 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 sceneItemId | Number | Numeric ID of the scene item
* @dataField sceneItemIndex | Number | Index position of the item * @dataField sceneItemIndex | Number | Index position of the item
* *
@ -49,7 +51,9 @@ void EventHandler::HandleSceneItemCreated(void *param, calldata_t *data)
json eventData; json eventData;
eventData["sceneName"] = obs_source_get_name(obs_scene_get_source(scene)); 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["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["sceneItemId"] = obs_sceneitem_get_id(sceneItem);
eventData["sceneItemIndex"] = obs_sceneitem_get_order_position(sceneItem); eventData["sceneItemIndex"] = obs_sceneitem_get_order_position(sceneItem);
eventHandler->BroadcastEvent(EventSubscription::SceneItems, "SceneItemCreated", eventData); 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. * 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 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 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 sceneItemId | Number | Numeric ID of the scene item
* *
* @eventType SceneItemRemoved * @eventType SceneItemRemoved
@ -86,7 +92,9 @@ void EventHandler::HandleSceneItemRemoved(void *param, calldata_t *data)
json eventData; json eventData;
eventData["sceneName"] = obs_source_get_name(obs_scene_get_source(scene)); 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["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["sceneItemId"] = obs_sceneitem_get_id(sceneItem);
eventHandler->BroadcastEvent(EventSubscription::SceneItems, "SceneItemRemoved", eventData); 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. * A scene's item list has been reindexed.
* *
* @dataField sceneName | String | Name of the scene * @dataField sceneName | String | Name of the scene
* @dataField sceneUuid | String | UUID of the scene
* @dataField sceneItems | Array<Object> | Array of scene item objects * @dataField sceneItems | Array<Object> | Array of scene item objects
* *
* @eventType SceneItemListReindexed * @eventType SceneItemListReindexed
@ -115,6 +124,7 @@ void EventHandler::HandleSceneItemListReindexed(void *param, calldata_t *data)
json eventData; json eventData;
eventData["sceneName"] = obs_source_get_name(obs_scene_get_source(scene)); 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); eventData["sceneItems"] = Utils::Obs::ArrayHelper::GetSceneItemList(scene, true);
eventHandler->BroadcastEvent(EventSubscription::SceneItems, "SceneItemListReindexed", eventData); 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. * A scene item's enable state has changed.
* *
* @dataField sceneName | String | Name of the scene the item is in * @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 sceneItemId | Number | Numeric ID of the scene item
* @dataField sceneItemEnabled | Boolean | Whether the scene item is enabled (visible) * @dataField sceneItemEnabled | Boolean | Whether the scene item is enabled (visible)
* *
@ -150,6 +161,7 @@ void EventHandler::HandleSceneItemEnableStateChanged(void *param, calldata_t *da
json eventData; json eventData;
eventData["sceneName"] = obs_source_get_name(obs_scene_get_source(scene)); 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["sceneItemId"] = obs_sceneitem_get_id(sceneItem);
eventData["sceneItemEnabled"] = sceneItemEnabled; eventData["sceneItemEnabled"] = sceneItemEnabled;
eventHandler->BroadcastEvent(EventSubscription::SceneItems, "SceneItemEnableStateChanged", eventData); 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. * A scene item's lock state has changed.
* *
* @dataField sceneName | String | Name of the scene the item is in * @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 sceneItemId | Number | Numeric ID of the scene item
* @dataField sceneItemLocked | Boolean | Whether the scene item is locked * @dataField sceneItemLocked | Boolean | Whether the scene item is locked
* *
@ -186,6 +199,7 @@ void EventHandler::HandleSceneItemLockStateChanged(void *param, calldata_t *data
json eventData; json eventData;
eventData["sceneName"] = obs_source_get_name(obs_scene_get_source(scene)); 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["sceneItemId"] = obs_sceneitem_get_id(sceneItem);
eventData["sceneItemLocked"] = sceneItemLocked; eventData["sceneItemLocked"] = sceneItemLocked;
eventHandler->BroadcastEvent(EventSubscription::SceneItems, "SceneItemLockStateChanged", eventData); 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. * A scene item has been selected in the Ui.
* *
* @dataField sceneName | String | Name of the scene the item is in * @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 sceneItemId | Number | Numeric ID of the scene item
* *
* @eventType SceneItemSelected * @eventType SceneItemSelected
@ -219,6 +234,7 @@ void EventHandler::HandleSceneItemSelected(void *param, calldata_t *data)
json eventData; json eventData;
eventData["sceneName"] = obs_source_get_name(obs_scene_get_source(scene)); 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["sceneItemId"] = obs_sceneitem_get_id(sceneItem);
eventHandler->BroadcastEvent(EventSubscription::SceneItems, "SceneItemSelected", eventData); 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. * The transform/crop of a scene item has changed.
* *
* @dataField sceneName | String | The name of the scene the item is in * @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 sceneItemId | Number | Numeric ID of the scene item
* @dataField sceneItemTransform | Object | New transform/crop info 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; json eventData;
eventData["sceneName"] = obs_source_get_name(obs_scene_get_source(scene)); 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["sceneItemId"] = obs_sceneitem_get_id(sceneItem);
eventData["sceneItemTransform"] = Utils::Obs::ObjectHelper::GetSceneItemTransform(sceneItem); eventData["sceneItemTransform"] = Utils::Obs::ObjectHelper::GetSceneItemTransform(sceneItem);
eventHandler->BroadcastEvent(EventSubscription::SceneItemTransformChanged, "SceneItemTransformChanged", eventData); eventHandler->BroadcastEvent(EventSubscription::SceneItemTransformChanged, "SceneItemTransformChanged", eventData);

View File

@ -23,6 +23,7 @@ with this program. If not, see <https://www.gnu.org/licenses/>
* A new scene has been created. * A new scene has been created.
* *
* @dataField sceneName | String | Name of the new scene * @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 * @dataField isGroup | Boolean | Whether the new scene is a group
* *
* @eventType SceneCreated * @eventType SceneCreated
@ -37,6 +38,7 @@ void EventHandler::HandleSceneCreated(obs_source_t *source)
{ {
json eventData; json eventData;
eventData["sceneName"] = obs_source_get_name(source); eventData["sceneName"] = obs_source_get_name(source);
eventData["sceneUuid"] = obs_source_get_uuid(source);
eventData["isGroup"] = obs_source_is_group(source); eventData["isGroup"] = obs_source_is_group(source);
BroadcastEvent(EventSubscription::Scenes, "SceneCreated", eventData); BroadcastEvent(EventSubscription::Scenes, "SceneCreated", eventData);
} }
@ -45,6 +47,7 @@ void EventHandler::HandleSceneCreated(obs_source_t *source)
* A scene has been removed. * A scene has been removed.
* *
* @dataField sceneName | String | Name of the removed scene * @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 * @dataField isGroup | Boolean | Whether the scene was a group
* *
* @eventType SceneRemoved * @eventType SceneRemoved
@ -59,6 +62,7 @@ void EventHandler::HandleSceneRemoved(obs_source_t *source)
{ {
json eventData; json eventData;
eventData["sceneName"] = obs_source_get_name(source); eventData["sceneName"] = obs_source_get_name(source);
eventData["sceneUuid"] = obs_source_get_uuid(source);
eventData["isGroup"] = obs_source_is_group(source); eventData["isGroup"] = obs_source_is_group(source);
BroadcastEvent(EventSubscription::Scenes, "SceneRemoved", eventData); BroadcastEvent(EventSubscription::Scenes, "SceneRemoved", eventData);
} }
@ -66,6 +70,7 @@ void EventHandler::HandleSceneRemoved(obs_source_t *source)
/** /**
* The name of a scene has changed. * The name of a scene has changed.
* *
* @dataField sceneUuid | String | UUID of the scene
* @dataField oldSceneName | String | Old name of the scene * @dataField oldSceneName | String | Old name of the scene
* @dataField sceneName | String | New 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 * @api events
* @category scenes * @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; json eventData;
eventData["sceneUuid"] = obs_source_get_uuid(source);
eventData["oldSceneName"] = oldSceneName; eventData["oldSceneName"] = oldSceneName;
eventData["sceneName"] = sceneName; eventData["sceneName"] = sceneName;
BroadcastEvent(EventSubscription::Scenes, "SceneNameChanged", eventData); BroadcastEvent(EventSubscription::Scenes, "SceneNameChanged", eventData);
@ -89,6 +95,7 @@ void EventHandler::HandleSceneNameChanged(obs_source_t *, std::string oldSceneNa
* The current program scene has changed. * The current program scene has changed.
* *
* @dataField sceneName | String | Name of the scene that was switched to * @dataField sceneName | String | Name of the scene that was switched to
* @dataField sceneUuid | String | UUID of the scene that was switched to
* *
* @eventType CurrentProgramSceneChanged * @eventType CurrentProgramSceneChanged
* @eventSubscription Scenes * @eventSubscription Scenes
@ -104,6 +111,7 @@ void EventHandler::HandleCurrentProgramSceneChanged()
json eventData; json eventData;
eventData["sceneName"] = obs_source_get_name(currentScene); eventData["sceneName"] = obs_source_get_name(currentScene);
eventData["sceneUuid"] = obs_source_get_uuid(currentScene);
BroadcastEvent(EventSubscription::Scenes, "CurrentProgramSceneChanged", eventData); BroadcastEvent(EventSubscription::Scenes, "CurrentProgramSceneChanged", eventData);
} }
@ -111,6 +119,7 @@ void EventHandler::HandleCurrentProgramSceneChanged()
* The current preview scene has changed. * The current preview scene has changed.
* *
* @dataField sceneName | String | Name of the scene that was switched to * @dataField sceneName | String | Name of the scene that was switched to
* @dataField sceneUuid | String | UUID of the scene that was switched to
* *
* @eventType CurrentPreviewSceneChanged * @eventType CurrentPreviewSceneChanged
* @eventSubscription Scenes * @eventSubscription Scenes
@ -130,6 +139,7 @@ void EventHandler::HandleCurrentPreviewSceneChanged()
json eventData; json eventData;
eventData["sceneName"] = obs_source_get_name(currentPreviewScene); eventData["sceneName"] = obs_source_get_name(currentPreviewScene);
eventData["sceneUuid"] = obs_source_get_uuid(currentPreviewScene);
BroadcastEvent(EventSubscription::Scenes, "CurrentPreviewSceneChanged", eventData); BroadcastEvent(EventSubscription::Scenes, "CurrentPreviewSceneChanged", eventData);
} }

View File

@ -23,6 +23,7 @@ with this program. If not, see <https://www.gnu.org/licenses/>
* The current scene transition has changed. * The current scene transition has changed.
* *
* @dataField transitionName | String | Name of the new transition * @dataField transitionName | String | Name of the new transition
* @dataField transitionUuid | String | UUID of the new transition
* *
* @eventType CurrentSceneTransitionChanged * @eventType CurrentSceneTransitionChanged
* @eventSubscription Transitions * @eventSubscription Transitions
@ -38,6 +39,7 @@ void EventHandler::HandleCurrentSceneTransitionChanged()
json eventData; json eventData;
eventData["transitionName"] = obs_source_get_name(transition); eventData["transitionName"] = obs_source_get_name(transition);
eventData["transitionUuid"] = obs_source_get_uuid(transition);
BroadcastEvent(EventSubscription::Transitions, "CurrentSceneTransitionChanged", eventData); BroadcastEvent(EventSubscription::Transitions, "CurrentSceneTransitionChanged", eventData);
} }
@ -65,6 +67,7 @@ void EventHandler::HandleCurrentSceneTransitionDurationChanged()
* A scene transition has started. * A scene transition has started.
* *
* @dataField transitionName | String | Scene transition name * @dataField transitionName | String | Scene transition name
* @dataField transitionUuid | String | Scene transition UUID
* *
* @eventType SceneTransitionStarted * @eventType SceneTransitionStarted
* @eventSubscription Transitions * @eventSubscription Transitions
@ -84,6 +87,7 @@ void EventHandler::HandleSceneTransitionStarted(void *param, calldata_t *data)
json eventData; json eventData;
eventData["transitionName"] = obs_source_get_name(source); eventData["transitionName"] = obs_source_get_name(source);
eventData["transitionUuid"] = obs_source_get_uuid(source);
eventHandler->BroadcastEvent(EventSubscription::Transitions, "SceneTransitionStarted", eventData); 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. * Note: Does not appear to trigger when the transition is interrupted by the user.
* *
* @dataField transitionName | String | Scene transition name * @dataField transitionName | String | Scene transition name
* @dataField transitionUuid | String | Scene transition UUID
* *
* @eventType SceneTransitionEnded * @eventType SceneTransitionEnded
* @eventSubscription Transitions * @eventSubscription Transitions
@ -112,6 +117,7 @@ void EventHandler::HandleSceneTransitionEnded(void *param, calldata_t *data)
json eventData; json eventData;
eventData["transitionName"] = obs_source_get_name(source); eventData["transitionName"] = obs_source_get_name(source);
eventData["transitionUuid"] = obs_source_get_uuid(source);
eventHandler->BroadcastEvent(EventSubscription::Transitions, "SceneTransitionEnded", eventData); 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. * Note: Appears to be called by every transition, regardless of relevance.
* *
* @dataField transitionName | String | Scene transition name * @dataField transitionName | String | Scene transition name
* @dataField transitionUuid | String | Scene transition UUID
* *
* @eventType SceneTransitionVideoEnded * @eventType SceneTransitionVideoEnded
* @eventSubscription Transitions * @eventSubscription Transitions
@ -143,5 +150,6 @@ void EventHandler::HandleSceneTransitionVideoEnded(void *param, calldata_t *data
json eventData; json eventData;
eventData["transitionName"] = obs_source_get_name(source); eventData["transitionName"] = obs_source_get_name(source);
eventData["transitionUuid"] = obs_source_get_uuid(source);
eventHandler->BroadcastEvent(EventSubscription::Transitions, "SceneTransitionVideoEnded", eventData); eventHandler->BroadcastEvent(EventSubscription::Transitions, "SceneTransitionVideoEnded", eventData);
} }

View File

@ -38,3 +38,27 @@ void EventHandler::HandleStudioModeStateChanged(bool enabled)
eventData["studioModeEnabled"] = enabled; eventData["studioModeEnabled"] = enabled;
BroadcastEvent(EventSubscription::Ui, "StudioModeStateChanged", eventData); BroadcastEvent(EventSubscription::Ui, "StudioModeStateChanged", eventData);
} }
/**
* A screenshot has been saved.
*
* Note: Triggered for the screenshot feature available in `Settings -> Hotkeys -> Screenshot Output` ONLY.
* Applications using `Get/SaveSourceScreenshot` should implement a `CustomEvent` if this kind of inter-client
* communication is desired.
*
* @dataField savedScreenshotPath | String | Path of the saved image file
*
* @eventType ScreenshotSaved
* @eventSubscription Ui
* @complexity 2
* @rpcVersion -1
* @initialVersion 5.1.0
* @api events
* @category ui
*/
void EventHandler::HandleScreenshotSaved()
{
json eventData;
eventData["savedScreenshotPath"] = Utils::Obs::StringHelper::GetLastScreenshotFileName();
BroadcastEvent(EventSubscription::Ui, "ScreenshotSaved", eventData);
}

View File

@ -21,9 +21,9 @@ with this program. If not, see <https://www.gnu.org/licenses/>
#include <QPainter> #include <QPainter>
#include <QUrl> #include <QUrl>
#include <obs-module.h> #include <obs-module.h>
#include <qrcodegen.hpp>
#include "ConnectInfo.h" #include "ConnectInfo.h"
#include "../../deps/qr/cpp/QrCode.hpp"
#include "../obs-websocket.h" #include "../obs-websocket.h"
#include "../Config.h" #include "../Config.h"
#include "../utils/Platform.h" #include "../utils/Platform.h"
@ -64,7 +64,7 @@ void ConnectInfo::RefreshData()
QString serverPassword; QString serverPassword;
if (conf->AuthRequired) { if (conf->AuthRequired) {
ui->copyServerPasswordButton->setEnabled(true); ui->copyServerPasswordButton->setEnabled(true);
serverPassword = QUrl::toPercentEncoding(conf->ServerPassword); serverPassword = QUrl::toPercentEncoding(QString::fromStdString(conf->ServerPassword));
} else { } else {
ui->copyServerPasswordButton->setEnabled(false); ui->copyServerPasswordButton->setEnabled(false);
serverPassword = obs_module_text("OBSWebSocket.ConnectInfo.ServerPasswordPlaceholderText"); serverPassword = obs_module_text("OBSWebSocket.ConnectInfo.ServerPasswordPlaceholderText");
@ -105,7 +105,7 @@ void ConnectInfo::SetClipboardText(QString text)
void ConnectInfo::DrawQr(QString qrText) void ConnectInfo::DrawQr(QString qrText)
{ {
QPixmap map(230, 230); QPixmap map(236, 236);
map.fill(Qt::white); map.fill(Qt::white);
QPainter painter(&map); QPainter painter(&map);

View File

@ -21,7 +21,7 @@ with this program. If not, see <https://www.gnu.org/licenses/>
#include <QtWidgets/QDialog> #include <QtWidgets/QDialog>
#include "../plugin-macros.generated.h" #include "plugin-macros.generated.h"
#include "ui_ConnectInfo.h" #include "ui_ConnectInfo.h"

View File

@ -7,7 +7,7 @@
<x>0</x> <x>0</x>
<y>0</y> <y>0</y>
<width>451</width> <width>451</width>
<height>412</height> <height>432</height>
</rect> </rect>
</property> </property>
<property name="minimumSize"> <property name="minimumSize">
@ -19,7 +19,7 @@
<property name="maximumSize"> <property name="maximumSize">
<size> <size>
<width>451</width> <width>451</width>
<height>412</height> <height>432</height>
</size> </size>
</property> </property>
<property name="windowTitle"> <property name="windowTitle">
@ -31,12 +31,21 @@
<x>10</x> <x>10</x>
<y>10</y> <y>10</y>
<width>431</width> <width>431</width>
<height>101</height> <height>121</height>
</rect> </rect>
</property> </property>
<layout class="QFormLayout" name="formLayout"> <layout class="QFormLayout" name="formLayout">
<property name="formAlignment">
<set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter</set>
</property>
<item row="0" column="0"> <item row="0" column="0">
<widget class="QLabel" name="serverIpLabel"> <widget class="QLabel" name="serverIpLabel">
<property name="maximumSize">
<size>
<width>200</width>
<height>16777215</height>
</size>
</property>
<property name="text"> <property name="text">
<string>OBSWebSocket.ConnectInfo.ServerIp</string> <string>OBSWebSocket.ConnectInfo.ServerIp</string>
</property> </property>
@ -46,6 +55,12 @@
<layout class="QHBoxLayout" name="horizontalLayout"> <layout class="QHBoxLayout" name="horizontalLayout">
<item> <item>
<widget class="QLineEdit" name="serverIpLineEdit"> <widget class="QLineEdit" name="serverIpLineEdit">
<property name="focusPolicy">
<enum>Qt::NoFocus</enum>
</property>
<property name="alignment">
<set>Qt::AlignBottom|Qt::AlignLeading|Qt::AlignLeft</set>
</property>
<property name="readOnly"> <property name="readOnly">
<bool>true</bool> <bool>true</bool>
</property> </property>
@ -53,6 +68,12 @@
</item> </item>
<item> <item>
<widget class="QPushButton" name="copyServerIpButton"> <widget class="QPushButton" name="copyServerIpButton">
<property name="maximumSize">
<size>
<width>75</width>
<height>16777215</height>
</size>
</property>
<property name="text"> <property name="text">
<string>OBSWebSocket.ConnectInfo.CopyText</string> <string>OBSWebSocket.ConnectInfo.CopyText</string>
</property> </property>
@ -62,6 +83,12 @@
</item> </item>
<item row="1" column="0"> <item row="1" column="0">
<widget class="QLabel" name="serverPortLabel"> <widget class="QLabel" name="serverPortLabel">
<property name="maximumSize">
<size>
<width>200</width>
<height>16777215</height>
</size>
</property>
<property name="text"> <property name="text">
<string>OBSWebSocket.ConnectInfo.ServerPort</string> <string>OBSWebSocket.ConnectInfo.ServerPort</string>
</property> </property>
@ -71,6 +98,12 @@
<layout class="QHBoxLayout" name="horizontalLayout_2"> <layout class="QHBoxLayout" name="horizontalLayout_2">
<item> <item>
<widget class="QLineEdit" name="serverPortLineEdit"> <widget class="QLineEdit" name="serverPortLineEdit">
<property name="focusPolicy">
<enum>Qt::NoFocus</enum>
</property>
<property name="alignment">
<set>Qt::AlignBottom|Qt::AlignLeading|Qt::AlignLeft</set>
</property>
<property name="readOnly"> <property name="readOnly">
<bool>true</bool> <bool>true</bool>
</property> </property>
@ -78,6 +111,12 @@
</item> </item>
<item> <item>
<widget class="QPushButton" name="copyServerPortButton"> <widget class="QPushButton" name="copyServerPortButton">
<property name="maximumSize">
<size>
<width>75</width>
<height>16777215</height>
</size>
</property>
<property name="text"> <property name="text">
<string>OBSWebSocket.ConnectInfo.CopyText</string> <string>OBSWebSocket.ConnectInfo.CopyText</string>
</property> </property>
@ -87,6 +126,12 @@
</item> </item>
<item row="2" column="0"> <item row="2" column="0">
<widget class="QLabel" name="serverPasswordLabel"> <widget class="QLabel" name="serverPasswordLabel">
<property name="maximumSize">
<size>
<width>200</width>
<height>16777215</height>
</size>
</property>
<property name="text"> <property name="text">
<string>OBSWebSocket.ConnectInfo.ServerPassword</string> <string>OBSWebSocket.ConnectInfo.ServerPassword</string>
</property> </property>
@ -96,9 +141,15 @@
<layout class="QHBoxLayout" name="horizontalLayout_3"> <layout class="QHBoxLayout" name="horizontalLayout_3">
<item> <item>
<widget class="QLineEdit" name="serverPasswordLineEdit"> <widget class="QLineEdit" name="serverPasswordLineEdit">
<property name="focusPolicy">
<enum>Qt::NoFocus</enum>
</property>
<property name="text"> <property name="text">
<string>OBSWebSocket.ConnectInfo.ServerPasswordPlaceholderText</string> <string>OBSWebSocket.ConnectInfo.ServerPasswordPlaceholderText</string>
</property> </property>
<property name="alignment">
<set>Qt::AlignBottom|Qt::AlignLeading|Qt::AlignLeft</set>
</property>
<property name="readOnly"> <property name="readOnly">
<bool>true</bool> <bool>true</bool>
</property> </property>
@ -106,6 +157,12 @@
</item> </item>
<item> <item>
<widget class="QPushButton" name="copyServerPasswordButton"> <widget class="QPushButton" name="copyServerPasswordButton">
<property name="maximumSize">
<size>
<width>75</width>
<height>16777215</height>
</size>
</property>
<property name="text"> <property name="text">
<string>OBSWebSocket.ConnectInfo.CopyText</string> <string>OBSWebSocket.ConnectInfo.CopyText</string>
</property> </property>
@ -119,7 +176,7 @@
<property name="geometry"> <property name="geometry">
<rect> <rect>
<x>10</x> <x>10</x>
<y>120</y> <y>140</y>
<width>431</width> <width>431</width>
<height>281</height> <height>281</height>
</rect> </rect>
@ -131,9 +188,9 @@
<property name="geometry"> <property name="geometry">
<rect> <rect>
<x>100</x> <x>100</x>
<y>40</y> <y>30</y>
<width>230</width> <width>236</width>
<height>230</height> <height>236</height>
</rect> </rect>
</property> </property>
<property name="text"> <property name="text">

View File

@ -123,7 +123,7 @@ void SettingsDialog::RefreshData()
ui->enableDebugLoggingCheckBox->setChecked(conf->DebugEnabled); ui->enableDebugLoggingCheckBox->setChecked(conf->DebugEnabled);
ui->serverPortSpinBox->setValue(conf->ServerPort); ui->serverPortSpinBox->setValue(conf->ServerPort);
ui->enableAuthenticationCheckBox->setChecked(conf->AuthRequired); ui->enableAuthenticationCheckBox->setChecked(conf->AuthRequired);
ui->serverPasswordLineEdit->setText(conf->ServerPassword); ui->serverPasswordLineEdit->setText(QString::fromStdString(conf->ServerPassword));
ui->serverPasswordLineEdit->setEnabled(conf->AuthRequired); ui->serverPasswordLineEdit->setEnabled(conf->AuthRequired);
ui->generatePasswordButton->setEnabled(conf->AuthRequired); ui->generatePasswordButton->setEnabled(conf->AuthRequired);
@ -158,7 +158,7 @@ void SettingsDialog::SaveFormData()
} }
// Show a confirmation box to the user if they attempt to provide their own password // Show a confirmation box to the user if they attempt to provide their own password
if (passwordManuallyEdited && (conf->ServerPassword != ui->serverPasswordLineEdit->text())) { if (passwordManuallyEdited && (conf->ServerPassword != ui->serverPasswordLineEdit->text().toStdString())) {
QMessageBox msgBox; QMessageBox msgBox;
msgBox.setWindowTitle(obs_module_text("OBSWebSocket.Settings.Save.UserPasswordWarningTitle")); msgBox.setWindowTitle(obs_module_text("OBSWebSocket.Settings.Save.UserPasswordWarningTitle"));
msgBox.setText(obs_module_text("OBSWebSocket.Settings.Save.UserPasswordWarningMessage")); msgBox.setText(obs_module_text("OBSWebSocket.Settings.Save.UserPasswordWarningMessage"));
@ -172,22 +172,22 @@ void SettingsDialog::SaveFormData()
break; break;
case QMessageBox::No: case QMessageBox::No:
default: default:
ui->serverPasswordLineEdit->setText(conf->ServerPassword); ui->serverPasswordLineEdit->setText(QString::fromStdString(conf->ServerPassword));
return; return;
} }
} }
bool needsRestart = bool needsRestart = (conf->ServerEnabled != ui->enableWebSocketServerCheckBox->isChecked()) ||
(conf->ServerEnabled != ui->enableWebSocketServerCheckBox->isChecked()) ||
(conf->ServerPort != ui->serverPortSpinBox->value()) || (conf->ServerPort != ui->serverPortSpinBox->value()) ||
(ui->enableAuthenticationCheckBox->isChecked() && conf->ServerPassword != ui->serverPasswordLineEdit->text()); (ui->enableAuthenticationCheckBox->isChecked() &&
conf->ServerPassword != ui->serverPasswordLineEdit->text().toStdString());
conf->ServerEnabled = ui->enableWebSocketServerCheckBox->isChecked(); conf->ServerEnabled = ui->enableWebSocketServerCheckBox->isChecked();
conf->AlertsEnabled = ui->enableSystemTrayAlertsCheckBox->isChecked(); conf->AlertsEnabled = ui->enableSystemTrayAlertsCheckBox->isChecked();
conf->DebugEnabled = ui->enableDebugLoggingCheckBox->isChecked(); conf->DebugEnabled = ui->enableDebugLoggingCheckBox->isChecked();
conf->ServerPort = ui->serverPortSpinBox->value(); conf->ServerPort = ui->serverPortSpinBox->value();
conf->AuthRequired = ui->enableAuthenticationCheckBox->isChecked(); conf->AuthRequired = ui->enableAuthenticationCheckBox->isChecked();
conf->ServerPassword = ui->serverPasswordLineEdit->text(); conf->ServerPassword = ui->serverPasswordLineEdit->text().toStdString();
conf->Save(); conf->Save();

View File

@ -23,7 +23,7 @@ with this program. If not, see <https://www.gnu.org/licenses/>
#include <QTimer> #include <QTimer>
#include "ConnectInfo.h" #include "ConnectInfo.h"
#include "../plugin-macros.generated.h" #include "plugin-macros.generated.h"
#include "ui_SettingsDialog.h" #include "ui_SettingsDialog.h"

View File

@ -80,7 +80,7 @@
<item row="3" column="1"> <item row="3" column="1">
<layout class="QHBoxLayout" name="horizontalLayout_2"> <layout class="QHBoxLayout" name="horizontalLayout_2">
<property name="spacing"> <property name="spacing">
<number>0</number> <number>2</number>
</property> </property>
<item> <item>
<widget class="QCheckBox" name="enableDebugLoggingCheckBox"> <widget class="QCheckBox" name="enableDebugLoggingCheckBox">
@ -97,6 +97,12 @@
<property name="toolTip"> <property name="toolTip">
<string>OBSWebSocket.Settings.DebugEnableHoverText</string> <string>OBSWebSocket.Settings.DebugEnableHoverText</string>
</property> </property>
<property name="scaledContents">
<bool>true</bool>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
</property>
</widget> </widget>
</item> </item>
<item> <item>

View File

@ -48,7 +48,9 @@ WebSocketApiPtr _webSocketApi;
WebSocketServerPtr _webSocketServer; WebSocketServerPtr _webSocketServer;
SettingsDialog *_settingsDialog = nullptr; SettingsDialog *_settingsDialog = nullptr;
void WebSocketApiEventCallback(std::string vendorName, std::string eventType, obs_data_t *obsEventData); void OnWebSocketApiVendorEvent(std::string vendorName, std::string eventType, obs_data_t *obsEventData);
void OnEvent(uint64_t requiredIntent, std::string eventType, json eventData, uint8_t rpcVersion);
void OnObsReady(bool ready);
bool obs_module_load(void) bool obs_module_load(void)
{ {
@ -60,19 +62,30 @@ bool obs_module_load(void)
// Initialize the cpu stats // Initialize the cpu stats
_cpuUsageInfo = os_cpu_usage_info_start(); _cpuUsageInfo = os_cpu_usage_info_start();
// Handle migrations
if (!MigratePersistentData()) {
os_cpu_usage_info_destroy(_cpuUsageInfo);
return false;
}
json migratedConfig = MigrateGlobalConfigData();
// Create the config manager then load the parameters from storage // Create the config manager then load the parameters from storage
_config = ConfigPtr(new Config()); _config = std::make_shared<Config>();
_config->Load(); _config->Load(migratedConfig);
// Initialize the event handler // Initialize the event handler
_eventHandler = EventHandlerPtr(new EventHandler()); _eventHandler = std::make_shared<EventHandler>();
_eventHandler->SetEventCallback(OnEvent);
_eventHandler->SetObsReadyCallback(OnObsReady);
// Initialize the plugin/script API // Initialize the plugin/script API
_webSocketApi = WebSocketApiPtr(new WebSocketApi()); _webSocketApi = std::make_shared<WebSocketApi>();
_webSocketApi->SetEventCallback(WebSocketApiEventCallback); _webSocketApi->SetVendorEventCallback(OnWebSocketApiVendorEvent);
// Initialize the WebSocket server // Initialize the WebSocket server
_webSocketServer = WebSocketServerPtr(new WebSocketServer()); _webSocketServer = std::make_shared<WebSocketServer>();
_webSocketServer->SetClientSubscriptionCallback(std::bind(&EventHandler::ProcessSubscriptionChange, _eventHandler.get(),
std::placeholders::_1, std::placeholders::_2));
// Initialize the settings dialog // Initialize the settings dialog
obs_frontend_push_ui_translation(obs_module_get_string); obs_frontend_push_ui_translation(obs_module_get_string);
@ -89,7 +102,28 @@ bool obs_module_load(void)
return true; return true;
} }
void obs_module_unload() #ifdef PLUGIN_TESTS
void test_call_request();
void test_register_event_callback();
void test_register_vendor();
#endif
void obs_module_post_load(void)
{
#ifdef PLUGIN_TESTS
test_call_request();
test_register_event_callback();
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..."); blog(LOG_INFO, "[obs_module_unload] Shutting down...");
@ -99,18 +133,20 @@ void obs_module_unload()
_webSocketServer->Stop(); _webSocketServer->Stop();
} }
// Destroy the WebSocket server // Release the WebSocket server
_webSocketServer.reset(); _webSocketServer->SetClientSubscriptionCallback(nullptr);
_webSocketServer = nullptr;
// Destroy the plugin/script api // Release the plugin/script api
_webSocketApi.reset(); _webSocketApi = nullptr;
// Destroy the event handler // Release the event handler
_eventHandler.reset(); _eventHandler->SetObsReadyCallback(nullptr);
_eventHandler->SetEventCallback(nullptr);
_eventHandler = nullptr;
// Save and destroy the config manager // Release the config manager
_config->Save(); _config = nullptr;
_config.reset();
// Destroy the cpu stats // Destroy the cpu stats
os_cpu_usage_info_destroy(_cpuUsageInfo); os_cpu_usage_info_destroy(_cpuUsageInfo);
@ -166,7 +202,7 @@ bool IsDebugEnabled()
* @api events * @api events
* @category general * @category general
*/ */
void WebSocketApiEventCallback(std::string vendorName, std::string eventType, obs_data_t *obsEventData) void OnWebSocketApiVendorEvent(std::string vendorName, std::string eventType, obs_data_t *obsEventData)
{ {
json eventData = Utils::Json::ObsDataToJson(obsEventData); json eventData = Utils::Json::ObsDataToJson(obsEventData);
@ -178,13 +214,62 @@ void WebSocketApiEventCallback(std::string vendorName, std::string eventType, ob
_webSocketServer->BroadcastEvent(EventSubscription::Vendors, "VendorEvent", broadcastEventData); _webSocketServer->BroadcastEvent(EventSubscription::Vendors, "VendorEvent", broadcastEventData);
} }
// Sent from: EventHandler
void OnEvent(uint64_t requiredIntent, std::string eventType, json eventData, uint8_t rpcVersion)
{
if (_webSocketServer)
_webSocketServer->BroadcastEvent(requiredIntent, eventType, eventData, rpcVersion);
if (_webSocketApi)
_webSocketApi->BroadcastEvent(requiredIntent, eventType, eventData, rpcVersion);
}
// Sent from: EventHandler
void OnObsReady(bool ready)
{
if (_webSocketServer)
_webSocketServer->SetObsReady(ready);
if (_webSocketApi)
_webSocketApi->SetObsReady(ready);
}
#ifdef PLUGIN_TESTS #ifdef PLUGIN_TESTS
void test_call_request()
{
blog(LOG_INFO, "[test_call_request] Testing obs-websocket plugin API request calling...");
struct obs_websocket_request_response *response = obs_websocket_call_request("GetVersion");
if (response) {
blog(LOG_INFO, "[test_call_request] Called GetVersion. Status Code: %u | Comment: %s | Response Data: %s",
response->status_code, response->comment, response->response_data);
obs_websocket_request_response_free(response);
} else {
blog(LOG_ERROR, "[test_call_request] Failed to call GetVersion request via obs-websocket plugin API!");
}
blog(LOG_INFO, "[test_call_request] Test done.");
}
static void test_event_cb(uint64_t eventIntent, const char *eventType, const char *eventData, void *priv_data)
{
blog(LOG_DEBUG, "[test_event_cb] New event! Type: %s | Data: %s", eventType, eventData);
UNUSED_PARAMETER(eventIntent);
UNUSED_PARAMETER(priv_data);
}
void test_register_event_callback()
{
blog(LOG_INFO, "[test_register_event_callback] Registering test event callback...");
if (!obs_websocket_register_event_callback(test_event_cb, nullptr))
blog(LOG_ERROR, "[test_register_event_callback] Failed to register event callback!");
blog(LOG_INFO, "[test_register_event_callback] Test done.");
}
static void test_vendor_request_cb(obs_data_t *requestData, obs_data_t *responseData, void *priv_data) static void test_vendor_request_cb(obs_data_t *requestData, obs_data_t *responseData, void *priv_data)
{ {
blog(LOG_INFO, "[test_vendor_request_cb] Request called!"); blog(LOG_INFO, "[test_vendor_request_cb] Request called! Request data: %s", obs_data_get_json(requestData));
blog(LOG_INFO, "[test_vendor_request_cb] Request data: %s", obs_data_get_json(requestData));
// Set an item to the response data // Set an item to the response data
obs_data_set_string(responseData, "test", "pp"); obs_data_set_string(responseData, "test", "pp");
@ -193,36 +278,27 @@ static void test_vendor_request_cb(obs_data_t *requestData, obs_data_t *response
obs_websocket_vendor_emit_event(priv_data, "TestEvent", requestData); 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] Testing vendor registration...");
// Test plugin API version fetch // Test plugin API version fetch
uint apiVersion = obs_websocket_get_api_version(); 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",
response->status_code, response->comment, response->response_data);
obs_websocket_request_response_free(response);
}
// Test vendor creation // Test vendor creation
auto vendor = obs_websocket_register_vendor("obs-websocket-test"); auto vendor = obs_websocket_register_vendor("obs-websocket-test");
if (!vendor) { if (!vendor) {
blog(LOG_WARNING, "[obs_module_post_load] Failed to create vendor!"); blog(LOG_ERROR, "[test_register_vendor] Failed to create vendor!");
return; return;
} }
// Test vendor request registration // Test vendor request registration
if (!obs_websocket_vendor_register_request(vendor, "TestRequest", test_vendor_request_cb, vendor)) { 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_ERROR, "[test_register_vendor] Failed to register vendor request!");
return; return;
} }
blog(LOG_INFO, "[obs_module_post_load] Post load completed."); blog(LOG_INFO, "[test_register_vendor] Test done.");
} }
#endif #endif

View File

@ -26,6 +26,8 @@ with this program. If not, see <https://www.gnu.org/licenses/>
#include "utils/Obs.h" #include "utils/Obs.h"
#include "plugin-macros.generated.h" #include "plugin-macros.generated.h"
#define CURRENT_RPC_VERSION 1
struct Config; struct Config;
typedef std::shared_ptr<Config> ConfigPtr; typedef std::shared_ptr<Config> ConfigPtr;

View File

@ -31,17 +31,15 @@ struct SerialFrameBatch {
json &variables; json &variables;
bool haltOnFailure; bool haltOnFailure;
size_t frameCount; size_t frameCount = 0;
size_t sleepUntilFrame; size_t sleepUntilFrame = 0;
std::mutex conditionMutex; std::mutex conditionMutex;
std::condition_variable condition; std::condition_variable condition;
SerialFrameBatch(RequestHandler &requestHandler, json &variables, bool haltOnFailure) SerialFrameBatch(RequestHandler &requestHandler, json &variables, bool haltOnFailure)
: requestHandler(requestHandler), : requestHandler(requestHandler),
variables(variables), variables(variables),
haltOnFailure(haltOnFailure), haltOnFailure(haltOnFailure)
frameCount(0),
sleepUntilFrame(0)
{ {
} }
}; };

View File

@ -51,6 +51,7 @@ const std::unordered_map<std::string, RequestMethodHandler> RequestHandler::_han
{"GetStreamServiceSettings", &RequestHandler::GetStreamServiceSettings}, {"GetStreamServiceSettings", &RequestHandler::GetStreamServiceSettings},
{"SetStreamServiceSettings", &RequestHandler::SetStreamServiceSettings}, {"SetStreamServiceSettings", &RequestHandler::SetStreamServiceSettings},
{"GetRecordDirectory", &RequestHandler::GetRecordDirectory}, {"GetRecordDirectory", &RequestHandler::GetRecordDirectory},
{"SetRecordDirectory", &RequestHandler::SetRecordDirectory},
// Sources // Sources
{"GetSourceActive", &RequestHandler::GetSourceActive}, {"GetSourceActive", &RequestHandler::GetSourceActive},
@ -110,6 +111,7 @@ const std::unordered_map<std::string, RequestMethodHandler> RequestHandler::_han
{"SetTBarPosition", &RequestHandler::SetTBarPosition}, {"SetTBarPosition", &RequestHandler::SetTBarPosition},
// Filters // Filters
{"GetSourceFilterKindList", &RequestHandler::GetSourceFilterKindList},
{"GetSourceFilterList", &RequestHandler::GetSourceFilterList}, {"GetSourceFilterList", &RequestHandler::GetSourceFilterList},
{"GetSourceFilterDefaultSettings", &RequestHandler::GetSourceFilterDefaultSettings}, {"GetSourceFilterDefaultSettings", &RequestHandler::GetSourceFilterDefaultSettings},
{"CreateSourceFilter", &RequestHandler::CreateSourceFilter}, {"CreateSourceFilter", &RequestHandler::CreateSourceFilter},
@ -124,6 +126,7 @@ const std::unordered_map<std::string, RequestMethodHandler> RequestHandler::_han
{"GetSceneItemList", &RequestHandler::GetSceneItemList}, {"GetSceneItemList", &RequestHandler::GetSceneItemList},
{"GetGroupSceneItemList", &RequestHandler::GetGroupSceneItemList}, {"GetGroupSceneItemList", &RequestHandler::GetGroupSceneItemList},
{"GetSceneItemId", &RequestHandler::GetSceneItemId}, {"GetSceneItemId", &RequestHandler::GetSceneItemId},
{"GetSceneItemSource", &RequestHandler::GetSceneItemSource},
{"CreateSceneItem", &RequestHandler::CreateSceneItem}, {"CreateSceneItem", &RequestHandler::CreateSceneItem},
{"RemoveSceneItem", &RequestHandler::RemoveSceneItem}, {"RemoveSceneItem", &RequestHandler::RemoveSceneItem},
{"DuplicateSceneItem", &RequestHandler::DuplicateSceneItem}, {"DuplicateSceneItem", &RequestHandler::DuplicateSceneItem},
@ -174,6 +177,8 @@ const std::unordered_map<std::string, RequestMethodHandler> RequestHandler::_han
{"ToggleRecordPause", &RequestHandler::ToggleRecordPause}, {"ToggleRecordPause", &RequestHandler::ToggleRecordPause},
{"PauseRecord", &RequestHandler::PauseRecord}, {"PauseRecord", &RequestHandler::PauseRecord},
{"ResumeRecord", &RequestHandler::ResumeRecord}, {"ResumeRecord", &RequestHandler::ResumeRecord},
{"SplitRecordFile", &RequestHandler::SplitRecordFile},
{"CreateRecordChapter", &RequestHandler::CreateRecordChapter},
// Media Inputs // Media Inputs
{"GetMediaInputStatus", &RequestHandler::GetMediaInputStatus}, {"GetMediaInputStatus", &RequestHandler::GetMediaInputStatus},
@ -220,9 +225,8 @@ RequestResult RequestHandler::ProcessRequest(const Request &request)
std::vector<std::string> RequestHandler::GetRequestList() std::vector<std::string> RequestHandler::GetRequestList()
{ {
std::vector<std::string> ret; std::vector<std::string> ret;
for (auto const &[key, val] : _handlerMap) { for (auto const &[key, val] : _handlerMap)
ret.push_back(key); ret.push_back(key);
}
return ret; return ret;
} }

View File

@ -30,7 +30,7 @@ with this program. If not, see <https://www.gnu.org/licenses/>
#include "../websocketserver/rpc/WebSocketSession.h" #include "../websocketserver/rpc/WebSocketSession.h"
#include "../obs-websocket.h" #include "../obs-websocket.h"
#include "../utils/Obs.h" #include "../utils/Obs.h"
#include "../plugin-macros.generated.h" #include "plugin-macros.generated.h"
class RequestHandler; class RequestHandler;
typedef RequestResult (RequestHandler::*RequestMethodHandler)(const Request &); typedef RequestResult (RequestHandler::*RequestMethodHandler)(const Request &);
@ -70,6 +70,7 @@ private:
RequestResult GetStreamServiceSettings(const Request &); RequestResult GetStreamServiceSettings(const Request &);
RequestResult SetStreamServiceSettings(const Request &); RequestResult SetStreamServiceSettings(const Request &);
RequestResult GetRecordDirectory(const Request &); RequestResult GetRecordDirectory(const Request &);
RequestResult SetRecordDirectory(const Request &);
// Sources // Sources
RequestResult GetSourceActive(const Request &); RequestResult GetSourceActive(const Request &);
@ -129,6 +130,7 @@ private:
RequestResult SetTBarPosition(const Request &); RequestResult SetTBarPosition(const Request &);
// Filters // Filters
RequestResult GetSourceFilterKindList(const Request &);
RequestResult GetSourceFilterList(const Request &); RequestResult GetSourceFilterList(const Request &);
RequestResult GetSourceFilterDefaultSettings(const Request &); RequestResult GetSourceFilterDefaultSettings(const Request &);
RequestResult CreateSourceFilter(const Request &); RequestResult CreateSourceFilter(const Request &);
@ -143,6 +145,7 @@ private:
RequestResult GetSceneItemList(const Request &); RequestResult GetSceneItemList(const Request &);
RequestResult GetGroupSceneItemList(const Request &); RequestResult GetGroupSceneItemList(const Request &);
RequestResult GetSceneItemId(const Request &); RequestResult GetSceneItemId(const Request &);
RequestResult GetSceneItemSource(const Request &);
RequestResult CreateSceneItem(const Request &); RequestResult CreateSceneItem(const Request &);
RequestResult RemoveSceneItem(const Request &); RequestResult RemoveSceneItem(const Request &);
RequestResult DuplicateSceneItem(const Request &); RequestResult DuplicateSceneItem(const Request &);
@ -193,6 +196,8 @@ private:
RequestResult ToggleRecordPause(const Request &); RequestResult ToggleRecordPause(const Request &);
RequestResult PauseRecord(const Request &); RequestResult PauseRecord(const Request &);
RequestResult ResumeRecord(const Request &); RequestResult ResumeRecord(const Request &);
RequestResult SplitRecordFile(const Request &);
RequestResult CreateRecordChapter(const Request &);
// Media Inputs // Media Inputs
RequestResult GetMediaInputStatus(const Request &); RequestResult GetMediaInputStatus(const Request &);

View File

@ -22,6 +22,8 @@ with this program. If not, see <https://www.gnu.org/licenses/>
#include "RequestHandler.h" #include "RequestHandler.h"
#define GLOBAL_PERSISTENT_DATA_FILE_NAME "persistent_data.json"
/** /**
* Gets the value of a "slot" from the selected persistent data realm. * Gets the value of a "slot" from the selected persistent data realm.
* *
@ -47,11 +49,11 @@ RequestResult RequestHandler::GetPersistentData(const Request &request)
std::string realm = request.RequestData["realm"]; std::string realm = request.RequestData["realm"];
std::string slotName = request.RequestData["slotName"]; std::string slotName = request.RequestData["slotName"];
std::string persistentDataPath = Utils::Obs::StringHelper::GetCurrentProfilePath(); std::string persistentDataPath;
if (realm == "OBS_WEBSOCKET_DATA_REALM_GLOBAL") if (realm == "OBS_WEBSOCKET_DATA_REALM_GLOBAL")
persistentDataPath += "/../../../obsWebSocketPersistentData.json"; persistentDataPath = Utils::Obs::StringHelper::GetModuleConfigPath(GLOBAL_PERSISTENT_DATA_FILE_NAME);
else if (realm == "OBS_WEBSOCKET_DATA_REALM_PROFILE") else if (realm == "OBS_WEBSOCKET_DATA_REALM_PROFILE")
persistentDataPath += "/obsWebSocketPersistentData.json"; persistentDataPath = Utils::Obs::StringHelper::GetCurrentProfilePath() + "/obsWebSocketPersistentData.json";
else else
return RequestResult::Error(RequestStatus::ResourceNotFound, return RequestResult::Error(RequestStatus::ResourceNotFound,
"You have specified an invalid persistent data realm."); "You have specified an invalid persistent data realm.");
@ -92,16 +94,16 @@ RequestResult RequestHandler::SetPersistentData(const Request &request)
std::string slotName = request.RequestData["slotName"]; std::string slotName = request.RequestData["slotName"];
json slotValue = request.RequestData["slotValue"]; json slotValue = request.RequestData["slotValue"];
std::string persistentDataPath = Utils::Obs::StringHelper::GetCurrentProfilePath(); std::string persistentDataPath;
if (realm == "OBS_WEBSOCKET_DATA_REALM_GLOBAL") if (realm == "OBS_WEBSOCKET_DATA_REALM_GLOBAL")
persistentDataPath += "/../../../obsWebSocketPersistentData.json"; persistentDataPath = Utils::Obs::StringHelper::GetModuleConfigPath(GLOBAL_PERSISTENT_DATA_FILE_NAME);
else if (realm == "OBS_WEBSOCKET_DATA_REALM_PROFILE") else if (realm == "OBS_WEBSOCKET_DATA_REALM_PROFILE")
persistentDataPath += "/obsWebSocketPersistentData.json"; persistentDataPath = Utils::Obs::StringHelper::GetCurrentProfilePath() + "/obsWebSocketPersistentData.json";
else else
return RequestResult::Error(RequestStatus::ResourceNotFound, return RequestResult::Error(RequestStatus::ResourceNotFound,
"You have specified an invalid persistent data realm."); "You have specified an invalid persistent data realm.");
json persistentData = json::object(); json persistentData;
Utils::Json::GetJsonFileContent(persistentDataPath, persistentData); Utils::Json::GetJsonFileContent(persistentDataPath, persistentData);
persistentData[slotName] = slotValue; persistentData[slotName] = slotValue;
if (!Utils::Json::SetJsonFileContent(persistentDataPath, persistentData)) if (!Utils::Json::SetJsonFileContent(persistentDataPath, persistentData))
@ -198,10 +200,7 @@ RequestResult RequestHandler::CreateSceneCollection(const Request &request)
if (std::find(sceneCollections.begin(), sceneCollections.end(), sceneCollectionName) != sceneCollections.end()) if (std::find(sceneCollections.begin(), sceneCollections.end(), sceneCollectionName) != sceneCollections.end())
return RequestResult::Error(RequestStatus::ResourceAlreadyExists); return RequestResult::Error(RequestStatus::ResourceAlreadyExists);
QMainWindow *mainWindow = static_cast<QMainWindow *>(obs_frontend_get_main_window()); bool success = obs_frontend_add_scene_collection(sceneCollectionName.c_str());
bool success = false;
QMetaObject::invokeMethod(mainWindow, "AddSceneCollection", Qt::BlockingQueuedConnection, Q_RETURN_ARG(bool, success),
Q_ARG(bool, true), Q_ARG(QString, QString::fromStdString(sceneCollectionName)));
if (!success) if (!success)
return RequestResult::Error(RequestStatus::ResourceCreationFailed, "Failed to create the scene collection."); return RequestResult::Error(RequestStatus::ResourceCreationFailed, "Failed to create the scene collection.");
@ -599,8 +598,8 @@ RequestResult RequestHandler::SetStreamServiceSettings(const Request &request)
obs_service_update(currentStreamService, newStreamServiceSettings); obs_service_update(currentStreamService, newStreamServiceSettings);
} else { } else {
// TODO: This leaks memory. I have no idea why. OBSServiceAutoRelease newStreamService = obs_service_create(requestedStreamServiceType.c_str(),
OBSService newStreamService = obs_service_create(requestedStreamServiceType.c_str(), "obs_websocket_custom_service", "obs_websocket_custom_service",
requestedStreamServiceSettings, nullptr); requestedStreamServiceSettings, nullptr);
// TODO: Check service type here, instead of relying on service creation to fail. // TODO: Check service type here, instead of relying on service creation to fail.
if (!newStreamService) if (!newStreamService)
@ -622,7 +621,7 @@ RequestResult RequestHandler::SetStreamServiceSettings(const Request &request)
* @responseField recordDirectory | String | Output directory * @responseField recordDirectory | String | Output directory
* *
* @requestType GetRecordDirectory * @requestType GetRecordDirectory
* @complexity 1 * @complexity 2
* @rpcVersion -1 * @rpcVersion -1
* @initialVersion 5.0.0 * @initialVersion 5.0.0
* @api requests * @api requests
@ -635,3 +634,35 @@ RequestResult RequestHandler::GetRecordDirectory(const Request &)
return RequestResult::Success(responseData); 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();
}

View File

@ -19,10 +19,32 @@ with this program. If not, see <https://www.gnu.org/licenses/>
#include "RequestHandler.h" #include "RequestHandler.h"
/**
* Gets an array of all available source filter kinds.
*
* Similar to `GetInputKindList`
*
* @responseField sourceFilterKinds | Array<String> | 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. * 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<Object> | Array of filters * @responseField filters | Array<Object> | Array of filters
* *
@ -37,7 +59,7 @@ RequestResult RequestHandler::GetSourceFilterList(const Request &request)
{ {
RequestStatus::RequestStatus statusCode; RequestStatus::RequestStatus statusCode;
std::string comment; std::string comment;
OBSSourceAutoRelease source = request.ValidateSource("sourceName", statusCode, comment); OBSSourceAutoRelease source = request.ValidateSource("sourceName", "sourceUuid", statusCode, comment);
if (!source) if (!source)
return RequestResult::Error(statusCode, comment); 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. * 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 filterName | String | Name of the new filter to be created
* @requestField filterKind | String | The kind of 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 * @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; RequestStatus::RequestStatus statusCode;
std::string comment; 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) && if (!(source && request.ValidateString("filterName", statusCode, comment) &&
request.ValidateString("filterKind", statusCode, comment))) request.ValidateString("filterKind", statusCode, comment)))
return RequestResult::Error(statusCode, comment); return RequestResult::Error(statusCode, comment);
@ -138,7 +161,8 @@ RequestResult RequestHandler::CreateSourceFilter(const Request &request)
/** /**
* Removes a filter from a source. * Removes a filter from 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 to remove * @requestField filterName | String | Name of the filter to remove
* *
* @requestType RemoveSourceFilter * @requestType RemoveSourceFilter
@ -152,7 +176,7 @@ RequestResult RequestHandler::RemoveSourceFilter(const Request &request)
{ {
RequestStatus::RequestStatus statusCode; RequestStatus::RequestStatus statusCode;
std::string comment; std::string comment;
FilterPair pair = request.ValidateFilter("sourceName", "filterName", statusCode, comment); FilterPair pair = request.ValidateFilter(statusCode, comment);
if (!pair.filter) if (!pair.filter)
return RequestResult::Error(statusCode, comment); return RequestResult::Error(statusCode, comment);
@ -164,7 +188,8 @@ RequestResult RequestHandler::RemoveSourceFilter(const Request &request)
/** /**
* Sets the name of a source filter (rename). * 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 filterName | String | Current name of the filter
* @requestField newFilterName | String | New name for the filter * @requestField newFilterName | String | New name for the filter
* *
@ -179,7 +204,7 @@ RequestResult RequestHandler::SetSourceFilterName(const Request &request)
{ {
RequestStatus::RequestStatus statusCode; RequestStatus::RequestStatus statusCode;
std::string comment; 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)) if (!pair.filter || !request.ValidateString("newFilterName", statusCode, comment))
return RequestResult::Error(statusCode, comment); return RequestResult::Error(statusCode, comment);
@ -197,7 +222,8 @@ RequestResult RequestHandler::SetSourceFilterName(const Request &request)
/** /**
* Gets the info for a specific source filter. * Gets the info for a specific source filter.
* *
* @requestField sourceName | String | Name of the source * @requestField ?sourceName | String | Name of the source
* @requestField ?sourceUuid | String | UUID of the source
* @requestField filterName | String | Name of the filter * @requestField filterName | String | Name of the filter
* *
* @responseField filterEnabled | Boolean | Whether the filter is enabled * @responseField filterEnabled | Boolean | Whether the filter is enabled
@ -216,7 +242,7 @@ RequestResult RequestHandler::GetSourceFilter(const Request &request)
{ {
RequestStatus::RequestStatus statusCode; RequestStatus::RequestStatus statusCode;
std::string comment; std::string comment;
FilterPair pair = request.ValidateFilter("sourceName", "filterName", statusCode, comment); FilterPair pair = request.ValidateFilter(statusCode, comment);
if (!pair.filter) if (!pair.filter)
return RequestResult::Error(statusCode, comment); 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. * 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 filterName | String | Name of the filter
* @requestField filterIndex | Number | New index position of the filter | >= 0 * @requestField filterIndex | Number | New index position of the filter | >= 0
* *
@ -251,7 +278,7 @@ RequestResult RequestHandler::SetSourceFilterIndex(const Request &request)
{ {
RequestStatus::RequestStatus statusCode; RequestStatus::RequestStatus statusCode;
std::string comment; 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))) if (!(pair.filter && request.ValidateNumber("filterIndex", statusCode, comment, 0, 8192)))
return RequestResult::Error(statusCode, comment); return RequestResult::Error(statusCode, comment);
@ -265,7 +292,8 @@ RequestResult RequestHandler::SetSourceFilterIndex(const Request &request)
/** /**
* Sets the settings of a source filter. * 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 filterName | String | Name of the filter to set the settings of
* @requestField filterSettings | Object | Object of settings to apply * @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 * @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; RequestStatus::RequestStatus statusCode;
std::string comment; 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))) if (!(pair.filter && request.ValidateObject("filterSettings", statusCode, comment, true)))
return RequestResult::Error(statusCode, comment); return RequestResult::Error(statusCode, comment);
@ -313,7 +341,8 @@ RequestResult RequestHandler::SetSourceFilterSettings(const Request &request)
/** /**
* Sets the enable state of a source filter. * 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 filterName | String | Name of the filter
* @requestField filterEnabled | Boolean | New enable state 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; RequestStatus::RequestStatus statusCode;
std::string comment; 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))) if (!(pair.filter && request.ValidateBoolean("filterEnabled", statusCode, comment)))
return RequestResult::Error(statusCode, comment); return RequestResult::Error(statusCode, comment);

View File

@ -102,6 +102,20 @@ RequestResult RequestHandler::GetStats(const Request &)
return RequestResult::Success(responseData); return RequestResult::Success(responseData);
} }
/**
* Custom event emitted by `BroadcastCustomEvent`.
*
* @dataField eventData | Object | Custom event data
*
* @eventType CustomEvent
* @eventSubscription General
* @complexity 1
* @rpcVersion -1
* @initialVersion 5.0.0
* @category general
* @api events
*/
/** /**
* Broadcasts a `CustomEvent` to all WebSocket clients. Receivers are clients which are identified and subscribed. * Broadcasts a `CustomEvent` to all WebSocket clients. Receivers are clients which are identified and subscribed.
* *
@ -164,7 +178,7 @@ RequestResult RequestHandler::CallVendorRequest(const Request &request)
OBSDataAutoRelease requestData = obs_data_create(); OBSDataAutoRelease requestData = obs_data_create();
if (request.Contains("requestData")) { if (request.Contains("requestData")) {
if (!request.ValidateOptionalObject("requestData", statusCode, comment)) if (!request.ValidateOptionalObject("requestData", statusCode, comment, true))
return RequestResult::Error(statusCode, comment); return RequestResult::Error(statusCode, comment);
requestData = Utils::Json::JsonToObsData(request.RequestData["requestData"]); requestData = Utils::Json::JsonToObsData(request.RequestData["requestData"]);
@ -197,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<String> | Array of hotkey names * @responseField hotkeys | Array<String> | Array of hotkey names
* *
* @requestType GetHotkeyList * @requestType GetHotkeyList
* @complexity 3 * @complexity 4
* @rpcVersion -1 * @rpcVersion -1
* @initialVersion 5.0.0 * @initialVersion 5.0.0
* @category general * @category general
@ -216,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 hotkeyName | String | Name of the hotkey to trigger
* @requestField ?contextName | String | Name of context of the hotkey to trigger
* *
* @requestType TriggerHotkeyByName * @requestType TriggerHotkeyByName
* @complexity 3 * @complexity 4
* @rpcVersion -1 * @rpcVersion -1
* @initialVersion 5.0.0 * @initialVersion 5.0.0
* @category general * @category general
@ -234,11 +253,20 @@ RequestResult RequestHandler::TriggerHotkeyByName(const Request &request)
if (!request.ValidateString("hotkeyName", statusCode, comment)) if (!request.ValidateString("hotkeyName", statusCode, comment))
return RequestResult::Error(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) if (!hotkey)
return RequestResult::Error(RequestStatus::ResourceNotFound, "No hotkeys were found by that name."); return RequestResult::Error(RequestStatus::ResourceNotFound, "No hotkeys were found by that name.");
obs_hotkey_trigger_routed_callback(obs_hotkey_get_id(hotkey), true); obs_hotkey_trigger_routed_callback(obs_hotkey_get_id(hotkey), true);
obs_hotkey_trigger_routed_callback(obs_hotkey_get_id(hotkey), false);
return RequestResult::Success(); return RequestResult::Success();
} }
@ -246,6 +274,8 @@ RequestResult RequestHandler::TriggerHotkeyByName(const Request &request)
/** /**
* Triggers a hotkey using a sequence of keys. * 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 ?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 | Object | Object containing key modifiers to apply | Ignored
* @requestField ?keyModifiers.shift | Boolean | Press Shift | Not pressed * @requestField ?keyModifiers.shift | Boolean | Press Shift | Not pressed
@ -311,8 +341,8 @@ RequestResult RequestHandler::TriggerHotkeyByKeySequence(const Request &request)
/** /**
* Sleeps for a time duration or number of frames. Only available in request batches with types `SERIAL_REALTIME` or `SERIAL_FRAME`. * Sleeps for a time duration or number of frames. Only available in request batches with types `SERIAL_REALTIME` or `SERIAL_FRAME`.
* *
* @requestField sleepMillis | Number | Number of milliseconds to sleep for (if `SERIAL_REALTIME` mode) | >= 0, <= 50000 * @requestField ?sleepMillis | Number | Number of milliseconds to sleep for (if `SERIAL_REALTIME` mode) | >= 0, <= 50000
* @requestField sleepFrames | Number | Number of frames to sleep for (if `SERIAL_FRAME` mode) | >= 0, <= 10000 * @requestField ?sleepFrames | Number | Number of frames to sleep for (if `SERIAL_FRAME` mode) | >= 0, <= 10000
* *
* @requestType Sleep * @requestType Sleep
* @complexity 2 * @complexity 2

Some files were not shown because too many files have changed in this diff Show More