Skip to content

Commit 0eb0190

Browse files
committed
merge main into this
2 parents 92a40f1 + e311d9a commit 0eb0190

18 files changed

+340
-16
lines changed

.gitignore

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,6 @@
1+
# Exclude 'Main' java class
2+
**/Main.java
3+
14
# Filesystem Stuff
25
**.DS_Store
36

build.gradle

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -65,12 +65,14 @@ artifacts {
6565
}
6666

6767
signing {
68-
def signingKey = System.getenv('PGP_KEY').replace("\\n", "\n")
68+
def signingKey = System.getenv('PGP_KEY') ? System.getenv('PGP_KEY').replace("\\n", "\n") : ''
6969
def signingPassword = System.getenv('PGP_PSW')
7070

7171
useInMemoryPgpKeys(signingKey, signingPassword)
7272

73-
sign configurations.archives
73+
if (signingKey != '') {
74+
sign configurations.archives
75+
}
7476
}
7577

7678
def ossrhUsername = System.getenv('OSSRH_USERNAME')

src/integrationTest/java/net/twasi/obsremotejava/test/OBSRemoteControllerUnsecuredIT.java

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,11 @@ void test() {
5757
controller.registerTransitionBeginCallback(res -> System.out.println("Transition started from scene: '" + res.getFromScene() + "' to scene: '" + res.getToScene() + "'"));
5858

5959
controller.registerTransitionEndCallback(res -> System.out.println("Transition ended with scene: " + res.getToScene()));
60+
61+
controller.registerSourceFilterVisibilityChangedCallback(res -> System.out.println(String.format(
62+
"Source Filter visibility changed on filter '%s' in source '%s'", res.getFilterName(), res.getSourceName()
63+
)));
64+
6065
});
6166

6267
try {
@@ -105,6 +110,41 @@ void testConnectAndDisconnect() {
105110
}
106111
}
107112

