essential-actions
Clone or download
Modified Files
package com.stream_pi.democustomtoggleaction;
package com.stream_pi.democustomtoggleaction;
import com.stream_pi.action_api.action.DisplayTextAlignment;
import com.stream_pi.action_api.actionproperty.property.ControlType;
import com.stream_pi.action_api.actionproperty.property.Property;
import com.stream_pi.action_api.actionproperty.property.Type;
import com.stream_pi.action_api.externalplugin.ToggleAction;
import com.stream_pi.action_api.externalplugin.ToggleAction;
import com.stream_pi.util.alert.StreamPiAlert;
import com.stream_pi.util.alert.StreamPiAlert;
import com.stream_pi.util.version.Version;
import com.stream_pi.util.version.Version;
import javafx.concurrent.Task;
import java.util.ArrayList;
public class DemoCustomToggleAction extends ToggleAction
public class DemoCustomToggleAction extends ToggleAction
{
{
public DemoCustomToggleAction()
public DemoCustomToggleAction()
{
{
setName("Demo Toggle Action");
setName("Demo Toggle Action");
setAuthor("rnayabed");
setAuthor("rnayabed");
setHelpLink("https://github.com/Stream-Pi/");
setHelpLink("https://github.com/Stream-Pi/");
setVersion(new Version(1,0,0));
setVersion(new Version(1, 0, 0));
setCategory("Custom Actions");
setCategory("Custom Actions");
}
}
@Override
@Override
public void onToggleOn() throws Exception
public void onToggleOn() throws Exception
{
{
}
}
@Override
@Override
public void onActionCreate()
public void onActionCreate()
{
{
new StreamPiAlert("Toggle was turned on!").show();
new StreamPiAlert("Toggle was turned on!").show();
}
}
@Override
@Override
public void onToggleOff()
public void onToggleOff()
{
{
new StreamPiAlert("Toggle was turned off!").show();
new StreamPiAlert("Toggle was turned off!").show();
}
}
@Override
@Override
public void initProperties()
public void initProperties()
{
{
//Called First
//Called First
}
}
@Override
@Override
public void initAction() {
public void initAction()
{
// This is called after initProperties()
// This is called after initProperties()
}
}
@Override
@Override
public void onShutDown() throws Exception {
public void onShutDown() throws Exception
{
// TODO Auto-generated method stub
// TODO Auto-generated method stub
}
}
}
}
build-all:
build-all:
./build.sh
./build.sh
build-hotkey-action:
hotkey:
./build.sh hotkey
./build.sh hotkey
build-media-key-action:
media-key:
./build.sh mediakey
./build.sh media_key
build-obs-suite-action:
obs-suite:
./build.sh obssuite
./build.sh obs_suite
build-play-audio-clip-action:
play-audio-clip:
./build.sh playaudioclip
./build.sh play_audio_clip
build-run-command-action:
run-command:
./build.sh runcommand
./build.sh run_command
build-text-block-action:
text-block:
./build.sh textblock
./build.sh text_block
build-twitch-chat-action:
twitch-chat:
./build.sh twitchchat
./build.sh twitch_chat
build-twitter-action:
twitter:
./build.sh twitter
./build.sh twitter
build-website-action:
website:
./build.sh website
./build.sh website
# Stream-Pi Essential Actions
# Stream-Pi Essential Actions
Set of trusted, pre-bundled actions and integrations for Stream-Pi using the [Stream-Pi Action API](https://github.com/stream-pi/actionapi).
Set of trusted, pre-bundled actions and integrations for Stream-Pi using the [Stream-Pi Action API](https://github.com/stream-pi/actionapi).
## Prerequisites
## Prerequisites
- Java >= 11
- Java >= 11
- Maven >= 3.6.3
- Maven >= 3.6.3
## List of Actions
## List of Actions
- Hotkey
- Hotkey
- Media File
- Media File
- Media Key
- Media Key
- OBS Actions
- OBS Actions
- Run Command
- Run Command
- Text Block
- Text Block
- Twitch Chat
- Twitch Chat
- Twitter
- Twitter
- Website
- Website
## Actions Help Guide
## Actions Help Guide
- [Hotkey](hotkeyaction/README.md)
- [Hotkey](hotkeyaction/README.md)
- [Run Command](runcommandaction/README.md)
- [Twitch Chat](twitch/README.md)
- [Twitch Chat](twitch/README.md)
---
## Quick Start
## Quick Start
Build all actions by executing `make build-all` from the command line or specific actions i.e. `make build-twitch-chat-action`, see [Makefile](Makefile) for complete list.
Build all actions by executing `make build-all` from the command line or specific actions i.e. `make twitch-chat`, see [Makefile](Makefile) for complete list.
To test these actions out in your local environment you'll need to run the [Stream-Pi Server](https://github.com/stream-pi/server) and copy the contents of `PreBuiltPlugins` to the server's
To test these actions out in your local environment you'll need to run the [Stream-Pi Server](https://github.com/stream-pi/server) and copy the contents of `PreBuiltPlugins` to the server's
Plugins directory (`data/Plugins` by default), especially if you're writing your own custom action / integration.
Plugins directory (`$HOME/Stream-Pi/Server/Plugins` by default), especially if you're writing your own custom action / integration.
#!/bin/bash
#!/bin/bash
FOLD=PreBuiltPlugins
FOLD=PreBuiltPlugins
DEPS=Dependencies
DEPS=Dependencies
hotkey() {
hotkey() {
pushd . || exit
pushd . || exit
cd hotkeyaction && mvn clean -Dmaven.test.skip package
cd hotkeyaction && mvn clean -Dmaven.test.skip package
mv target/hotkeyaction-*.jar ../$FOLD/hotkeyaction.jar
mv target/hotkeyaction-*.jar ../$FOLD/hotkeyaction.jar
popd || exit
popd || exit
}
}
mediakey() {
media_key() {
pushd . || exit
pushd . || exit
cd mediakeyaction && mvn clean -Dmaven.test.skip package
cd mediakeyaction && mvn clean -Dmaven.test.skip package
mv target/mediakeyaction-*.jar ../$FOLD/mediakeyaction.jar
mv target/mediakeyaction-*.jar ../$FOLD/mediakeyaction.jar
popd || exit
popd || exit
}
}
obssuite() {
obs_suite() {
pushd . || exit
pushd . || exit
cd obssuite/mother && mvn clean install -Dmaven.test.skip package
cd obssuite/mother && mvn clean install -Dmaven.test.skip package
mv target/obssuite_motheraction-*.jar ../../$FOLD/obssuite_motheraction.jar
mv target/obssuite_motheraction-*.jar ../../$FOLD/obssuite_motheraction.jar
cd ../setcurrentprofile && mvn clean -Dmaven.test.skip package
cd ../setcurrentprofile && mvn clean -Dmaven.test.skip package
mv target/obssuite_setcurrentprofileaction-*.jar ../../$FOLD/obssuite_setcurrentprofileaction.jar
mv target/obssuite_setcurrentprofileaction-*.jar ../../$FOLD/obssuite_setcurrentprofileaction.jar
cd ../setcurrentscene && mvn clean -Dmaven.test.skip package
cd ../setcurrentscene && mvn clean -Dmaven.test.skip package
mv target/obssuite_setcurrentsceneaction-*.jar ../../$FOLD/obssuite_setcurrentsceneaction.jar
mv target/obssuite_setcurrentsceneaction-*.jar ../../$FOLD/obssuite_setcurrentsceneaction.jar
cd ../setcurrenttransition && mvn clean -Dmaven.test.skip package
cd ../setcurrenttransition && mvn clean -Dmaven.test.skip package
mv target/obssuite_setcurrenttransitionaction-*.jar ../../$FOLD/obssuite_setcurrenttransitionaction.jar
mv target/obssuite_setcurrenttransitionaction-*.jar ../../$FOLD/obssuite_setcurrenttransitionaction.jar
cd ../setmute && mvn clean -Dmaven.test.skip package
cd ../setmute && mvn clean -Dmaven.test.skip package
mv target/obssuite_setmuteaction-*.jar ../../$FOLD/obssuite_setmuteaction.jar
mv target/obssuite_setmuteaction-*.jar ../../$FOLD/obssuite_setmuteaction.jar
cd ../setcurrentprofile && mvn clean -Dmaven.test.skip package
cd ../setcurrentprofile && mvn clean -Dmaven.test.skip package
mv target/obssuite_setcurrentprofileaction-*.jar ../../$FOLD/obssuite_setcurrentprofileaction.jar
mv target/obssuite_setcurrentprofileaction-*.jar ../../$FOLD/obssuite_setcurrentprofileaction.jar
cd ../setpreviewscene && mvn clean -Dmaven.test.skip package
cd ../setpreviewscene && mvn clean -Dmaven.test.skip package
mv target/obssuite_setpreviewsceneaction-*.jar ../../$FOLD/obssuite_setpreviewsceneaction.jar
mv target/obssuite_setpreviewsceneaction-*.jar ../../$FOLD/obssuite_setpreviewsceneaction.jar
cd ../setrecording && mvn clean -Dmaven.test.skip package
cd ../setrecording && mvn clean -Dmaven.test.skip package
mv target/obssuite_setrecordingaction-*.jar ../../$FOLD/obssuite_setrecordingaction.jar
mv target/obssuite_setrecordingaction-*.jar ../../$FOLD/obssuite_setrecordingaction.jar
cd ../setreplaybuffer && mvn clean -Dmaven.test.skip package
cd ../setreplaybuffer && mvn clean -Dmaven.test.skip package
mv target/obssuite_setreplaybufferaction-*.jar ../../$FOLD/obssuite_setreplaybufferaction.jar
mv target/obssuite_setreplaybufferaction-*.jar ../../$FOLD/obssuite_setreplaybufferaction.jar
cd ../setstreaming && mvn clean -Dmaven.test.skip package
cd ../setstreaming && mvn clean -Dmaven.test.skip package
mv target/obssuite_setstreamingaction-*.jar ../../$FOLD/obssuite_setstreamingaction.jar
mv target/obssuite_setstreamingaction-*.jar ../../$FOLD/obssuite_setstreamingaction.jar
cd ../setstudiomode && mvn clean -Dmaven.test.skip package
cd ../setstudiomode && mvn clean -Dmaven.test.skip package
mv target/obssuite_setstudiomodeaction-*.jar ../../$FOLD/obssuite_setstudiomodeaction.jar
mv target/obssuite_setstudiomodeaction-*.jar ../../$FOLD/obssuite_setstudiomodeaction.jar
cd ../setvolume && mvn clean -Dmaven.test.skip package
cd ../setvolume && mvn clean -Dmaven.test.skip package
mv target/obssuite_setvolumeaction-*.jar ../../$FOLD/obssuite_setvolumeaction.jar
mv target/obssuite_setvolumeaction-*.jar ../../$FOLD/obssuite_setvolumeaction.jar
popd || exit
popd || exit
}
}
playaudioclip() {
play_audio_clip() {
pushd . || exit
pushd . || exit
cd playaudioclipaction && mvn clean -Dmaven.test.skip package
cd playaudioclipaction && mvn clean -Dmaven.test.skip package
mv target/playaudioclipaction-*.jar ../$FOLD/playaudioclipaction.jar
mv target/playaudioclipaction-*.jar ../$FOLD/playaudioclipaction.jar
popd || exit
popd || exit
}
}
runcommand() {
run_command() {
pushd . || exit
pushd . || exit
cd runcommandaction && mvn clean -Dmaven.test.skip package
cd runcommandaction && mvn clean -Dmaven.test.skip package
mv target/runcommandaction-*.jar ../$FOLD/runcommandaction.jar
mv target/runcommandaction-*.jar ../$FOLD/runcommandaction.jar
popd || exit
popd || exit
}
}
textblock() {
text_block() {
pushd . || exit
pushd . || exit
cd textblockaction && mvn clean -Dmaven.test.skip package
cd textblockaction && mvn clean -Dmaven.test.skip package
mv target/textblockaction-*.jar ../$FOLD/textblockaction.jar
mv target/textblockaction-*.jar ../$FOLD/textblockaction.jar
popd || exit
popd || exit
}
}
twitter() {
twitch_chat() {
pushd . || exit
cd twitteraction && mvn clean -Dmaven.test.skip package
mv target/twitteraction-*.jar ../$FOLD/twitteraction.jar
popd || exit
}
twitchchat() {
pushd . || exit
pushd . || exit
cd twitch/twitch-chat-connect && mvn clean install -Dmaven.test.skip package
cd twitch/twitch-chat-connect && mvn clean install -Dmaven.test.skip package
mv target/twitch-chat-connect-*.jar ../../$FOLD/twitch-chat-connect.jar
mv target/twitch-chat-connect-*.jar ../../$FOLD/twitch-chat-connect.jar
cd ../send-channel-msg && mvn clean -Dmaven.test.skip package
cd ../send-channel-msg && mvn clean -Dmaven.test.skip package
mv target/twitch-send-channel-msg-*.jar ../../$FOLD/twitch-send-channel-msg.jar
mv target/twitch-send-channel-msg-*.jar ../../$FOLD/twitch-send-channel-msg.jar
cd ../clear-chat && mvn clean -Dmaven.test.skip package
cd ../clear-chat && mvn clean -Dmaven.test.skip package
mv target/twitch-clear-chat-*.jar ../../$FOLD/twitch-clear-chat.jar
mv target/twitch-clear-chat-*.jar ../../$FOLD/twitch-clear-chat.jar
cd ../set-color && mvn clean -Dmaven.test.skip package
cd ../set-color && mvn clean -Dmaven.test.skip package
mv target/twitch-set-color-*.jar ../../$FOLD/twitch-set-color.jar
mv target/twitch-set-color-*.jar ../../$FOLD/twitch-set-color.jar
cd ../whisper && mvn clean -Dmaven.test.skip package
cd ../whisper && mvn clean -Dmaven.test.skip package
mv target/twitch-whisper-*.jar ../../$FOLD/twitch-whisper.jar
mv target/twitch-whisper-*.jar ../../$FOLD/twitch-whisper.jar
cd ../unraid && mvn clean -Dmaven.test.skip package
cd ../unraid && mvn clean -Dmaven.test.skip package
mv target/twitch-unraid-*.jar ../../$FOLD/twitch-unraid.jar
mv target/twitch-unraid-*.jar ../../$FOLD/twitch-unraid.jar
cd ../unhost && mvn clean -Dmaven.test.skip package
cd ../unhost && mvn clean -Dmaven.test.skip package
mv target/twitch-unhost-*.jar ../../$FOLD/twitch-unhost.jar
mv target/twitch-unhost-*.jar ../../$FOLD/twitch-unhost.jar
cd ../add-stream-marker && mvn clean -Dmaven.test.skip package
cd ../add-stream-marker && mvn clean -Dmaven.test.skip package
mv target/twitch-add-stream-marker-*.jar ../../$FOLD/twitch-add-stream-marker.jar
mv target/twitch-add-stream-marker-*.jar ../../$FOLD/twitch-add-stream-marker.jar
cd ../host-channel && mvn clean -Dmaven.test.skip package
cd ../host-channel && mvn clean -Dmaven.test.skip package
mv target/twitch-host-channel-*.jar ../../$FOLD/twitch-host-channel.jar
mv target/twitch-host-channel-*.jar ../../$FOLD/twitch-host-channel.jar
cd ../raid-channel && mvn clean -Dmaven.test.skip package
cd ../raid-channel && mvn clean -Dmaven.test.skip package
mv target/twitch-raid-channel-*.jar ../../$FOLD/twitch-raid-channel.jar
mv target/twitch-raid-channel-*.jar ../../$FOLD/twitch-raid-channel.jar
cd ../start-commercial && mvn clean -Dmaven.test.skip package
cd ../start-commercial && mvn clean -Dmaven.test.skip package
mv target/twitch-start-commercial-*.jar ../../$FOLD/twitch-start-commercial.jar
mv target/twitch-start-commercial-*.jar ../../$FOLD/twitch-start-commercial.jar
cd ../subs-only && mvn clean -Dmaven.test.skip package
cd ../subs-only && mvn clean -Dmaven.test.skip package
mv target/twitch-subs-only-*.jar ../../$FOLD/twitch-subs-only.jar
mv target/twitch-subs-only-*.jar ../../$FOLD/twitch-subs-only.jar
cd ../slow-mode && mvn clean -Dmaven.test.skip package
cd ../slow-mode && mvn clean -Dmaven.test.skip package
mv target/twitch-slow-mode-*.jar ../../$FOLD/twitch-slow-mode.jar
mv target/twitch-slow-mode-*.jar ../../$FOLD/twitch-slow-mode.jar
popd || exit
popd || exit
}
}
twitter() {
pushd . || exit
cd twitteraction && mvn clean -Dmaven.test.skip package
mv target/twitteraction-*.jar ../$FOLD/twitteraction.jar
popd || exit
}
website() {
website() {
pushd . || exit
pushd . || exit
cd websiteaction && mvn clean -Dmaven.test.skip package
cd websiteaction && mvn clean -Dmaven.test.skip package
mv target/websiteaction-*.jar ../$FOLD/websiteaction.jar
mv target/websiteaction-*.jar ../$FOLD/websiteaction.jar
popd || exit
popd || exit
}
}
mkdir -p $FOLD
mkdir -p $FOLD
rm -rf "${FOLD:?}/"*
rm -rf "${FOLD:?}/"*
cp $DEPS/* $FOLD/
cp $DEPS/* $FOLD/
case "$1" in
case "$1" in
hotkey)
hotkey)
hotkey
hotkey
;;
;;
mediakey)
media_key)
mediakey
media_key
;;
obs_suite)
obs_suite
;;
play_audio_clip)
play_audio_clip
;;
;;
playaudioclip)
run_command)
playaudioclip
run_command
;;
;;
runcommand)
text_block)
runcommand
text_block
;;
;;
textblock)
twitch_chat)
textblock
twitch_chat
;;
;;
twitter)
twitter)
twitter
twitter
;;
;;
website)
website)
website
website
;;
;;
obssuite)
obssuite
;;
twitchchat)
twitchchat
;;
*)
*)
# build all actions as default
# build all actions as default
hotkey
hotkey
mediakey
media_key
obssuite
obs_suite
playaudioclip
play_audio_clip
runcommand
run_command
textblock
text_block
twitch_chat
twitter
twitter
twitchchat
website
website
;;
;;
esac
esac
package mother;
package mother;
import com.stream_pi.action_api.actionproperty.property.ControlType;
import com.stream_pi.action_api.actionproperty.property.ControlType;
import com.stream_pi.action_api.actionproperty.property.Property;
import com.stream_pi.action_api.actionproperty.property.Property;
import com.stream_pi.action_api.actionproperty.property.Type;
import com.stream_pi.action_api.actionproperty.property.Type;
import com.stream_pi.action_api.externalplugin.NormalAction;
import com.stream_pi.action_api.externalplugin.NormalAction;
import com.stream_pi.util.version.Version;
import com.stream_pi.util.exception.MinorException;
import com.stream_pi.util.exception.MinorException;
import mother.motherconnection.MotherConnection;
import javafx.scene.control.Button;
import javafx.scene.control.Button;
import mother.motherconnection.MotherConnection;
public class Mother extends NormalAction
public class Mother extends NormalAction
{
{
public Mother()
public Mother()
{
{
setName("OBS Plugin");
setName("OBS Plugin");
setCategory("OBS");
setCategory("OBS");
setVisibilityInPluginsPane(false);
setVisibilityInPluginsPane(false);
setAuthor("rnayabed");
setAuthor("rnayabed");
setHelpLink("https://github.com/Stream-Pi/EssentialActions");
setHelpLink("https://github.com/Stream-Pi/EssentialActions");
setVersion(MotherConnection.VERSION);
setVersion(MotherConnection.VERSION);
connectDisconnectButton = new Button("Connect");
connectDisconnectButton = new Button("Connect");
setServerSettingsButtonBar(connectDisconnectButton);
setServerSettingsButtonBar(connectDisconnectButton);
}
}
@Override
@Override
public void onActionClicked()
public void onActionClicked()
{
{
}
}
private Button connectDisconnectButton;
private Button connectDisconnectButton;
@Override
@Override
public void initProperties() throws Exception
public void initProperties() throws Exception
{
{
Property urlProperty = new Property("url", Type.STRING);
Property urlProperty = new Property("url", Type.STRING);
urlProperty.setDisplayName("URL");
urlProperty.setDisplayName("URL");
urlProperty.setDefaultValueStr("ws://localhost:4444");
urlProperty.setDefaultValueStr("ws://localhost:4444");
urlProperty.setCanBeBlank(false);
urlProperty.setCanBeBlank(false);
Property passwordProperty = new Property("pass", Type.STRING);
Property passwordProperty = new Property("pass", Type.STRING);
passwordProperty.setControlType(ControlType.TEXT_FIELD_MASKED);
passwordProperty.setControlType(ControlType.TEXT_FIELD_MASKED);
passwordProperty.setDisplayName("Password");
passwordProperty.setDisplayName("Password");
Property connectOnStartupProperty = new Property("connect_on_startup", Type.BOOLEAN);
Property connectOnStartupProperty = new Property("connect_on_startup", Type.BOOLEAN);
connectOnStartupProperty.setDisplayName("Connect On Startup");
connectOnStartupProperty.setDisplayName("Connect On Startup");
connectOnStartupProperty.setDefaultValueBoolean(false);
connectOnStartupProperty.setDefaultValueBoolean(false);
addServerProperties(
addServerProperties(
urlProperty,
urlProperty,
passwordProperty,
passwordProperty,
connectOnStartupProperty
connectOnStartupProperty
);
);
}
}
@Override
@Override
public void initAction() throws Exception
public void initAction() throws Exception
{
{
MotherConnection.setPass(getPassword());
MotherConnection.setPass(getPassword());
MotherConnection.setUrl(getURL());
MotherConnection.setUrl(getURL());
MotherConnection.setConnectDisconnectButton(connectDisconnectButton);
MotherConnection.setConnectDisconnectButton(connectDisconnectButton);
connectDisconnectButton.setOnAction(action->{
connectDisconnectButton.setOnAction(action->{
try
try
{
{
if(MotherConnection.getRemoteController() == null)
if(MotherConnection.getRemoteController() == null)
{
{
connect(getURL(), getPassword());
connect(getURL(), getPassword());
}
}
else
else
{
{
MotherConnection.getRemoteController().disconnect();
MotherConnection.getRemoteController().disconnect();
}
}
}
}
catch (Exception e)
catch (Exception e)
{
{
e.printStackTrace();
e.printStackTrace();
}
}
});
});
if(isConnectOnStartup() && firstRun)
if(isConnectOnStartup() && firstRun)
{
{
connect(getURL(), getPassword());
connect(getURL(), getPassword());
}
}
firstRun = false;
firstRun = false;
}
}
private boolean firstRun = true;
private boolean firstRun = true;
private String getURL() throws MinorException
private String getURL() throws MinorException
{
{
return getServerProperties().getSingleProperty("url").getStringValue();
return getServerProperties().getSingleProperty("url").getStringValue();
}
}
private String getPassword() throws MinorException
private String getPassword() throws MinorException
{
{
return getServerProperties().getSingleProperty("pass").getStringValue();
return getServerProperties().getSingleProperty("pass").getStringValue();
}
}
private boolean isConnectOnStartup() throws MinorException
private boolean isConnectOnStartup() throws MinorException
{
{
return getServerProperties().getSingleProperty("connect_on_startup").getBoolValue();
return getServerProperties().getSingleProperty("connect_on_startup").getBoolValue();
}
}
private void connect(String url, String pass)
private void connect(String url, String pass)
{
{
MotherConnection.setPass(pass);
MotherConnection.setPass(pass);
MotherConnection.setUrl(url);
MotherConnection.setUrl(url);
new OBSActionConnectionTask(true, null, null, null);
new OBSActionConnectionTask(true, null, null, null);
}
}
@Override
@Override
public void onShutDown()
public void onShutDown()
{
{
if(MotherConnection.getRemoteController() != null)
if(MotherConnection.getRemoteController() != null)
{
{
MotherConnection.getRemoteController().disconnect();
MotherConnection.getRemoteController().disconnect();
}
}
}
}
}
}
package mother;
package mother;
import mother.motherconnection.MotherConnection;
import com.stream_pi.util.alert.StreamPiAlert;
import com.stream_pi.util.alert.StreamPiAlertType;
import javafx.application.Platform;
import javafx.application.Platform;
import javafx.concurrent.Task;
import javafx.concurrent.Task;
import javafx.scene.control.Button;
import mother.motherconnection.MotherConnection;
import net.twasi.obsremotejava.OBSRemoteController;
import net.twasi.obsremotejava.OBSRemoteController;
import com.stream_pi.util.alert.StreamPiAlert;
import com.stream_pi.util.alert.StreamPiAlertType;
public class OBSActionConnectionTask extends Task<Void>
public class OBSActionConnectionTask extends Task<Void>
{
{
private Runnable onFailToConnectRunnable = null;
private Runnable onFailToConnectRunnable = null;
private Runnable onConnectRunnable = null;
private Runnable onConnectRunnable = null;
private Runnable onDisconnectRunnable = null;
private Runnable onDisconnectRunnable = null;
public OBSActionConnectionTask(boolean runAsync, Runnable onFailToConnectRunnable,
public OBSActionConnectionTask(boolean runAsync, Runnable onFailToConnectRunnable,
Runnable onConnectRunnable, Runnable onDisconnectRunnable)
Runnable onConnectRunnable, Runnable onDisconnectRunnable)
{
{
this.onFailToConnectRunnable = onFailToConnectRunnable;
this.onFailToConnectRunnable = onFailToConnectRunnable;
this.onConnectRunnable = onConnectRunnable;
this.onConnectRunnable = onConnectRunnable;
this.onDisconnectRunnable = onDisconnectRunnable;
this.onDisconnectRunnable = onDisconnectRunnable;
if(runAsync)
if(runAsync)
{
{
new Thread(this).start();
new Thread(this).start();
}
}
else
else
{
{
call();
call();
}
}
}
}
@Override
@Override
protected Void call()
protected Void call()
{
{
try
try
{
{
String url = MotherConnection.getUrl();
String url = MotherConnection.getUrl();
String pass = MotherConnection.getPass();
String pass = MotherConnection.getPass();
setConnectDisconnectButtonDisable(true);
setConnectDisconnectButtonDisable(true);
if(!url.startsWith("ws://"))
if(!url.startsWith("ws://"))
{
{
new StreamPiAlert("Invalid URL","Please fix URL and try again", StreamPiAlertType.ERROR).show();
new StreamPiAlert("Invalid URL","Please fix URL and try again", StreamPiAlertType.ERROR).show();
return null;
return null;
}
}
if(pass.isEmpty() || pass.isBlank())
if(pass.isEmpty() || pass.isBlank())
pass = null;
pass = null;
OBSRemoteController obsRemoteController = new OBSRemoteController(url, false, pass);
OBSRemoteController obsRemoteController = new OBSRemoteController(url, false, pass);
if(obsRemoteController.isFailed())
if(obsRemoteController.isFailed())
{
{
new StreamPiAlert("Unable to Connect to OBS", "Is it even running? Make sure the websocket plugin is installed. Check Credentials too", StreamPiAlertType.ERROR).show();
new StreamPiAlert("Unable to Connect to OBS", "Is it even running? Make sure the websocket plugin is installed. Check Credentials too", StreamPiAlertType.ERROR).show();
}
}
obsRemoteController.registerConnectionFailedCallback(message->{
obsRemoteController.registerConnectionFailedCallback(message->{
setConnectDisconnectButtonText("Connect");
setConnectDisconnectButtonText("Connect");
new StreamPiAlert("Unable to Connect", "Unable to establish connection to WebSocket with provided crendentials\n\n"+
new StreamPiAlert("Unable to Connect", "Unable to establish connection to WebSocket with provided crendentials\n\n"+
"Detailed Error : "+message, StreamPiAlertType.ERROR).show();
"Detailed Error : "+message, StreamPiAlertType.ERROR).show();
MotherConnection.setRemoteController(null);
MotherConnection.setRemoteController(null);
if(onFailToConnectRunnable != null)
if(onFailToConnectRunnable != null)
{
{
onFailToConnectRunnable.run();
onFailToConnectRunnable.run();
onFailToConnectRunnable = null;
onFailToConnectRunnable = null;
}
}
});
});
obsRemoteController.registerDisconnectCallback(()->{
obsRemoteController.registerDisconnectCallback(()->{
setConnectDisconnectButtonText("Connect");
setConnectDisconnectButtonText("Connect");
MotherConnection.setRemoteController(null);
MotherConnection.setRemoteController(null);
if(onDisconnectRunnable != null)
if(onDisconnectRunnable != null)
{
{
onDisconnectRunnable.run();
onDisconnectRunnable.run();
onDisconnectRunnable = null;
onDisconnectRunnable = null;
}
}
});
});
obsRemoteController.registerConnectCallback(onConnect->{
obsRemoteController.registerConnectCallback(onConnect->{
setConnectDisconnectButtonText("Disconnect");
setConnectDisconnectButtonText("Disconnect");
MotherConnection.setRemoteController(obsRemoteController);
MotherConnection.setRemoteController(obsRemoteController);
if(onConnectRunnable != null)
if(onConnectRunnable != null)
{
{
onConnectRunnable.run();
onConnectRunnable.run();
onConnectRunnable = null;
onConnectRunnable = null;
}
}
});
});
}
}
catch (Exception e)
catch (Exception e)
{
{
MotherConnection.showOBSNotRunningError();
MotherConnection.showOBSNotRunningError();
MotherConnection.setRemoteController(null);
MotherConnection.setRemoteController(null);
e.printStackTrace();
e.printStackTrace();
}
}
finally
finally
{
{
setConnectDisconnectButtonDisable(false);
setConnectDisconnectButtonDisable(false);
}
}
return null;
return null;
}
}
private void setConnectDisconnectButtonText(String text)
private void setConnectDisconnectButtonText(String text)
{
{
if(MotherConnection.getConnectDisconnectButton() == null)
if(MotherConnection.getConnectDisconnectButton() == null)
return;
return;
Platform.runLater(()-> MotherConnection.getConnectDisconnectButton().setText(text));
Platform.runLater(()-> MotherConnection.getConnectDisconnectButton().setText(text));
}
}
private void setConnectDisconnectButtonDisable(boolean disable)
private void setConnectDisconnectButtonDisable(boolean disable)
{
{
if(MotherConnection.getConnectDisconnectButton() == null)
if(MotherConnection.getConnectDisconnectButton() == null)
return;
return;
Platform.runLater(()-> MotherConnection.getConnectDisconnectButton().setDisable(disable));
Platform.runLater(()-> MotherConnection.getConnectDisconnectButton().setDisable(disable));
}
}
}
}
package mother.motherconnection;
package mother.motherconnection;
import com.stream_pi.util.alert.StreamPiAlert;
import com.stream_pi.util.alert.StreamPiAlert;
import com.stream_pi.util.alert.StreamPiAlertType;
import com.stream_pi.util.alert.StreamPiAlertType;
import com.stream_pi.util.version.Version;
import com.stream_pi.util.version.Version;
import javafx.scene.control.Button;
import javafx.scene.control.Button;
import mother.OBSActionConnectionTask;
import mother.OBSActionConnectionTask;
import net.twasi.obsremotejava.OBSRemoteController;
import net.twasi.obsremotejava.OBSRemoteController;
import net.twasi.obsremotejava.callbacks.Callback;
import net.twasi.obsremotejava.callbacks.Callback;
import net.twasi.obsremotejava.requests.ResponseBase;
public class MotherConnection
public class MotherConnection
{
{
private static OBSRemoteController obsRemoteController = null;
private static OBSRemoteController obsRemoteController = null;
public static final Version VERSION = new Version(2,0,0);
public static final Version VERSION = new Version(2,0,0);
private static String url = null;
private static String url = null;
private static String pass = null;
private static String pass = null;
private static Button connectDisconnectButton = null;
private static Button connectDisconnectButton = null;
public static void setConnectDisconnectButton(Button connectDisconnectButton)
public static void setConnectDisconnectButton(Button connectDisconnectButton)
{
{
MotherConnection.connectDisconnectButton = connectDisconnectButton;
MotherConnection.connectDisconnectButton = connectDisconnectButton;
}
}
public static Button getConnectDisconnectButton()
public static Button getConnectDisconnectButton()
{
{
return connectDisconnectButton;
return connectDisconnectButton;
}
}
public static void setUrl(String url) {
public static void setUrl(String url) {
MotherConnection.url = url;
MotherConnection.url = url;
}
}
public static void setPass(String pass) {
public static void setPass(String pass) {
MotherConnection.pass = pass;
MotherConnection.pass = pass;
}
}
public static String getUrl() {
public static String getUrl() {
return url;
return url;
}
}
public static String getPass() {
public static String getPass() {
return pass;
return pass;
}
}
public static void connect()
public static void connect()
{
{
connect(true, null, null, null);
connect(true, null, null, null);
}
}
public static void connect(Runnable onConnectRunnable)
public static void connect(Runnable onConnectRunnable)
{
{
connect(true, null, onConnectRunnable, null);
connect(true, null, onConnectRunnable, null);
}
}
public static void connect(boolean runAsync, Runnable onFailToConnectRunnable,
public static void connect(boolean runAsync, Runnable onFailToConnectRunnable,
Runnable onConnectRunnable, Runnable onDisconnectRunnable)
Runnable onConnectRunnable, Runnable onDisconnectRunnable)
{
{
new OBSActionConnectionTask(runAsync, onFailToConnectRunnable,
new OBSActionConnectionTask(runAsync, onFailToConnectRunnable,
onConnectRunnable, onDisconnectRunnable);
onConnectRunnable, onDisconnectRunnable);
}
}
public static OBSRemoteController getRemoteController()
public static OBSRemoteController getRemoteController()
{
{
return obsRemoteController;
return obsRemoteController;
}
}
public static void setRemoteController(OBSRemoteController obsRemoteController)
public static void setRemoteController(OBSRemoteController obsRemoteController)
{
{
MotherConnection.obsRemoteController = obsRemoteController;
MotherConnection.obsRemoteController = obsRemoteController;
}
}
public static Callback getDefaultCallBack(String head, String content)
public static Callback getDefaultCallBack(String head, String content)
{
{
return response ->
return response ->
{
{
if(response.getStatus().equals("error"))
if(response.getStatus().equals("error"))
{
{
new StreamPiAlert(head, content, StreamPiAlertType.ERROR).show();
new StreamPiAlert(head, content, StreamPiAlertType.ERROR).show();
}
}
};
};
}
}
public static void showOBSNotRunningError()
public static void showOBSNotRunningError()
{
{
new StreamPiAlert("Is OBS Connected?",
new StreamPiAlert("Is OBS Connected?",
"It seems there is no connection to OBS, please connect it in Settings", StreamPiAlertType.WARNING)
"It seems there is no connection to OBS, please connect it in Settings", StreamPiAlertType.WARNING)
.show();
.show();
}
}
}
}
package setcurrenttransition;
package setcurrenttransition;
import com.stream_pi.action_api.actionproperty.property.Property;
import com.stream_pi.action_api.actionproperty.property.Property;
import com.stream_pi.action_api.actionproperty.property.Type;
import com.stream_pi.action_api.actionproperty.property.Type;
import com.stream_pi.action_api.externalplugin.NormalAction;
import com.stream_pi.action_api.externalplugin.NormalAction;
import com.stream_pi.util.alert.StreamPiAlert;
import com.stream_pi.util.alert.StreamPiAlert;
import com.stream_pi.util.alert.StreamPiAlertType;
import com.stream_pi.util.alert.StreamPiAlertType;
import com.stream_pi.util.exception.MinorException;
import com.stream_pi.util.exception.MinorException;
import com.stream_pi.util.version.Version;
import mother.motherconnection.MotherConnection;
import mother.motherconnection.MotherConnection;
import net.twasi.obsremotejava.OBSRemoteController;
public class SetCurrentTransition extends NormalAction {
public class SetCurrentTransition extends NormalAction {
public SetCurrentTransition()
public SetCurrentTransition()
{
{
setName("Set Current Transition");
setName("Set Current Transition");
setCategory("OBS");
setCategory("OBS");
setVisibilityInServerSettingsPane(false);
setVisibilityInServerSettingsPane(false);
setAuthor("rnayabed");
setAuthor("rnayabed");
setVersion(MotherConnection.VERSION);
setVersion(MotherConnection.VERSION);
}
}
@Override
@Override
public void initProperties() throws Exception
public void initProperties() throws Exception
{
{
Property currentTransitionProperty = new Property("transition", Type.STRING);
Property currentTransitionProperty = new Property("transition", Type.STRING);
currentTransitionProperty.setDisplayName("Transition Name");
currentTransitionProperty.setDisplayName("Transition Name");
Property autoConnectProperty = new Property("auto_connect", Type.BOOLEAN);
Property autoConnectProperty = new Property("auto_connect", Type.BOOLEAN);
autoConnectProperty.setDefaultValueBoolean(true);
autoConnectProperty.setDefaultValueBoolean(true);
autoConnectProperty.setDisplayName("Auto Connect if not connected");
autoConnectProperty.setDisplayName("Auto Connect if not connected");
addClientProperties(currentTransitionProperty, autoConnectProperty);
addClientProperties(currentTransitionProperty, autoConnectProperty);
}
}
@Override
@Override
public void onActionClicked() throws Exception
public void onActionClicked() throws Exception
{
{
String transition = getClientProperties().getSingleProperty("transition").getStringValue();
String transition = getClientProperties().getSingleProperty("transition").getStringValue();
if(transition.isBlank())
if(transition.isBlank())
{
{
throw new MinorException("Blank Transition Name","No Transition Name specified");
throw new MinorException("Blank Transition Name","No Transition Name specified");
}
}
if (MotherConnection.getRemoteController() == null)
if (MotherConnection.getRemoteController() == null)
{
{
boolean autoConnect = getClientProperties().getSingleProperty(
boolean autoConnect = getClientProperties().getSingleProperty(
"auto_connect"
"auto_connect"
).getBoolValue();
).getBoolValue();
if(autoConnect)
if(autoConnect)
{
{
MotherConnection.connect(()->setTransition(transition));
MotherConnection.connect(()->setTransition(transition));
}
}
else
else
{
{
MotherConnection.showOBSNotRunningError();
MotherConnection.showOBSNotRunningError();
}
}
}
}
else
else
{
{
setTransition(transition);
setTransition(transition);
}
}
}
}
public void setTransition(String transition)
public void setTransition(String transition)
{
{
MotherConnection.getRemoteController().setCurrentTransition(transition, setCurrentTransitionResponse -> {
MotherConnection.getRemoteController().setCurrentTransition(transition, setCurrentTransitionResponse -> {
String status = setCurrentTransitionResponse.getStatus();
String status = setCurrentTransitionResponse.getStatus();
String error = setCurrentTransitionResponse.getError();
String error = setCurrentTransitionResponse.getError();
if(status.equals("error"))
if(status.equals("error"))
{
{
String content;
String content;
if(error.equals("transition does not exist"))
if(error.equals("transition does not exist"))
{
{
content = "Transition "+transition+" does not exist.";
content = "Transition "+transition+" does not exist.";
}
}
else
else
{
{
content = error;
content = error;
}
}
new StreamPiAlert("OBS",content, StreamPiAlertType.ERROR).show();
new StreamPiAlert("OBS",content, StreamPiAlertType.ERROR).show();
}
}
});
});
}
}
}
}
package setmute;
package setmute;
import com.stream_pi.action_api.actionproperty.property.Property;
import com.stream_pi.action_api.actionproperty.property.Property;
import com.stream_pi.action_api.actionproperty.property.Type;
import com.stream_pi.action_api.actionproperty.property.Type;
import com.stream_pi.action_api.externalplugin.NormalAction;
import com.stream_pi.action_api.externalplugin.ToggleAction;
import com.stream_pi.action_api.externalplugin.ToggleAction;
import com.stream_pi.util.alert.StreamPiAlert;
import com.stream_pi.util.alert.StreamPiAlert;
import com.stream_pi.util.alert.StreamPiAlertType;
import com.stream_pi.util.alert.StreamPiAlertType;
import com.stream_pi.util.exception.MinorException;
import com.stream_pi.util.exception.MinorException;
import com.stream_pi.util.version.Version;
import mother.motherconnection.MotherConnection;
import mother.motherconnection.MotherConnection;
import net.twasi.obsremotejava.OBSRemoteController;
public class SetMute extends ToggleAction
public class SetMute extends ToggleAction
{
{
public SetMute()
public SetMute()
{
{
setName("Set Mute");
setName("Set Mute");
setCategory("OBS");
setCategory("OBS");
setVisibilityInServerSettingsPane(false);
setVisibilityInServerSettingsPane(false);
setAuthor("rnayabed");
setAuthor("rnayabed");
setVersion(MotherConnection.VERSION);
setVersion(MotherConnection.VERSION);
}
}
@Override
@Override
public void onToggleOn() throws Exception
public void onToggleOn() throws Exception
{
{
onClicked(true);
onClicked(true);
}
}
@Override
@Override
public void onToggleOff() throws Exception
public void onToggleOff() throws Exception
{
{
onClicked(false);
onClicked(false);
}
}
@Override
@Override
public void initProperties() throws Exception
public void initProperties() throws Exception
{
{
Property sourceProperty = new Property("source", Type.STRING);
Property sourceProperty = new Property("source", Type.STRING);
sourceProperty.setDisplayName("Source");
sourceProperty.setDisplayName("Source");
Property autoConnectProperty = new Property("auto_connect", Type.BOOLEAN);
Property autoConnectProperty = new Property("auto_connect", Type.BOOLEAN);
autoConnectProperty.setDefaultValueBoolean(true);
autoConnectProperty.setDefaultValueBoolean(true);
autoConnectProperty.setDisplayName("Auto Connect if not connected");
autoConnectProperty.setDisplayName("Auto Connect if not connected");
addClientProperties(sourceProperty, autoConnectProperty);
addClientProperties(sourceProperty, autoConnectProperty);
}
}
public void onClicked(boolean mute) throws MinorException
public void onClicked(boolean mute) throws MinorException
{
{
String source = getClientProperties().getSingleProperty("source").getStringValue();
String source = getClientProperties().getSingleProperty("source").getStringValue();
if(source.isBlank())
if(source.isBlank())
{
{
throw new MinorException("Blank Source Name","No Source specified");
throw new MinorException("Blank Source Name","No Source specified");
}
}
if (MotherConnection.getRemoteController() == null)
if (MotherConnection.getRemoteController() == null)
{
{
boolean autoConnect = getClientProperties().getSingleProperty(
boolean autoConnect = getClientProperties().getSingleProperty(
"auto_connect"
"auto_connect"
).getBoolValue();
).getBoolValue();
if(autoConnect)
if(autoConnect)
{
{
MotherConnection.connect(()->setMute(source, mute));
MotherConnection.connect(()->setMute(source, mute));
}
}
else
else
{
{
MotherConnection.showOBSNotRunningError();
MotherConnection.showOBSNotRunningError();
}
}
}
}
else
else
{
{
setMute(source, mute);
setMute(source, mute);
}
}
}
}
public void setMute(String scene, boolean mute)
public void setMute(String scene, boolean mute)
{
{
MotherConnection.getRemoteController().setMute(scene, mute, setMuteResponse -> {
MotherConnection.getRemoteController().setMute(scene, mute, setMuteResponse -> {
String status = setMuteResponse.getStatus();
String status = setMuteResponse.getStatus();
String error = setMuteResponse.getError();
String error = setMuteResponse.getError();
if(status.equals("error"))
if(status.equals("error"))
{
{
String content;
String content;
if(error.equals("source does not exist"))
if(error.equals("source does not exist"))
{
{
content = "Source "+scene+" does not exist.";
content = "Source "+scene+" does not exist.";
}
}
else
else
{
{
content = error;
content = error;
}
}
new StreamPiAlert("OBS",content, StreamPiAlertType.ERROR).show();
new StreamPiAlert("OBS",content, StreamPiAlertType.ERROR).show();
}
}
});
});
}
}
}
}
package setpreviewscene;
package setpreviewscene;
import com.stream_pi.action_api.actionproperty.property.Property;
import com.stream_pi.action_api.actionproperty.property.Property;
import com.stream_pi.action_api.actionproperty.property.Type;
import com.stream_pi.action_api.actionproperty.property.Type;
import com.stream_pi.action_api.externalplugin.NormalAction;
import com.stream_pi.action_api.externalplugin.NormalAction;
import com.stream_pi.util.alert.StreamPiAlert;
import com.stream_pi.util.alert.StreamPiAlert;
import com.stream_pi.util.alert.StreamPiAlertType;
import com.stream_pi.util.alert.StreamPiAlertType;
import com.stream_pi.util.exception.MinorException;
import com.stream_pi.util.exception.MinorException;
import com.stream_pi.util.version.Version;
import mother.motherconnection.MotherConnection;
import mother.motherconnection.MotherConnection;
import net.twasi.obsremotejava.OBSRemoteController;
public class SetPreviewScene extends NormalAction
public class SetPreviewScene extends NormalAction
{
{
public SetPreviewScene()
public SetPreviewScene()
{
{
setName("Set Preview Scene");
setName("Set Preview Scene");
setCategory("OBS");
setCategory("OBS");
setVisibilityInServerSettingsPane(false);
setVisibilityInServerSettingsPane(false);
setAuthor("rnayabed");
setAuthor("rnayabed");
setVersion(MotherConnection.VERSION);
setVersion(MotherConnection.VERSION);
}
}
@Override
@Override
public void initProperties() throws Exception {
public void initProperties() throws Exception {
Property previewSceneProperty = new Property("preview_scene", Type.STRING);
Property previewSceneProperty = new Property("preview_scene", Type.STRING);
previewSceneProperty.setDisplayName("Preview Scene");
previewSceneProperty.setDisplayName("Preview Scene");
Property autoConnectProperty = new Property("auto_connect", Type.BOOLEAN);
Property autoConnectProperty = new Property("auto_connect", Type.BOOLEAN);
autoConnectProperty.setDefaultValueBoolean(true);
autoConnectProperty.setDefaultValueBoolean(true);
autoConnectProperty.setDisplayName("Auto Connect if not connected");
autoConnectProperty.setDisplayName("Auto Connect if not connected");
addClientProperties(previewSceneProperty, autoConnectProperty);
addClientProperties(previewSceneProperty, autoConnectProperty);
}
}
@Override
@Override
public void onActionClicked() throws Exception
public void onActionClicked() throws Exception
{
{
String previewScene = getClientProperties().getSingleProperty("preview_scene").getStringValue();
String previewScene = getClientProperties().getSingleProperty("preview_scene").getStringValue();
if(previewScene.isBlank())
if(previewScene.isBlank())
{
{
throw new MinorException("Blank Preview Scene Name","No Preview Scene Name specified");
throw new MinorException("Blank Preview Scene Name","No Preview Scene Name specified");
}
}
if (MotherConnection.getRemoteController() == null)
if (MotherConnection.getRemoteController() == null)
{
{
boolean autoConnect = getClientProperties().getSingleProperty(
boolean autoConnect = getClientProperties().getSingleProperty(
"auto_connect"
"auto_connect"
).getBoolValue();
).getBoolValue();
if(autoConnect)
if(autoConnect)
{
{
MotherConnection.connect(()->setPreviewScene(previewScene));
MotherConnection.connect(()->setPreviewScene(previewScene));
}
}
else
else
{
{
MotherConnection.showOBSNotRunningError();
MotherConnection.showOBSNotRunningError();
}
}
}
}
else
else
{
{
setPreviewScene(previewScene);
setPreviewScene(previewScene);
}
}
}
}
public void setPreviewScene(String previewScene)
public void setPreviewScene(String previewScene)
{
{
MotherConnection.getRemoteController().setPreviewScene(previewScene, setPreviewSceneResponse -> {
MotherConnection.getRemoteController().setPreviewScene(previewScene, setPreviewSceneResponse -> {
String status = setPreviewSceneResponse.getStatus();
String status = setPreviewSceneResponse.getStatus();
String error = setPreviewSceneResponse.getError();
String error = setPreviewSceneResponse.getError();
if(status.equals("error"))
if(status.equals("error"))
{
{
String content;
String content;
if(error.equals("scene does not exist"))
if(error.equals("scene does not exist"))
{
{
content = "Preview Scene "+previewScene+" does not exist.";
content = "Preview Scene "+previewScene+" does not exist.";
}
}
else
else
{
{
content = error;
content = error;
}
}
new StreamPiAlert("OBS",content, StreamPiAlertType.ERROR).show();
new StreamPiAlert("OBS",content, StreamPiAlertType.ERROR).show();
}
}
});
});
}
}
}
}
package setrecording;
package setrecording;
import java.util.ArrayList;
import com.stream_pi.action_api.actionproperty.property.Property;
import com.stream_pi.action_api.actionproperty.property.Property;
import com.stream_pi.action_api.actionproperty.property.Type;
import com.stream_pi.action_api.actionproperty.property.Type;
import com.stream_pi.action_api.externalplugin.NormalAction;
import com.stream_pi.action_api.externalplugin.ToggleAction;
import com.stream_pi.action_api.externalplugin.ToggleAction;
import com.stream_pi.util.alert.StreamPiAlert;
import com.stream_pi.util.alert.StreamPiAlert;
import com.stream_pi.util.alert.StreamPiAlertType;
import com.stream_pi.util.alert.StreamPiAlertType;
import com.stream_pi.util.exception.MinorException;
import com.stream_pi.util.exception.MinorException;
import com.stream_pi.util.version.Version;
import mother.motherconnection.MotherConnection;
import mother.motherconnection.MotherConnection;
import net.twasi.obsremotejava.OBSRemoteController;
public class SetRecording extends ToggleAction
public class SetRecording extends ToggleAction
{
{
public SetRecording() {
public SetRecording() {
setName("Set Recording");
setName("Set Recording");
setCategory("OBS");
setCategory("OBS");
setVisibilityInServerSettingsPane(false);
setVisibilityInServerSettingsPane(false);
setAuthor("rnayabed");
setAuthor("rnayabed");
setVersion(MotherConnection.VERSION);
setVersion(MotherConnection.VERSION);
}
}
@Override
@Override
public void onToggleOn() throws Exception
public void onToggleOn() throws Exception
{
{
onClicked(true);
onClicked(true);
}
}
@Override
@Override
public void onToggleOff() throws Exception
public void onToggleOff() throws Exception
{
{
onClicked(false);
onClicked(false);
}
}
@Override
@Override
public void initProperties() throws Exception
public void initProperties() throws Exception
{
{
Property autoConnectProperty = new Property("auto_connect", Type.BOOLEAN);
Property autoConnectProperty = new Property("auto_connect", Type.BOOLEAN);
autoConnectProperty.setDefaultValueBoolean(true);
autoConnectProperty.setDefaultValueBoolean(true);
autoConnectProperty.setDisplayName("Auto Connect if not connected");
autoConnectProperty.setDisplayName("Auto Connect if not connected");
addClientProperties(autoConnectProperty);
addClientProperties(autoConnectProperty);
}
}
public void onClicked(boolean record) throws MinorException
public void onClicked(boolean record) throws MinorException
{
{
if (MotherConnection.getRemoteController() == null)
if (MotherConnection.getRemoteController() == null)
{
{
boolean autoConnect = getClientProperties().getSingleProperty(
boolean autoConnect = getClientProperties().getSingleProperty(
"auto_connect"
"auto_connect"
).getBoolValue();
).getBoolValue();
if(autoConnect)
if(autoConnect)
{
{
MotherConnection.connect(()->setRecording(record));
MotherConnection.connect(()->setRecording(record));
}
}
else
else
{
{
MotherConnection.showOBSNotRunningError();
MotherConnection.showOBSNotRunningError();
}
}
}
}
else
else
{
{
setRecording(record);
setRecording(record);
}
}
}
}
public void setRecording(boolean recording)
public void setRecording(boolean recording)
{
{
if(recording)
if(recording)
{
{
MotherConnection.getRemoteController().startRecording(setRecordingResponse -> {
MotherConnection.getRemoteController().startRecording(setRecordingResponse -> {
String status = setRecordingResponse.getStatus();
String status = setRecordingResponse.getStatus();
String error = setRecordingResponse.getError();
String error = setRecordingResponse.getError();
errorHandler(status, error);
errorHandler(status, error);
});
});
}
}
else
else
{
{
MotherConnection.getRemoteController().stopRecording(setRecordingResponse -> {
MotherConnection.getRemoteController().stopRecording(setRecordingResponse -> {
String status = setRecordingResponse.getStatus();
String status = setRecordingResponse.getStatus();
String error = setRecordingResponse.getError();
String error = setRecordingResponse.getError();
errorHandler(status, error);
errorHandler(status, error);
});
});
}
}
}
}
private void errorHandler(String status, String error)
private void errorHandler(String status, String error)
{
{
if(status.equals("error"))
if(status.equals("error"))
{
{
new StreamPiAlert("OBS",error, StreamPiAlertType.ERROR).show();
new StreamPiAlert("OBS",error, StreamPiAlertType.ERROR).show();
}
}
}
}
}
}
# Twitch Chat Integration
# Twitch Chat Integration
The first step is to acquire an [OAuth token](https://twitchapps.com/tmi/), the generated OAuth token should look something like `oauth:xxxxx`.
The first step is to acquire an [OAuth token](https://twitchapps.com/tmi/), the generated OAuth token should look something like `oauth:xxxxx`.
Then in the Stream-Pi Server's Plugin page you will need to enter your Twitch username with the generated OAuth token then click on `Save Twitch Chat credentials` button.
Then in the Stream-Pi Server's Plugin page you will need to enter your Twitch username with the generated OAuth token then click on `Save Twitch Chat credentials` button.
You should then be able to use the pre-bundled Twitch chat actions.
You should then be able to use the pre-bundled Twitch chat actions.
## Supported actions (see [Chat Commands](https://help.twitch.tv/s/article/chat-commands?language=en_US) for full documentation)
## Supported actions (see [Twitch Chat Commands](https://help.twitch.tv/s/article/chat-commands?language=en_US) for full documentation)
### All Users
### All Users
- Set username color
- Set username color
- Normal users can choose between Blue, Coral, DodgerBlue, SpringGreen, YellowGreen, Green, OrangeRed, Red, GoldenRod, HotPink, CadetBlue, SeaGreen, Chocolate, BlueViolet, and Firebrick. Twitch Turbo users can use any Hex value (i.e: #000000).
- Normal users can choose between Blue, Coral, DodgerBlue, SpringGreen, YellowGreen, Green, OrangeRed, Red, GoldenRod, HotPink, CadetBlue, SeaGreen, Chocolate, BlueViolet, and Firebrick. Twitch Turbo users can use any Hex value (i.e: #000000).
- Send channel message
- Send channel message
- Whisper (send user message)
- Whisper (send user message)
### Broadcaster and Mods
### Broadcaster and Mods
- Clear chat
- Clear chat
### Broadcaster and channel editors
### Broadcaster and channel editors
- Run commercial
- Run commercial
- Host
- Host
- Unhost
- Unhost
- Raid
- Raid
- Unraid
- Unraid
- Add stream marker
- Add stream marker
- Toggle slow mode
- Toggle subs-only mode
### TODO
### TODO
- Toggle slow mode
- Toggle followers-only mode
- Toggle followers-only mode
- Toggle subs-only mode
- Toggle emotes-only mode
## Running locally
## Running locally
Copy the `Java-Twirk` and the `twitch-xxx-action` jar files from the `PreBuiltPlugins` directory to your Stream-Pi server plugins' directory.
Copy the `Java-Twirk` from the `Dependencies` directory and the `twitch-xxx-action` jar files from the `PreBuiltPlugins` directory to your Stream-Pi server plugins' directory.
package com.stream_pi.twitteraction;
package com.stream_pi.twitteraction;
import com.stream_pi.action_api.actionproperty.property.ControlType;
import com.stream_pi.action_api.actionproperty.property.ControlType;
import com.stream_pi.action_api.actionproperty.property.Property;
import com.stream_pi.action_api.actionproperty.property.Property;
import com.stream_pi.action_api.actionproperty.property.Type;
import com.stream_pi.action_api.actionproperty.property.Type;
import com.stream_pi.action_api.externalplugin.NormalAction;
import com.stream_pi.action_api.externalplugin.NormalAction;
import com.stream_pi.util.alert.StreamPiAlert;
import com.stream_pi.util.alert.StreamPiAlert;
import com.stream_pi.util.alert.StreamPiAlertListener;
import com.stream_pi.util.alert.StreamPiAlertListener;
import com.stream_pi.util.alert.StreamPiAlertType;
import com.stream_pi.util.alert.StreamPiAlertType;
import com.stream_pi.util.uihelper.HBoxInputBox;
import com.stream_pi.util.uihelper.HBoxInputBox;
import com.stream_pi.util.version.Version;
import com.stream_pi.util.version.Version;
import javafx.application.Platform;
import javafx.application.Platform;
import javafx.beans.value.ChangeListener;
import javafx.beans.value.ObservableValue;
import javafx.concurrent.Task;
import javafx.concurrent.Task;
import javafx.scene.control.*;
import javafx.scene.control.Button;
import javafx.scene.control.Label;
import javafx.scene.control.TextArea;
import javafx.scene.control.TextField;
import javafx.scene.layout.HBox;
import javafx.scene.layout.HBox;
import javafx.scene.layout.VBox;
import javafx.scene.layout.VBox;
import twitter4j.Status;
import twitter4j.Twitter;
import twitter4j.Twitter;
import twitter4j.TwitterException;
import twitter4j.TwitterFactory;
import twitter4j.TwitterFactory;
import twitter4j.auth.AccessToken;
import twitter4j.auth.AccessToken;
import twitter4j.auth.RequestToken;
import twitter4j.auth.RequestToken;
import twitter4j.conf.ConfigurationBuilder;
import twitter4j.conf.ConfigurationBuilder;
import java.net.URI;
import java.util.Random;
public class TwitterAction extends NormalAction {
public class TwitterAction extends NormalAction {
Button loginAsNewUserButton, logoutButton;
Button loginAsNewUserButton, logoutButton;
public TwitterAction()
public TwitterAction()
{
{
setName("Tweet");
setName("Tweet");
setCategory("Twitter");
setCategory("Twitter");
setAuthor("rnayabed");
setAuthor("rnayabed");
setServerButtonGraphic("fab-twitter");
setServerButtonGraphic("fab-twitter");
setHelpLink("https://github.com/stream-pi/essentialactions");
setHelpLink("https://github.com/stream-pi/essentialactions");
setVersion(new Version(1,0,1));
setVersion(new Version(1,0,1));
loginAsNewUserButton = new Button("Login as new user");
loginAsNewUserButton = new Button("Login as new user");
loginAsNewUserButton.setOnAction(event-> new Thread(new Task<Void>() {
loginAsNewUserButton.setOnAction(event-> new Thread(new Task<Void>() {
@Override
@Override
protected Void call()
protected Void call()
{
{
try {
try {
Platform.runLater(()->{
Platform.runLater(()->{
loginAsNewUserButton.setDisable(true);
loginAsNewUserButton.setDisable(true);
logoutButton.setDisable(true);
logoutButton.setDisable(true);
});
});
loginAsNewUser();
loginAsNewUser();
} catch (Exception e) {
} catch (Exception e) {
Platform.runLater(()-> {
Platform.runLater(()-> {
Platform.runLater(()->{
Platform.runLater(()->{
loginAsNewUserButton.setDisable(false);
loginAsNewUserButton.setDisable(false);
logoutButton.setDisable(false);
logoutButton.setDisable(false);
});
});
new StreamPiAlert(e.getMessage(), StreamPiAlertType.ERROR).show();
new StreamPiAlert(e.getMessage(), StreamPiAlertType.ERROR).show();
});
});
e.printStackTrace();
e.printStackTrace();
}
}
return null;
return null;
}
}
}).start());
}).start());
logoutButton = new Button("Logout");
logoutButton = new Button("Logout");
logoutButton.setOnAction(event-> new Thread(new Task<Void>() {
logoutButton.setOnAction(event-> new Thread(new Task<Void>() {
@Override
@Override
protected Void call()
protected Void call()
{
{
try {
try {
Platform.runLater(()->{
Platform.runLater(()->{
loginAsNewUserButton.setDisable(false);
loginAsNewUserButton.setDisable(false);
logoutButton.setDisable(false);
logoutButton.setDisable(false);
});
});
logout();
logout();
} catch (Exception e) {
} catch (Exception e) {
Platform.runLater(()-> {
Platform.runLater(()-> {
Platform.runLater(()->{
Platform.runLater(()->{
loginAsNewUserButton.setDisable(false);
loginAsNewUserButton.setDisable(false);
logoutButton.setDisable(false);
logoutButton.setDisable(false);
});
});
new StreamPiAlert(e.getMessage(), StreamPiAlertType.ERROR).show();
new StreamPiAlert(e.getMessage(), StreamPiAlertType.ERROR).show();
});
});
e.printStackTrace();
e.printStackTrace();
}
}
return null;
return null;
}
}
}).start());
}).start());
setServerSettingsButtonBar(loginAsNewUserButton, logoutButton);
setServerSettingsButtonBar(loginAsNewUserButton, logoutButton);
}
}
@Override
@Override
public void initProperties() throws Exception
public void initProperties() throws Exception
{
{
Property oAuthConsumerKey = new Property("consumer_key", Type.STRING);
Property oAuthConsumerKey = new Property("consumer_key", Type.STRING);
oAuthConsumerKey.setDisplayName("API Key");
oAuthConsumerKey.setDisplayName("API Key");
Property oAuthConsumerKeySecret = new Property("consumer_key_secret", Type.STRING);
Property oAuthConsumerKeySecret = new Property("consumer_key_secret", Type.STRING);
oAuthConsumerKeySecret.setControlType(ControlType.TEXT_FIELD_MASKED);
oAuthConsumerKeySecret.setControlType(ControlType.TEXT_FIELD_MASKED);
oAuthConsumerKeySecret.setDisplayName("API Key Secret");
oAuthConsumerKeySecret.setDisplayName("API Key Secret");
Property oAuthAccessToken = new Property("access_token", Type.STRING);
Property oAuthAccessToken = new Property("access_token", Type.STRING);
oAuthAccessToken.setDisplayName("Access Token");
oAuthAccessToken.setDisplayName("Access Token");
oAuthAccessToken.setVisible(false);
oAuthAccessToken.setVisible(false);
Property oAuthAccessTokenSecret = new Property("access_token_secret", Type.STRING);
Property oAuthAccessTokenSecret = new Property("access_token_secret", Type.STRING);
oAuthAccessTokenSecret.setDisplayName("Access Token Secret");
oAuthAccessTokenSecret.setDisplayName("Access Token Secret");
oAuthAccessTokenSecret.setVisible(false);
oAuthAccessTokenSecret.setVisible(false);
addServerProperties(
addServerProperties(
oAuthConsumerKey,
oAuthConsumerKey,
oAuthConsumerKeySecret,
oAuthConsumerKeySecret,
oAuthAccessToken,
oAuthAccessToken,
oAuthAccessTokenSecret
oAuthAccessTokenSecret
);
);
Property toBeTweeted = new Property("tweet", Type.STRING);
Property toBeTweeted = new Property("tweet", Type.STRING);
toBeTweeted.setDisplayName("Tweet");
toBeTweeted.setDisplayName("Tweet");
toBeTweeted.setDefaultValueStr("Hello From Stream-Pi!");
toBeTweeted.setDefaultValueStr("Hello From Stream-Pi!");
toBeTweeted.setCanBeBlank(false);
toBeTweeted.setCanBeBlank(false);
addClientProperties(
addClientProperties(
toBeTweeted
toBeTweeted
);
);
}
}
public void loginAsNewUser() throws Exception
public void loginAsNewUser() throws Exception
{
{
logout();
logout();
getAuthToken();
getAuthToken();
}
}
public void logout() throws Exception
public void logout() throws Exception
{
{
setNewTwitterConfig(
setNewTwitterConfig(
getServerProperties().getSingleProperty("consumer_key").getStringValue(),
getServerProperties().getSingleProperty("consumer_key").getStringValue(),
getServerProperties().getSingleProperty("consumer_key_secret").getStringValue(),
getServerProperties().getSingleProperty("consumer_key_secret").getStringValue(),
null,null
null,null
);
);
}
}
public void getAuthToken() throws Exception {
public void getAuthToken() throws Exception {
RequestToken requestToken = tf.getInstance().getOAuthRequestToken();
RequestToken requestToken = tf.getInstance().getOAuthRequestToken();
String cancel = "Cancel";
String cancel = "Cancel";
String login = "Log In";
String login = "Log In";
TextArea authURLTextArea = new TextArea(requestToken.getAuthorizationURL());
TextArea authURLTextArea = new TextArea(requestToken.getAuthorizationURL());
authURLTextArea.setEditable(false);
authURLTextArea.setEditable(false);
TextField pinTextField = new TextField();
TextField pinTextField = new TextField();
HBox textBox = new HBoxInputBox("PIN", pinTextField);
HBox textBox = new HBoxInputBox("PIN", pinTextField);
Platform.runLater(()->{
Platform.runLater(()->{
try
try
{
{
StreamPiAlert alert = new StreamPiAlert("Authorise App", StreamPiAlertType.INFORMATION, cancel, login);
StreamPiAlert alert = new StreamPiAlert("Authorise App", StreamPiAlertType.INFORMATION, cancel, login);
VBox vBox = new VBox(new Label("Go the following Link below, authorise app and then enter the PIN Below"), authURLTextArea, textBox);
VBox vBox = new VBox(new Label("Go the following Link below, authorise app and then enter the PIN Below"), authURLTextArea, textBox);
vBox.setSpacing(5.0);
vBox.setSpacing(5.0);
alert.setAlertContent(vBox);
alert.setAlertContent(vBox);
alert.show();
alert.show();
alert.setOnClicked(new StreamPiAlertListener(){
alert.setOnClicked(new StreamPiAlertListener(){
@Override
@Override
public void onClick(String buttonClicked) {
public void onClick(String buttonClicked) {
// TODO Auto-generated method stub
// TODO Auto-generated method stub
try
try
{
{
if(buttonClicked.equals(login))
if(buttonClicked.equals(login))
{
{
AccessToken accessToken = tf.getInstance().getOAuthAccessToken(requestToken, pinTextField.getText());
AccessToken accessToken = tf.getInstance().getOAuthAccessToken(requestToken, pinTextField.getText());
getServerProperties().getSingleProperty("access_token").setStringValue(accessToken.getToken());
getServerProperties().getSingleProperty("access_token").setStringValue(accessToken.getToken());
getServerProperties().getSingleProperty("access_token_secret").setStringValue(accessToken.getTokenSecret());
getServerProperties().getSingleProperty("access_token_secret").setStringValue(accessToken.getTokenSecret());
saveServerProperties();
saveServerProperties();
initAction();
initAction();
new StreamPiAlert("Success", "Login Successful!", StreamPiAlertType.INFORMATION).show();
new StreamPiAlert("Success", "Login Successful!", StreamPiAlertType.INFORMATION).show();
}
}
else
else
{
{
initAction();
initAction();
}
}
}
}
catch (Exception e)
catch (Exception e)
{
{
new StreamPiAlert(e.getMessage(), StreamPiAlertType.ERROR).show();
new StreamPiAlert(e.getMessage(), StreamPiAlertType.ERROR).show();
e.printStackTrace();
e.printStackTrace();
}
}
}
}
});
});
}
}
catch (Exception e)
catch (Exception e)
{
{
new StreamPiAlert(e.getMessage(), StreamPiAlertType.ERROR).show();
new StreamPiAlert(e.getMessage(), StreamPiAlertType.ERROR).show();
e.printStackTrace();
e.printStackTrace();
}
}
finally
finally
{
{
loginAsNewUserButton.setDisable(false);
loginAsNewUserButton.setDisable(false);
}
}
});
});
}
}
TwitterFactory tf;
TwitterFactory tf;
@Override
@Override
public void initAction() throws Exception {
public void initAction() throws Exception {
//System.setProperty("twitter4j.http.useSSL", "true");
//System.setProperty("twitter4j.http.useSSL", "true");
setNewTwitterConfig(
setNewTwitterConfig(
getServerProperties().getSingleProperty("consumer_key").getStringValue(),
getServerProperties().getSingleProperty("consumer_key").getStringValue(),
getServerProperties().getSingleProperty("consumer_key_secret").getStringValue(),
getServerProperties().getSingleProperty("consumer_key_secret").getStringValue(),
getServerProperties().getSingleProperty("access_token").getStringValue(),
getServerProperties().getSingleProperty("access_token").getStringValue(),
getServerProperties().getSingleProperty("access_token_secret").getStringValue()
getServerProperties().getSingleProperty("access_token_secret").getStringValue()
);
);
}
}
public void setNewTwitterConfig(String consumerKey, String consumerKeySecret, String accessToken, String accessTokenSecret)
public void setNewTwitterConfig(String consumerKey, String consumerKeySecret, String accessToken, String accessTokenSecret)
{
{
ConfigurationBuilder cb = new ConfigurationBuilder();
ConfigurationBuilder cb = new ConfigurationBuilder();
cb.setDebugEnabled(true)
cb.setDebugEnabled(true)
.setOAuthConsumerKey(consumerKey)
.setOAuthConsumerKey(consumerKey)
.setOAuthConsumerSecret(consumerKeySecret)
.setOAuthConsumerSecret(consumerKeySecret)
.setOAuthAccessToken(accessToken)
.setOAuthAccessToken(accessToken)
.setOAuthAccessTokenSecret(accessTokenSecret);
.setOAuthAccessTokenSecret(accessTokenSecret);
tf = new TwitterFactory(cb.build());
tf = new TwitterFactory(cb.build());
}
}
@Override
@Override
public void onActionClicked() throws Exception {
public void onActionClicked() throws Exception {
Twitter twitter = tf.getInstance();
Twitter twitter = tf.getInstance();
twitter.updateStatus(getClientProperties().getSingleProperty("tweet").getStringValue());
twitter.updateStatus(getClientProperties().getSingleProperty("tweet").getStringValue());
}
}
/*public String addRandomBlank(String value)
/*public String addRandomBlank(String value)
{
{
return value+("⠀".repeat(new Random().nextInt(100)));
return value+("⠀".repeat(new Random().nextInt(100)));
}*/
}*/
@Override
@Override
public void onShutDown() throws Exception {
public void onShutDown() throws Exception {
// TODO Auto-generated method stub
// TODO Auto-generated method stub
}
}
}
}