Compare commits

...

16 Commits

Author SHA1 Message Date
896bacf550 requesthandler: Add Compare and Assert
Usable for performing some basic logic functions. Not feature-complete.
2024-01-16 01:24:56 -08: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
23 changed files with 370 additions and 54 deletions

View File

@ -2,7 +2,7 @@ cmake_minimum_required(VERSION 3.16...3.25)
legacy_check() legacy_check()
set(obs-websocket_VERSION 5.3.3) set(obs-websocket_VERSION 5.3.5)
set(OBS_WEBSOCKET_RPC_VERSION 1) set(OBS_WEBSOCKET_RPC_VERSION 1)
option(ENABLE_WEBSOCKET "Enable building OBS with websocket plugin" ON) option(ENABLE_WEBSOCKET "Enable building OBS with websocket plugin" ON)
@ -12,7 +12,7 @@ if(NOT ENABLE_WEBSOCKET)
endif() endif()
# Find Qt # Find Qt
find_qt(COMPONENTS Core Widgets Svg Network) find_package(Qt6 REQUIRED Core Widgets Svg Network)
# Find nlohmann JSON # Find nlohmann JSON
find_package(nlohmann_json 3 REQUIRED) find_package(nlohmann_json 3 REQUIRED)
@ -31,51 +31,53 @@ find_package(Asio 1.12.1 REQUIRED)
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(obs-websocket PRIVATE)
target_sources( target_sources(
obs-websocket obs-websocket
PRIVATE src/obs-websocket.cpp PRIVATE # cmake-format: sortable
src/obs-websocket.h lib/obs-websocket-api.h
src/Config.cpp src/Config.cpp
src/Config.h src/Config.h
lib/obs-websocket-api.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.cpp
src/forms/SettingsDialog.h src/forms/SettingsDialog.h
src/obs-websocket.cpp
src/obs-websocket.h
src/WebSocketApi.cpp src/WebSocketApi.cpp
src/WebSocketApi.h) src/WebSocketApi.h)
target_sources( target_sources(
obs-websocket obs-websocket
PRIVATE src/websocketserver/WebSocketServer.cpp PRIVATE # cmake-format: sortable
src/websocketserver/WebSocketServer_Protocol.cpp
src/websocketserver/WebSocketServer.h
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( target_sources(
obs-websocket obs-websocket
PRIVATE src/eventhandler/EventHandler.cpp PRIVATE # cmake-format: sortable
src/eventhandler/EventHandler.cpp
src/eventhandler/EventHandler.h src/eventhandler/EventHandler.h
src/eventhandler/EventHandler_Config.cpp src/eventhandler/EventHandler_Config.cpp
src/eventhandler/EventHandler_General.cpp
src/eventhandler/EventHandler_Filters.cpp src/eventhandler/EventHandler_Filters.cpp
src/eventhandler/EventHandler_General.cpp
src/eventhandler/EventHandler_Inputs.cpp src/eventhandler/EventHandler_Inputs.cpp
src/eventhandler/EventHandler_MediaInputs.cpp src/eventhandler/EventHandler_MediaInputs.cpp
src/eventhandler/EventHandler_Outputs.cpp src/eventhandler/EventHandler_Outputs.cpp
src/eventhandler/EventHandler_Scenes.cpp
src/eventhandler/EventHandler_SceneItems.cpp src/eventhandler/EventHandler_SceneItems.cpp
src/eventhandler/EventHandler_Scenes.cpp
src/eventhandler/EventHandler_Transitions.cpp src/eventhandler/EventHandler_Transitions.cpp
src/eventhandler/EventHandler_Ui.cpp src/eventhandler/EventHandler_Ui.cpp
src/eventhandler/types/EventSubscription.h) src/eventhandler/types/EventSubscription.h)
target_sources( target_sources(
obs-websocket obs-websocket
PRIVATE src/requesthandler/RequestBatchHandler.cpp PRIVATE # cmake-format: sortable
src/requesthandler/RequestBatchHandler.cpp
src/requesthandler/RequestBatchHandler.h src/requesthandler/RequestBatchHandler.h
src/requesthandler/RequestHandler.cpp src/requesthandler/RequestHandler.cpp
src/requesthandler/RequestHandler.h src/requesthandler/RequestHandler.h
@ -85,10 +87,10 @@ target_sources(
src/requesthandler/RequestHandler_Inputs.cpp src/requesthandler/RequestHandler_Inputs.cpp
src/requesthandler/RequestHandler_MediaInputs.cpp src/requesthandler/RequestHandler_MediaInputs.cpp
src/requesthandler/RequestHandler_Outputs.cpp src/requesthandler/RequestHandler_Outputs.cpp
src/requesthandler/RequestHandler_Sources.cpp
src/requesthandler/RequestHandler_Record.cpp src/requesthandler/RequestHandler_Record.cpp
src/requesthandler/RequestHandler_Scenes.cpp
src/requesthandler/RequestHandler_SceneItems.cpp src/requesthandler/RequestHandler_SceneItems.cpp
src/requesthandler/RequestHandler_Scenes.cpp
src/requesthandler/RequestHandler_Sources.cpp
src/requesthandler/RequestHandler_Stream.cpp src/requesthandler/RequestHandler_Stream.cpp
src/requesthandler/RequestHandler_Transitions.cpp src/requesthandler/RequestHandler_Transitions.cpp
src/requesthandler/RequestHandler_Ui.cpp src/requesthandler/RequestHandler_Ui.cpp
@ -98,12 +100,13 @@ target_sources(
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( target_sources(
obs-websocket obs-websocket
PRIVATE src/utils/Compat.cpp PRIVATE # cmake-format: sortable
src/utils/Compat.cpp
src/utils/Compat.h src/utils/Compat.h
src/utils/Crypto.cpp src/utils/Crypto.cpp
src/utils/Crypto.h src/utils/Crypto.h
@ -115,8 +118,8 @@ target_sources(
src/utils/Obs_ArrayHelper.cpp src/utils/Obs_ArrayHelper.cpp
src/utils/Obs_NumberHelper.cpp src/utils/Obs_NumberHelper.cpp
src/utils/Obs_ObjectHelper.cpp src/utils/Obs_ObjectHelper.cpp
src/utils/Obs_StringHelper.cpp
src/utils/Obs_SearchHelper.cpp src/utils/Obs_SearchHelper.cpp
src/utils/Obs_StringHelper.cpp
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
@ -133,14 +136,19 @@ target_compile_definitions(
target_compile_options( target_compile_options(
obs-websocket obs-websocket
PRIVATE PRIVATE $<$<PLATFORM_ID:Windows>:/wd4267>
$<$<PLATFORM_ID:Windows>:/wd4267> $<$<COMPILE_LANG_AND_ID:CXX,GNU,AppleClang,Clang>:-Wall>
$<$<PLATFORM_ID:Windows>:/wd4996> $<$<COMPILE_LANG_AND_ID:CXX,GNU,AppleClang,Clang>:-Wno-error=float-conversion>
$<$<PLATFORM_ID:Darwin,Linux,FreeBSD>:-Wall> $<$<COMPILE_LANG_AND_ID:CXX,GNU,AppleClang,Clang>:-Wno-error=shadow>
$<$<COMPILE_LANG_AND_ID:CXX,GNU,AppleClang,Clang>:-Wno-error=float-conversion;-Wno-error=shadow> $<$<COMPILE_LANG_AND_ID:CXX,GNU>:-Wno-error=format-overflow>
$<$<COMPILE_LANG_AND_ID:CXX,GNU>:-Wno-error=format-overflow;-Wno-error=int-conversion;-Wno-error=comment> $<$<COMPILE_LANG_AND_ID:CXX,GNU>:-Wno-error=int-conversion>
$<$<COMPILE_LANG_AND_ID:CXX,AppleClang,Clang>:-Wno-error=null-pointer-subtraction;-Wno-error=deprecated-declarations;-Wno-error=implicit-int-conversion;-Wno-error=shorten-64-to-32;-Wno-comma;-Wno-quoted-include-in-framework-header> $<$<COMPILE_LANG_AND_ID:CXX,GNU>:-Wno-error=comment>
) $<$<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
@ -155,6 +163,8 @@ target_link_libraries(
Asio::Asio Asio::Asio
qrcodegencpp::qrcodegencpp) qrcodegencpp::qrcodegencpp)
target_link_options(obs-websocket PRIVATE $<$<PLATFORM_ID:Windows>:/IGNORE:4099>)
set_target_properties_obs( set_target_properties_obs(
obs-websocket obs-websocket
PROPERTIES FOLDER plugins PROPERTIES FOLDER plugins
@ -168,6 +178,4 @@ if(OS_WINDOWS)
TARGET obs-websocket TARGET obs-websocket
APPEND APPEND
PROPERTY AUTORCC_OPTIONS --format-version 1) PROPERTY AUTORCC_OPTIONS --format-version 1)
target_link_options(obs-websocket PRIVATE /IGNORE:4099)
endif() endif()

View File

@ -1,4 +1,4 @@
project(obs-websocket VERSION 5.3.3) project(obs-websocket VERSION 5.3.5)
set(OBS_WEBSOCKET_RPC_VERSION 1) set(OBS_WEBSOCKET_RPC_VERSION 1)
option(ENABLE_WEBSOCKET "Enable building OBS with websocket plugin" ON) option(ENABLE_WEBSOCKET "Enable building OBS with websocket plugin" ON)

View File

@ -10,6 +10,7 @@ OBSWebSocket.Settings.ShowConnectInfoWarningTitle="Waarskuwing: Tans regstreeks"
OBSWebSocket.Settings.ShowConnectInfoWarningMessage="Dit lyk of n afvoer (stroom, opname, ens.) tans aktief is." 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.ShowConnectInfoWarningInfoText="Is u seker u wil u verbindingsinligting laat sien?"
OBSWebSocket.Settings.Save.UserPasswordWarningTitle="Waarskuwing: potensiële beveiligingsprobleem" 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.UserPasswordWarningInfoText="Is u seker u wil u eie wagwoord gebruik?"
OBSWebSocket.Settings.Save.PasswordInvalidErrorTitle="Fout: Ongeldige opstalling" OBSWebSocket.Settings.Save.PasswordInvalidErrorTitle="Fout: Ongeldige opstalling"
OBSWebSocket.Settings.Save.PasswordInvalidErrorMessage="U moet n wagwoord van meet as 6 karakters gebruik." OBSWebSocket.Settings.Save.PasswordInvalidErrorMessage="U moet n wagwoord van meet as 6 karakters gebruik."
@ -18,6 +19,9 @@ OBSWebSocket.SessionTable.RemoteAddressColumnTitle="Afstandsadres"
OBSWebSocket.SessionTable.SessionDurationColumnTitle="Sessieduur" OBSWebSocket.SessionTable.SessionDurationColumnTitle="Sessieduur"
OBSWebSocket.SessionTable.MessagesInOutColumnTitle="Boodskappe In/Uit" OBSWebSocket.SessionTable.MessagesInOutColumnTitle="Boodskappe In/Uit"
OBSWebSocket.SessionTable.IdentifiedTitle="Geïdentifiseer" OBSWebSocket.SessionTable.IdentifiedTitle="Geïdentifiseer"
OBSWebSocket.SessionTable.KickButtonColumnTitle="Verwyder?"
OBSWebSocket.SessionTable.KickButtonText="Verwyder"
OBSWebSocket.ConnectInfo.DialogTitle="WebSocket-verbindingsinligting"
OBSWebSocket.ConnectInfo.CopyText="Kopieer" OBSWebSocket.ConnectInfo.CopyText="Kopieer"
OBSWebSocket.ConnectInfo.ServerIp="Bediener-IP (beste skatting)" OBSWebSocket.ConnectInfo.ServerIp="Bediener-IP (beste skatting)"
OBSWebSocket.ConnectInfo.ServerPort="Bedienerpoort" OBSWebSocket.ConnectInfo.ServerPort="Bedienerpoort"

View File

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

View File

@ -1,4 +1,5 @@
OBSWebSocket.Plugin.Description="Kawalan-jauh OBS Studio melalui WebSocket" OBSWebSocket.Plugin.Description="Kawalan-jauh OBS Studio melalui 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"

View File

@ -1,2 +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.Password="Server Passord"
OBSWebSocket.Settings.GeneratePassword="Generer 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

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

View File

@ -1259,6 +1259,23 @@
], ],
"responseFields": [] "responseFields": []
}, },
{
"description": "Gets an array of all available source filter kinds.\n\nSimilar to `GetInputKindList`",
"requestType": "GetSourceFilterKindList",
"complexity": 2,
"rpcVersion": "1",
"deprecated": false,
"initialVersion": "5.4.0",
"category": "filters",
"requestFields": [],
"responseFields": [
{
"valueName": "sourceFilterKinds",
"valueType": "Array<String>",
"valueDescription": "Array of source filter kinds"
}
]
},
{ {
"description": "Gets an array of all of a source's filters.", "description": "Gets an array of all of a source's filters.",
"requestType": "GetSourceFilterList", "requestType": "GetSourceFilterList",
@ -1803,6 +1820,14 @@
"valueRestrictions": null, "valueRestrictions": null,
"valueOptional": false, "valueOptional": false,
"valueOptionalBehavior": null "valueOptionalBehavior": null
},
{
"valueName": "contextName",
"valueType": "String",
"valueDescription": "Name of context of the hotkey to trigger",
"valueRestrictions": null,
"valueOptional": true,
"valueOptionalBehavior": "Unknown"
} }
], ],
"responseFields": [] "responseFields": []
@ -3117,7 +3142,13 @@
"initialVersion": "5.0.0", "initialVersion": "5.0.0",
"category": "record", "category": "record",
"requestFields": [], "requestFields": [],
"responseFields": [] "responseFields": [
{
"valueName": "outputActive",
"valueType": "Boolean",
"valueDescription": "The new active state of the output"
}
]
}, },
{ {
"description": "Starts the record output.", "description": "Starts the record output.",

View File

@ -2596,6 +2596,7 @@ communication is desired.
- [TriggerStudioModeTransition](#triggerstudiomodetransition) - [TriggerStudioModeTransition](#triggerstudiomodetransition)
- [SetTBarPosition](#settbarposition) - [SetTBarPosition](#settbarposition)
- [Filters Requests](#filters-1-requests) - [Filters Requests](#filters-1-requests)
- [GetSourceFilterKindList](#getsourcefilterkindlist)
- [GetSourceFilterList](#getsourcefilterlist) - [GetSourceFilterList](#getsourcefilterlist)
- [GetSourceFilterDefaultSettings](#getsourcefilterdefaultsettings) - [GetSourceFilterDefaultSettings](#getsourcefilterdefaultsettings)
- [CreateSourceFilter](#createsourcefilter) - [CreateSourceFilter](#createsourcefilter)
@ -2793,6 +2794,7 @@ Triggers a hotkey using its name. See `GetHotkeyList`
| Name | Type | Description | Value Restrictions | ?Default Behavior | | Name | Type | Description | Value Restrictions | ?Default Behavior |
| ---- | :---: | ----------- | :----------------: | ----------------- | | ---- | :---: | ----------- | :----------------: | ----------------- |
| hotkeyName | String | Name of the hotkey to trigger | None | N/A | | hotkeyName | String | Name of the hotkey to trigger | None | N/A |
| ?contextName | String | Name of context of the hotkey to trigger | None | Unknown |
--- ---
@ -4091,6 +4093,24 @@ Sets the position of the TBar.
## Filters Requests ## Filters Requests
### GetSourceFilterKindList
Gets an array of all available source filter kinds.
Similar to `GetInputKindList`
- Complexity Rating: `2/5`
- Latest Supported RPC Version: `1`
- Added in v5.4.0
**Response Fields:**
| Name | Type | Description |
| ---- | :---: | ----------- |
| sourceFilterKinds | Array&lt;String&gt; | Array of source filter kinds |
---
### GetSourceFilterList ### GetSourceFilterList
Gets an array of all of a source's filters. Gets an array of all of a source's filters.
@ -5023,6 +5043,12 @@ Toggles the status of the record output.
- Latest Supported RPC Version: `1` - Latest Supported RPC Version: `1`
- Added in v5.0.0 - Added in v5.0.0
**Response Fields:**
| Name | Type | Description |
| ---- | :---: | ----------- |
| outputActive | Boolean | The new active state of the output |
--- ---
### StartRecord ### StartRecord

View File

@ -31,6 +31,7 @@ EventHandler::EventHandler()
signal_handler_connect(coreSignalHandler, "source_destroy", SourceDestroyedMultiHandler, this); signal_handler_connect(coreSignalHandler, "source_destroy", SourceDestroyedMultiHandler, this);
signal_handler_connect(coreSignalHandler, "source_remove", SourceRemovedMultiHandler, this); signal_handler_connect(coreSignalHandler, "source_remove", SourceRemovedMultiHandler, this);
signal_handler_connect(coreSignalHandler, "source_rename", SourceRenamedMultiHandler, this); signal_handler_connect(coreSignalHandler, "source_rename", SourceRenamedMultiHandler, this);
signal_handler_connect(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!");
} }
@ -50,10 +51,25 @@ EventHandler::~EventHandler()
signal_handler_disconnect(coreSignalHandler, "source_destroy", SourceDestroyedMultiHandler, this); signal_handler_disconnect(coreSignalHandler, "source_destroy", SourceDestroyedMultiHandler, this);
signal_handler_disconnect(coreSignalHandler, "source_remove", SourceRemovedMultiHandler, this); signal_handler_disconnect(coreSignalHandler, "source_remove", SourceRemovedMultiHandler, this);
signal_handler_disconnect(coreSignalHandler, "source_rename", SourceRenamedMultiHandler, this); signal_handler_disconnect(coreSignalHandler, "source_rename", SourceRenamedMultiHandler, this);
signal_handler_disconnect(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!");
} }
// Revoke callbacks of all inputs and scenes, in case some still have our callbacks attached
auto enumInputs = [](void *param, obs_source_t *source) {
auto eventHandler = static_cast<EventHandler *>(param);
eventHandler->DisconnectSourceSignals(source);
return true;
};
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.");
} }
@ -574,6 +590,23 @@ void EventHandler::SourceRenamedMultiHandler(void *param, calldata_t *data)
} }
} }
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;
default:
break;
}
}
void EventHandler::StreamOutputReconnectHandler(void *param, calldata_t *) void EventHandler::StreamOutputReconnectHandler(void *param, calldata_t *)
{ {
auto eventHandler = static_cast<EventHandler *>(param); auto eventHandler = static_cast<EventHandler *>(param);

View File

@ -69,9 +69,10 @@ private:
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);
@ -106,7 +107,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,
@ -123,6 +124,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();

View File

@ -93,6 +93,32 @@ void EventHandler::HandleInputNameChanged(obs_source_t *, std::string oldInputNa
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 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["inputSettings"] = Utils::Json::ObsDataToJson(inputSettings);
BroadcastEvent(EventSubscription::Inputs, "InputSettingsChanged", eventData);
}
/** /**
* An input's active state has changed. * An input's active state has changed.
* *

View File

@ -33,6 +33,8 @@ const std::unordered_map<std::string, RequestMethodHandler> RequestHandler::_han
{"TriggerHotkeyByName", &RequestHandler::TriggerHotkeyByName}, {"TriggerHotkeyByName", &RequestHandler::TriggerHotkeyByName},
{"TriggerHotkeyByKeySequence", &RequestHandler::TriggerHotkeyByKeySequence}, {"TriggerHotkeyByKeySequence", &RequestHandler::TriggerHotkeyByKeySequence},
{"Sleep", &RequestHandler::Sleep}, {"Sleep", &RequestHandler::Sleep},
{"Compare", &RequestHandler::Compare},
{"Assert", &RequestHandler::Assert},
// Config // Config
{"GetPersistentData", &RequestHandler::GetPersistentData}, {"GetPersistentData", &RequestHandler::GetPersistentData},
@ -111,6 +113,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},

View File

@ -52,6 +52,8 @@ private:
RequestResult TriggerHotkeyByName(const Request &); RequestResult TriggerHotkeyByName(const Request &);
RequestResult TriggerHotkeyByKeySequence(const Request &); RequestResult TriggerHotkeyByKeySequence(const Request &);
RequestResult Sleep(const Request &); RequestResult Sleep(const Request &);
RequestResult Compare(const Request &);
RequestResult Assert(const Request &);
// Config // Config
RequestResult GetPersistentData(const Request &); RequestResult GetPersistentData(const Request &);
@ -130,6 +132,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 &);

View File

@ -19,6 +19,27 @@ 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.
* *

View File

@ -233,6 +233,7 @@ RequestResult RequestHandler::GetHotkeyList(const Request &)
* Triggers a hotkey using its name. See `GetHotkeyList` * Triggers a hotkey using its name. See `GetHotkeyList`
* *
* @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 3
@ -248,7 +249,15 @@ 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.");
@ -323,7 +332,9 @@ 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.
*
* Note: 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
@ -356,3 +367,63 @@ RequestResult RequestHandler::Sleep(const Request &request)
return RequestResult::Error(RequestStatus::UnsupportedRequestBatchExecutionType); return RequestResult::Error(RequestStatus::UnsupportedRequestBatchExecutionType);
} }
} }
/**
* Compares the values of the two request fields, `left` and `right`.
*
* Note: Only available in request batches with types `SERIAL_REALTIME` or `SERIAL_FRAME`.
*
* @requestField left | Any | First request batch variable in comparison
* @requestField right | Any | Second request batch variable in comparison
*
* @responseField result | Boolean | Whether the comparison is equal
*
* @requestType Compare
* @complexity 4
* @rpcVersion -1
* @initialVersion 5.4.0
* @category general
* @api requests
*/
RequestResult RequestHandler::Compare(const Request &request)
{
if (!request.RequestData.contains("left") || !request.RequestData.contains("right"))
return RequestResult::Error(RequestStatus::MissingRequestField, "One or more sides of the comparison are missing.");
bool result = request.RequestData["left"] == request.RequestData["right"];
json responseData;
responseData["result"] = result;
return RequestResult::Success(responseData);
}
/**
* Returns an error if the value of `check` is not `true`.
*
* This can be useful to interrupt a request batch from proceeding if an assumed state does not match real-world state.
*
* Note: Only available in request batches with types `SERIAL_REALTIME` or `SERIAL_FRAME`.
*
* @requestField check | Boolean | Value to assert to be true
*
* @requestType Assert
* @complexity 4
* @rpcVersion -1
* @initialVersion 5.4.0
* @category general
* @api requests
*/
RequestResult RequestHandler::Assert(const Request &request)
{
RequestStatus::RequestStatus statusCode;
std::string comment;
if (!request.ValidateBoolean("check", statusCode, comment))
return RequestResult::Error(statusCode, comment);
bool check = request.RequestData["check"];
if (!check)
return RequestResult::Error(RequestStatus::AssertFailed, "Assertion failed.");
return RequestResult::Success();
}

View File

@ -54,6 +54,8 @@ RequestResult RequestHandler::GetRecordStatus(const Request &)
/** /**
* Toggles the status of the record output. * Toggles the status of the record output.
* *
* @responseField outputActive | Boolean | The new active state of the output
*
* @requestType ToggleRecord * @requestType ToggleRecord
* @complexity 1 * @complexity 1
* @rpcVersion -1 * @rpcVersion -1

View File

@ -44,12 +44,16 @@ RequestResult RequestHandler::GetStreamStatus(const Request &)
uint64_t outputDuration = Utils::Obs::NumberHelper::GetOutputDuration(streamOutput); uint64_t outputDuration = Utils::Obs::NumberHelper::GetOutputDuration(streamOutput);
float outputCongestion = obs_output_get_congestion(streamOutput);
if (std::isnan(outputCongestion)) // libobs does not handle NaN, so we're handling it here
outputCongestion = 0.0f;
json responseData; json responseData;
responseData["outputActive"] = obs_output_active(streamOutput); responseData["outputActive"] = obs_output_active(streamOutput);
responseData["outputReconnecting"] = obs_output_reconnecting(streamOutput); responseData["outputReconnecting"] = obs_output_reconnecting(streamOutput);
responseData["outputTimecode"] = Utils::Obs::StringHelper::DurationToTimecode(outputDuration); responseData["outputTimecode"] = Utils::Obs::StringHelper::DurationToTimecode(outputDuration);
responseData["outputDuration"] = outputDuration; responseData["outputDuration"] = outputDuration;
responseData["outputCongestion"] = obs_output_get_congestion(streamOutput); responseData["outputCongestion"] = outputCongestion;
responseData["outputBytes"] = (uint64_t)obs_output_get_total_bytes(streamOutput); responseData["outputBytes"] = (uint64_t)obs_output_get_total_bytes(streamOutput);
responseData["outputSkippedFrames"] = obs_output_get_frames_dropped(streamOutput); responseData["outputSkippedFrames"] = obs_output_get_frames_dropped(streamOutput);
responseData["outputTotalFrames"] = obs_output_get_total_frames(streamOutput); responseData["outputTotalFrames"] = obs_output_get_total_frames(streamOutput);

View File

@ -415,5 +415,16 @@ namespace RequestStatus {
* @api enums * @api enums
*/ */
CannotAct = 703, CannotAct = 703,
/**
* Assertion failed.
*
* @enumIdentifier AssertFailed
* @enumValue 704
* @enumType RequestStatus
* @rpcVersion -1
* @initialVersion 5.4.0
* @api enums
*/
AssertFailed = 704,
}; };
} }