113+
@Test
114+
void testCloseCallback() {
115+
116+
// Given a controller that connects successfully
117+
final OBSRemoteController controller = new OBSRemoteController(obsAddress, true,
118+
obsPassword, true);
119+
120+
if (controller.isFailed()) {
121+
fail("Failed to connect to websocket");
122+
}
123+
124+
// When we register a Close callback
125+
AtomicReference<Boolean> testSuccessful = new AtomicReference<>(Boolean.FALSE);
126+
AtomicReference<String> testFailedReason = new AtomicReference<>();
127+
128+
controller.registerCloseCallback((int statusCode, String reason) -> testSuccessful.set(Boolean.TRUE));
129+
130+
// When we disconnect
131+
try {
132+
controller.disconnect();
133+
controller.await();
134+
} catch (InterruptedException e) {
135+
e.printStackTrace();
136+
}
137+
138+
// Then the close callback should have been called
139+
if (testFailedReason.get() != null) {
140+
fail(testFailedReason.get());
141+
}
142+
143+
if (!testSuccessful.get()) {
144+
fail("Disconnect didn't work");
145+
}
146+
}
147+
108148
@Test
109149
void disconnectShouldNotHaveErrorsWhenNoConnectDisconnectCallbacksRegistered() {
110150
AtomicReference<String> testFailedReason = new AtomicReference<>();

src/main/java/net/twasi/obsremotejava/OBSCommunicator.java

Lines changed: 71 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,7 @@
44
import com.google.gson.JsonElement;
55
import com.google.gson.JsonObject;
66
import com.google.gson.JsonParser;
7-
import net.twasi.obsremotejava.callbacks.Callback;
8-
import net.twasi.obsremotejava.callbacks.ErrorCallback;
9-
import net.twasi.obsremotejava.callbacks.StringCallback;
10-
import net.twasi.obsremotejava.callbacks.VoidCallback;
7+
import net.twasi.obsremotejava.callbacks.*;
118
import net.twasi.obsremotejava.events.EventType;
129
import net.twasi.obsremotejava.events.responses.*;
1310
import net.twasi.obsremotejava.objects.throwables.InvalidResponseTypeError;
@@ -24,6 +21,10 @@
2421
import net.twasi.obsremotejava.requests.GetSceneItemProperties.GetSceneItemPropertiesRequest;
2522
import net.twasi.obsremotejava.requests.GetSceneList.GetSceneListRequest;
2623
import net.twasi.obsremotejava.requests.GetSceneList.GetSceneListResponse;
24+
import net.twasi.obsremotejava.requests.GetSourceFilterInfo.GetSourceFilterInfoRequest;
25+
import net.twasi.obsremotejava.requests.GetSourceFilterInfo.GetSourceFilterInfoResponse;
26+
import net.twasi.obsremotejava.requests.GetSourceFilters.GetSourceFiltersRequest;
27+
import net.twasi.obsremotejava.requests.GetSourceFilters.GetSourceFiltersResponse;
2728
import net.twasi.obsremotejava.requests.GetSourceSettings.GetSourceSettingsRequest;
2829
import net.twasi.obsremotejava.requests.GetSourceSettings.GetSourceSettingsResponse;
2930
import net.twasi.obsremotejava.requests.GetStreamingStatus.GetStreamingStatusRequest;
@@ -55,6 +56,8 @@
5556
import net.twasi.obsremotejava.requests.SetPreviewScene.SetPreviewSceneResponse;
5657
import net.twasi.obsremotejava.requests.SetSceneItemProperties.SetSceneItemPropertiesRequest;
5758
import net.twasi.obsremotejava.requests.SetSceneItemProperties.SetSceneItemPropertiesResponse;
59+
import net.twasi.obsremotejava.requests.SetSourceFilterVisibility.SetSourceFilterVisibilityRequest;
60+
import net.twasi.obsremotejava.requests.SetSourceFilterVisibility.SetSourceFilterVisibilityResponse;
5861
import net.twasi.obsremotejava.requests.SetSourceSettings.SetSourceSettingsRequest;
5962
import net.twasi.obsremotejava.requests.SetSourceSettings.SetSourceSettingsResponse;
6063
import net.twasi.obsremotejava.requests.SetStudioModeEnabled.SetStudioModeEnabledRequest;
@@ -107,6 +110,7 @@ public class OBSCommunicator {
107110

108111
private Callback<GetVersionResponse> onConnect;
109112
private VoidCallback onDisconnect;
113+
private CloseCallback onClose;
110114
private StringCallback onConnectionFailed;
111115
private ErrorCallback onError;
112116

@@ -125,6 +129,7 @@ public class OBSCommunicator {
125129
private Callback<TransitionListChangedResponse> onTransitionListChanged;
126130
private Callback<TransitionBeginResponse> onTransitionBegin;
127131
private Callback<TransitionEndResponse> onTransitionEnd;
132+
private Callback<SourceFilterVisibilityChangedResponse> onSourceFilterVisibilityChanged;
128133

129134
private GetVersionResponse versionInfo;
130135

@@ -155,12 +160,9 @@ public void onError(Session session, Throwable throwable) {
155160
@OnWebSocketClose
156161
public void onClose(int statusCode, String reason) {
157162
log.info(String.format("Connection closed: %d - %s%n", statusCode, reason));
163+
runOnDisconnect();
158164
this.closeLatch.countDown(); // trigger latch
159-
try {
160-
this.onDisconnect.run();
161-
} catch (Throwable t) {
162-
log.error("Unable to disconnect OBS Client", t);
163-
}
165+
runOnClosed(statusCode, reason);
164166
}
165167

166168
@OnWebSocketConnect
@@ -191,6 +193,7 @@ public void onMessage(String msg) {
191193
// Response
192194
ResponseBase responseBase = new Gson().fromJson(msg, ResponseBase.class);
193195
Class type = messageTypes.get(responseBase.getMessageId());
196+
log.trace(String.format("Trying to deserialize response with type %s and message '%s'", type, msg));
194197
responseBase = (ResponseBase) new Gson().fromJson(msg, type);
195198

196199
try {
@@ -292,6 +295,11 @@ private void processIncomingEvent(String msg, EventType eventType) {
292295
onScenesChanged.run(new Gson().fromJson(msg, ScenesChangedResponse.class));
293296
}
294297
break;
298+
case SourceFilterVisibilityChanged:
299+
if(onSourceFilterVisibilityChanged != null) {
300+
onSourceFilterVisibilityChanged.run(new Gson().fromJson(msg, SourceFilterVisibilityChangedResponse.class));
301+
}
302+
break;
295303
case SwitchTransition:
296304
if (onSwitchTransition != null) {
297305
onSwitchTransition.run(new Gson().fromJson(msg, SwitchTransitionResponse.class));
@@ -379,6 +387,8 @@ public void registerOnDisconnect(VoidCallback onDisconnect) {
379387
this.onDisconnect = onDisconnect;
380388
}
381389

390+
public void registerOnClose(CloseCallback closeCallback) { this.onClose = closeCallback; }
391+
382392
public void registerOnConnectionFailed(StringCallback onConnectionFailed) {
383393
this.onConnectionFailed = onConnectionFailed;
384394
}
@@ -407,6 +417,10 @@ public void registerOnScenesChanged(Callback<ScenesChangedResponse> onScenesChan
407417
this.onScenesChanged = onScenesChanged;
408418
}
409419

420+
public void registerOnSourceFilterVisibilityChanged(Callback<SourceFilterVisibilityChangedResponse> onSourceFilterVisibilityChanged) {
421+
this.onSourceFilterVisibilityChanged = onSourceFilterVisibilityChanged;
422+
}
423+
410424
public void registerOnSwitchTransition(Callback<SwitchTransitionResponse> onSwitchTransition) {
411425
this.onSwitchTransition = onSwitchTransition;
412426
}
@@ -493,6 +507,24 @@ public void setSourceSettings(String sourceName, Map<String, Object> settings, C
493507
callbacks.put(SetSourceSettingsResponse.class, callback);
494508
}
495509

510+
public void getSourceFilters(String sourceName, Callback<GetSourceFiltersResponse> callback) {
511+
GetSourceFiltersRequest request = new GetSourceFiltersRequest(sourceName);
512+
session.getRemote().sendStringByFuture(new Gson().toJson(request));
513+
callbacks.put(GetSourceFiltersResponse.class, callback);
514+
}
515+
516+
public void getSourceFilterInfo(String sourceName, String filterName, Callback<GetSourceFilterInfoResponse> callback) {
517+
GetSourceFilterInfoRequest request = new GetSourceFilterInfoRequest(sourceName, filterName);
518+
session.getRemote().sendStringByFuture(new Gson().toJson(request));
519+
callbacks.put(GetSourceFilterInfoResponse.class, callback);
520+
}
521+
522+
public void setSourceFilterVisibility(String sourceName, String filterName, boolean filterEnabled, Callback<SetSourceFilterVisibilityResponse> callback) {
523+
SetSourceFilterVisibilityRequest request = new SetSourceFilterVisibilityRequest(sourceName, filterName, filterEnabled);
524+
session.getRemote().sendStringByFuture(new Gson().toJson(request));
525+
callbacks.put(SetSourceFilterVisibilityResponse.class, callback);
526+
}
527+
496528
public void startRecording(Callback<StartRecordingResponse> callback) {
497529
StartRecordingRequest request = new StartRecordingRequest(this);
498530

@@ -692,4 +724,34 @@ private void runOnConnect(GetVersionResponse versionInfo) {
692724
log.error("Unable to run OnConnect callback", t);
693725
}
694726
}
727+
728+
void runOnDisconnect() {
729+
log.debug("Running onDisconnect");
730+
if (onDisconnect == null) {
731+
log.debug("No onDisconnect callback was registered");
732+
return;
733+
}
734+
735+
try {
736+
onDisconnect.run();
737+
} catch (Throwable t) {
738+
log.error("Unable to run OnDisconnect callback", t);
739+
}
740+
}
741+
742+
743+
private void runOnClosed(int statusCode, String reason) {
744+
log.debug("Running onClose with statusCode " + statusCode + " and reason: " + reason);
745+
746+
if(this.onClose == null) {
747+
log.debug("No onClose was registered.");
748+
return;
749+
}
750+
751+
try {
752+
onClose.run(statusCode, reason);
753+
} catch (Throwable t) {
754+
log.error("Unable to run onClose callback", t);
755+
}
756+
}
695757
}

src/main/java/net/twasi/obsremotejava/OBSRemoteController.java

Lines changed: 35 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,17 @@
11
package net.twasi.obsremotejava;
22

3-
import net.twasi.obsremotejava.callbacks.Callback;
4-
import net.twasi.obsremotejava.callbacks.ErrorCallback;
5-
import net.twasi.obsremotejava.callbacks.StringCallback;
6-
import net.twasi.obsremotejava.callbacks.VoidCallback;
3+
import com.google.gson.Gson;
4+
import net.twasi.obsremotejava.callbacks.*;
75
import net.twasi.obsremotejava.events.responses.*;
86
import net.twasi.obsremotejava.objects.throwables.OBSResponseError;
97
import net.twasi.obsremotejava.requests.GetCurrentProfile.GetCurrentProfileResponse;
108
import net.twasi.obsremotejava.requests.GetCurrentScene.GetCurrentSceneResponse;
119
import net.twasi.obsremotejava.requests.GetPreviewScene.GetPreviewSceneResponse;
1210
import net.twasi.obsremotejava.requests.GetSceneList.GetSceneListResponse;
11+
import net.twasi.obsremotejava.requests.GetSourceFilterInfo.GetSourceFilterInfoRequest;
12+
import net.twasi.obsremotejava.requests.GetSourceFilterInfo.GetSourceFilterInfoResponse;
13+
import net.twasi.obsremotejava.requests.GetSourceFilters.GetSourceFiltersRequest;
14+
import net.twasi.obsremotejava.requests.GetSourceFilters.GetSourceFiltersResponse;
1315
import net.twasi.obsremotejava.requests.GetSourceSettings.GetSourceSettingsResponse;
1416
import net.twasi.obsremotejava.requests.GetStreamingStatus.GetStreamingStatusResponse;
1517
import net.twasi.obsremotejava.requests.GetStudioModeEnabled.GetStudioModeEnabledResponse;
@@ -25,6 +27,8 @@
2527
import net.twasi.obsremotejava.requests.SetMute.SetMuteResponse;
2628
import net.twasi.obsremotejava.requests.SetPreviewScene.SetPreviewSceneResponse;
2729
import net.twasi.obsremotejava.requests.SetSceneItemProperties.SetSceneItemPropertiesResponse;
30+
import net.twasi.obsremotejava.requests.SetSourceFilterVisibility.SetSourceFilterVisibilityRequest;
31+
import net.twasi.obsremotejava.requests.SetSourceFilterVisibility.SetSourceFilterVisibilityResponse;
2832
import net.twasi.obsremotejava.requests.SetSourceSettings.SetSourceSettingsResponse;
2933
import net.twasi.obsremotejava.requests.SetStudioModeEnabled.SetStudioModeEnabledResponse;
3034
import net.twasi.obsremotejava.requests.SetTransitionDuration.SetTransitionDurationResponse;
@@ -114,7 +118,7 @@ public void connect() {
114118
}
115119

116120
public void disconnect() {
117-
// wait for closed socket connection
121+
// trigger the latch
118122
try {
119123
if (debug) {
120124
log.debug("Closing connection.");
@@ -124,6 +128,7 @@ public void disconnect() {
124128
runOnError("Error during closing websocket connection", e);
125129
}
126130

131+
// stop the client if it isn't already stopped or stopping
127132
if (!client.isStopped() && !client.isStopping()) {
128133
try {
129134
if (debug) {
@@ -162,6 +167,10 @@ public void registerConnectionFailedCallback(StringCallback onConnectionFailed)
162167
communicator.registerOnConnectionFailed(onConnectionFailed);
163168
}
164169

170+
public void registerCloseCallback(CloseCallback closeCallback) {
171+
communicator.registerOnClose(closeCallback);
172+
}
173+
165174
public void registerRecordingStartedCallback(VoidCallback onRecordingStarted) {
166175
communicator.registerOnRecordingStarted(onRecordingStarted);
167176
}
@@ -218,6 +227,10 @@ public void registerTransitionEndCallback(Callback<TransitionEndResponse> onTran
218227
communicator.registerOnTransitionEnd(onTransitionEnd);
219228
}
220229

230+
public void registerSourceFilterVisibilityChangedCallback(Callback<SourceFilterVisibilityChangedResponse> onSourceVisibilityChanged) {
231+
communicator.registerOnSourceFilterVisibilityChanged(onSourceVisibilityChanged);
232+
}
233+
221234
public void await() throws InterruptedException {
222235
communicator.await();
223236
}
@@ -248,6 +261,22 @@ public void getSceneItemProperties(String scene, String source, Callback<SetScen
248261
communicator.getSceneItemProperties(scene, source, callback);
249262
}
250263

264+
public void getSourceProperties(String scene, String source, Callback<SetSceneItemPropertiesResponse> callback) {
265+
getSceneItemProperties(scene, source, callback);
266+
}
267+
268+
public void getSourceFilters(String sourceName, Callback<GetSourceFiltersResponse> callback) {
269+
communicator.getSourceFilters(sourceName, callback);
270+
}
271+
272+
public void getSourceFilterInfo(String sourceName, String filterName, Callback<GetSourceFilterInfoResponse> callback) {
273+
communicator.getSourceFilterInfo(sourceName, filterName, callback);
274+
}
275+
276+
public void setSourceFilterVisibility(String sourceName, String filterName, boolean filterEnabled, Callback<SetSourceFilterVisibilityResponse> callback) {
277+
communicator.setSourceFilterVisibility(sourceName, filterName, filterEnabled, callback);
278+
}
279+
251280
public void getTransitionList(Callback<GetTransitionListResponse> callback) {
252281
communicator.getTransitionList(callback);
253282
}
@@ -377,4 +406,5 @@ private void runOnConnectionFailed(String message, Throwable throwable) {
377406
log.error("Unable to run OnConnectionFailed callback", e);
378407
}
379408
}
409+
380410
}
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
package net.twasi.obsremotejava.callbacks;
2+
3+
public interface CloseCallback {
4+
void run(int statusCode, String reason);
5+
}

src/main/java/net/twasi/obsremotejava/events/EventType.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ public enum EventType {
1111
StreamStopped,
1212
SwitchScenes,
1313
ScenesChanged,
14+
SourceFilterVisibilityChanged,
1415
SwitchTransition,
1516
TransitionListChanged,
1617
TransitionBegin,
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
package net.twasi.obsremotejava.events.responses;
2+
3+
import net.twasi.obsremotejava.requests.ResponseBase;
4+
5+
public class SourceFilterVisibilityChangedResponse extends ResponseBase {
6+
private String sourceName;
7+
private String filterName;
8+
private boolean filterEnabled;
9+
10+
public String getSourceName() {
11+
return sourceName;
12+
}
13+
14+
public String getFilterName() {
15+
return filterName;
16+
}
17+
18+
public boolean isFilterEnabled() {
19+
return filterEnabled;
20+
}
21+
}

0 commit comments

Comments
 (0)