View File

@ -297,7 +297,7 @@ namespace Utils {
} }
namespace SearchHelper { namespace SearchHelper {
obs_hotkey_t *GetHotkeyByName(std::string name); obs_hotkey_t *GetHotkeyByName(std::string name, std::string context);
obs_source_t *GetSceneTransitionByName(std::string name); // Increments source ref. Use OBSSourceAutoRelease obs_source_t *GetSceneTransitionByName(std::string name); // Increments source ref. Use OBSSourceAutoRelease
obs_sceneitem_t *GetSceneItemByName(obs_scene_t *scene, std::string name, obs_sceneitem_t *GetSceneItemByName(obs_scene_t *scene, std::string name,
int offset = 0); // Increments ref. Use OBSSceneItemAutoRelease int offset = 0); // Increments ref. Use OBSSceneItemAutoRelease

View File

@ -19,7 +19,7 @@ with this program. If not, see <https://www.gnu.org/licenses/>
#include "Obs.h" #include "Obs.h"
#include "plugin-macros.generated.h" #include "plugin-macros.generated.h"
obs_hotkey_t *Utils::Obs::SearchHelper::GetHotkeyByName(std::string name) obs_hotkey_t *Utils::Obs::SearchHelper::GetHotkeyByName(std::string name, std::string context)
{ {
if (name.empty()) if (name.empty())
return nullptr; return nullptr;
@ -27,8 +27,47 @@ obs_hotkey_t *Utils::Obs::SearchHelper::GetHotkeyByName(std::string name)
auto hotkeys = ArrayHelper::GetHotkeyList(); auto hotkeys = ArrayHelper::GetHotkeyList();
for (auto hotkey : hotkeys) { for (auto hotkey : hotkeys) {
if (obs_hotkey_get_name(hotkey) == name) if (obs_hotkey_get_name(hotkey) != name)
continue;
if (context.empty())
return hotkey; return hotkey;
auto type = obs_hotkey_get_registerer_type(hotkey);
if (type == OBS_HOTKEY_REGISTERER_SOURCE) {
OBSSourceAutoRelease source = obs_weak_source_get_source((obs_weak_source_t *)obs_hotkey_get_registerer(hotkey));
if (!source)
continue;
if (context != obs_source_get_name(source))
continue;
} else if (type == OBS_HOTKEY_REGISTERER_OUTPUT) {
OBSOutputAutoRelease output = obs_weak_output_get_output((obs_weak_output_t *)obs_hotkey_get_registerer(hotkey));
if (!output)
continue;
if (context != obs_output_get_name(output))
continue;
} else if (type == OBS_HOTKEY_REGISTERER_ENCODER) {
OBSEncoderAutoRelease encoder = obs_weak_encoder_get_encoder((obs_weak_encoder_t *)obs_hotkey_get_registerer(hotkey));
if (!encoder)
continue;
if (context != obs_encoder_get_name(encoder))
continue;
} else if (type == OBS_HOTKEY_REGISTERER_SERVICE) {
OBSServiceAutoRelease service = obs_weak_service_get_service((obs_weak_service_t *)obs_hotkey_get_registerer(hotkey));
if (!service)
continue;
if (context != obs_service_get_name(service))
continue;
}
return hotkey;
} }
return nullptr; return nullptr;

View File

@ -116,11 +116,12 @@ void Utils::Platform::SendTrayNotification(QSystemTrayIcon::MessageIcon icon, QS
obs_queue_task( obs_queue_task(
OBS_TASK_UI, OBS_TASK_UI,
[](void *param) { [](void *param) {
void *systemTrayPtr = obs_frontend_get_system_tray();
auto systemTray = static_cast<QSystemTrayIcon *>(systemTrayPtr);
auto notification = static_cast<SystemTrayNotification *>(param); auto notification = static_cast<SystemTrayNotification *>(param);
systemTray->showMessage(notification->title, notification->body, notification->icon); void *systemTrayPtr = obs_frontend_get_system_tray();
if (systemTrayPtr) {
auto systemTray = static_cast<QSystemTrayIcon *>(systemTrayPtr);
systemTray->showMessage(notification->title, notification->body, notification->icon);
}
delete notification; delete notification;
}, },
(void *)notification, false); (void *)notification, false);

View File

@ -49,14 +49,21 @@ WebSocketServer::WebSocketServer() : QObject(nullptr)
websocketpp::lib::placeholders::_2)); websocketpp::lib::placeholders::_2));
auto eventHandler = GetEventHandler(); auto eventHandler = GetEventHandler();
eventHandler->SetBroadcastCallback(std::bind(&WebSocketServer::BroadcastEvent, this, std::placeholders::_1, if (eventHandler) {
std::placeholders::_2, std::placeholders::_3, std::placeholders::_4)); eventHandler->SetBroadcastCallback(std::bind(&WebSocketServer::BroadcastEvent, this, std::placeholders::_1,
std::placeholders::_2, std::placeholders::_3, std::placeholders::_4));
eventHandler->SetObsReadyCallback(std::bind(&WebSocketServer::onObsReady, this, std::placeholders::_1)); eventHandler->SetObsReadyCallback(std::bind(&WebSocketServer::onObsReady, this, std::placeholders::_1));
}
} }
WebSocketServer::~WebSocketServer() WebSocketServer::~WebSocketServer()
{ {
auto eventHandler = GetEventHandler();
if (eventHandler) {
eventHandler->SetObsReadyCallback(nullptr);
eventHandler->SetBroadcastCallback(nullptr);
}
if (_server.is_listening()) if (_server.is_listening())
Stop(); Stop();
} }