Skip to content

Commit

Permalink
split stream updates from layout updates.
Browse files Browse the repository at this point in the history
gave update staff button.
auto refresh layouts on obs.
  • Loading branch information
KonoTyran committed Sep 19, 2023
1 parent f8c185c commit 4785261
Show file tree
Hide file tree
Showing 6 changed files with 90 additions and 25 deletions.
2 changes: 1 addition & 1 deletion pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@

<groupId>com.alttprleague</groupId>
<artifactId>restreamtool</artifactId>
<version>3.1</version>
<version>3.3</version>

<build>
<plugins>
Expand Down
63 changes: 49 additions & 14 deletions src/main/java/com/alttprleague/LeagueRestreamTool.java
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ public class LeagueRestreamTool {

public static void main(String[] args) throws IOException {
var restreamTool = new LeagueRestreamTool();
window = new JFrame("League Restream Tool V3.1");
window = new JFrame("League Restream Tool V3.3");
URL iconURL = LeagueRestreamTool.class.getResource("/LeagueLogo.png");
window.setIconImage(ImageIO.read(iconURL));
window.setContentPane(restreamTool.pMain);
Expand Down Expand Up @@ -248,6 +248,10 @@ private Process startLink(String streamFrom, int port, Console console, boolean
}

private void fetchChannel(String channelName) {
fetchChannel(channelName, true);
}

private void fetchChannel(String channelName, boolean updateStreams) {
try {
var request = HttpRequest.newBuilder()
.uri(URI.create("https://alttprleague.com/api/restream/?channel="+ channelName))
Expand All @@ -256,28 +260,42 @@ private void fetchChannel(String channelName) {

httpClient.sendAsync(request, HttpResponse.BodyHandlers.ofString())
.thenApply(HttpResponse::body)
.thenAccept(this::ProcessWebsiteResponse);
.thenAccept((r) -> ProcessWebsiteResponse(r, updateStreams));
}
catch (Exception e) {
consoleTopLeft.appendError("Error while fetching restream data from League website.");
consoleTopLeft.appendError("Reason: " + e.getLocalizedMessage());
}
}

private void ProcessWebsiteResponse(String json) {
try {
private void ProcessWebsiteResponse(String json, boolean updateStreams) {
var gson = new Gson();
var channel = gson.fromJson(json, Channel.class);
if(!channel.error.isBlank()) {
channel = gson.fromJson(json, Channel.class);
if (!channel.error.isBlank()) {
consoleTopLeft.appendError(channel.error);
return;
}
if(channel.episode == null) {
consoleTopLeft.appendError("No episode loaded on Restreamer Dashboard for "+channel.twitch_name+".");
if (channel.episode == null) {
consoleTopLeft.appendError("No episode loaded on Restreamer Dashboard for " + channel.twitch_name + ".");
return;
}

this.channel = channel;
updateLayouts();
if(updateStreams)
updateStreams();
}

private void updateStreams() {
startStreamLink(Screen.TOP_LEFT,channel.episode.players[0].streaming_from);
startStreamLink(Screen.TOP_RIGHT,channel.episode.players[1].streaming_from);
if(channel.episode.players.length == 4) {
startStreamLink(Screen.BOTTOM_LEFT,channel.episode.players[2].streaming_from);
startStreamLink(Screen.BOTTOM_RIGHT,channel.episode.players[3].streaming_from);
}
}

private void updateLayouts() {

btnStreamKey.setEnabled(true);
obsRelay.setStreamKey(channel.stream_key);

Expand Down Expand Up @@ -305,7 +323,6 @@ private void ProcessWebsiteResponse(String json) {
}

// LEFT TEAM PLAYER 1
startStreamLink(Screen.TOP_LEFT,channel.episode.players[0].streaming_from);
preRaceTemplate.getElementById("p1_logo").attr("src",channel.episode.players[0].logo_url);
//preRaceTemplate.getElementById("p1_sprite").attr("src",channel.episode.players[0].sprite_url);
preRaceTemplate.getElementById("p1_name").text(channel.episode.players[0].name);
Expand All @@ -316,7 +333,6 @@ private void ProcessWebsiteResponse(String json) {

// LEFT TEAM PLAYER 2
if(channel.episode.players.length >= 3) {
startStreamLink(Screen.BOTTOM_LEFT,channel.episode.players[2].streaming_from);
preRaceTemplate.getElementById("p3_logo").attr("src",channel.episode.players[2].logo_url);
//preRaceTemplate.getElementById("p3_sprite").attr("src",channel.episode.players[2].sprite_url);
preRaceTemplate.getElementById("p3_name").text(channel.episode.players[2].name);
Expand All @@ -339,7 +355,6 @@ private void ProcessWebsiteResponse(String json) {


// RIGHT TEAM PLAYER 1
startStreamLink(Screen.TOP_RIGHT,channel.episode.players[1].streaming_from);
preRaceTemplate.getElementById("p2_logo").attr("src",channel.episode.players[1].logo_url);
//preRaceTemplate.getElementById("p2_sprite").attr("src",channel.episode.players[1].sprite_url);
preRaceTemplate.getElementById("p2_name").text(channel.episode.players[1].name);
Expand All @@ -349,7 +364,6 @@ private void ProcessWebsiteResponse(String json) {

// RIGHT TEAM PLAYER 2
if(channel.episode.players.length >= 4) {
startStreamLink(Screen.BOTTOM_RIGHT,channel.episode.players[3].streaming_from);
preRaceTemplate.getElementById("p4_logo").attr("src",channel.episode.players[3].logo_url);
//preRaceTemplate.getElementById("p4_sprite").attr("src",channel.episode.players[3].sprite_url);
preRaceTemplate.getElementById("p4_name").text(channel.episode.players[3].name);
Expand All @@ -362,9 +376,12 @@ private void ProcessWebsiteResponse(String json) {
preRaceTemplate.getElementById("stage").text(channel.episode.stage);
preRaceTemplate.getElementById("mode").text(channel.episode.mode);
preRaceTemplate.getElementById("open").text(channel.episode.season.open ? "Open":"Invitational");

if(channel.episode.is_playoff && (channel.episode.background.toLowerCase().contains("power") || channel.episode.background.toLowerCase().contains("game4"))) {
raceTemplate.getElementById("mode").removeClass("hidden");
raceTemplate.getElementById("mode").text(channel.episode.mode);
} else {
raceTemplate.getElementById("mode").remove();
}


Expand Down Expand Up @@ -408,6 +425,9 @@ private void ProcessWebsiteResponse(String json) {
cardContainer.appendChild(scheduleCard);

for (Division division : channel.divisions) {
if(division.teams == null){
division.teams = new Team[0];
}
ArrayList<Team> teams = new ArrayList<>(Arrays.asList(division.teams));
teams.sort(Comparator.comparingInt(team -> team.points));
Collections.reverse(teams);
Expand All @@ -429,6 +449,7 @@ private void ProcessWebsiteResponse(String json) {
cardContainer.appendChild(standingsCard);
}

try {
cardContainer.child(0).addClass("active");

FileWriter raceOut = new FileWriter(new File(baseDir,"RaceLayout.html"));
Expand All @@ -453,6 +474,7 @@ private void ProcessWebsiteResponse(String json) {
playlist.close();


obsRelay.reloadLayout();
} catch (IOException e) {
e.printStackTrace();
consoleTopLeft.appendError("Error Writing Files");
Expand Down Expand Up @@ -482,6 +504,7 @@ private void fetchRaceTimeData(String roomURL) {
FileWriter timeOut = new FileWriter(new File(baseDir, "PreRaceLayout.html"));
timeOut.write(doc.outerHtml());
timeOut.close();
obsRelay.reloadLayout();
} catch (IOException e) {
consoleTopLeft.appendError("Error updating layout with race start time.");
}
Expand Down Expand Up @@ -599,6 +622,10 @@ private void miOBSSettings(ActionEvent e) {
panel.setVisible(true);
}

private void ReloadStaff(ActionEvent e) {
fetchChannel(channel.twitch_name, false);
}

private enum Screen {
TOP_LEFT,TOP_RIGHT,BOTTOM_LEFT,BOTTOM_RIGHT
}
Expand Down Expand Up @@ -632,6 +659,7 @@ private void initComponents() {
obsStatus = new StatusLight();
btnOBSConnect = new JButton();
btnOBSSaveCrop = new JButton();
btnReloadStaff = new JButton();

//======== pMain ========
{
Expand Down Expand Up @@ -777,7 +805,8 @@ private void initComponents() {
"insets 0,hidemode 3",
// columns
"[fill]" +
"[grow,fill]",
"[532,grow,fill]" +
"[right]",
// rows
"[]"));

Expand All @@ -801,6 +830,11 @@ public void mouseClicked(MouseEvent e) {
btnOBSSaveCrop.setEnabled(false);
btnOBSSaveCrop.addActionListener(e -> btnOBSSaveCrop(e));
pUtil.add(btnOBSSaveCrop, "cell 0 0");

//---- btnReloadStaff ----
btnReloadStaff.setText("Reload Staff");
btnReloadStaff.addActionListener(e -> ReloadStaff(e));
pUtil.add(btnReloadStaff, "cell 2 0");
}
pBody.add(pUtil, "cell 0 2 6 1");
}
Expand Down Expand Up @@ -837,5 +871,6 @@ public void mouseClicked(MouseEvent e) {
private StatusLight obsStatus;
private JButton btnOBSConnect;
private JButton btnOBSSaveCrop;
private JButton btnReloadStaff;
// JFormDesigner - End of variables declaration //GEN-END:variables @formatter:on
}
11 changes: 9 additions & 2 deletions src/main/java/com/alttprleague/LeagueRestreamTool.jfd
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
JFDML JFormDesigner: "8.0.0.0.194" Java: "17.0.4.1" encoding: "UTF-8"
JFDML JFormDesigner: "8.1.1.0.298" Java: "17.0.8" encoding: "UTF-8"

new FormModel {
contentType: "form/swing"
Expand Down Expand Up @@ -141,7 +141,7 @@ new FormModel {
} )
add( new FormContainer( "javax.swing.JPanel", new FormLayoutManager( class net.miginfocom.swing.MigLayout ) {
"$layoutConstraints": "insets 0,hidemode 3"
"$columnConstraints": "[fill][grow,fill]"
"$columnConstraints": "[fill][532,grow,fill][right]"
"$rowConstraints": "[]"
} ) {
name: "pUtil"
Expand All @@ -167,6 +167,13 @@ new FormModel {
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
"value": "cell 0 0"
} )
add( new FormComponent( "javax.swing.JButton" ) {
name: "btnReloadStaff"
"text": "Reload Staff"
addEvent( new FormEvent( "java.awt.event.ActionListener", "actionPerformed", "ReloadStaff", true ) )
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
"value": "cell 2 0"
} )
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
"value": "cell 0 2 6 1"
} )
Expand Down
19 changes: 15 additions & 4 deletions src/main/java/com/alttprleague/OBSClient.kt
Original file line number Diff line number Diff line change
Expand Up @@ -7,18 +7,21 @@ import io.obswebsocket.community.client.OBSRemoteController
import io.obswebsocket.community.client.WebSocketCloseCode
import io.obswebsocket.community.client.listener.lifecycle.ReasonThrowable
import io.obswebsocket.community.client.message.event.sceneitems.SceneItemTransformChangedEvent
import io.obswebsocket.community.client.message.request.Request
import io.obswebsocket.community.client.message.request.Request.Data
import io.obswebsocket.community.client.message.request.inputs.PressInputPropertiesButtonRequest
import io.obswebsocket.community.client.message.request.ui.GetStudioModeEnabledRequest
import io.obswebsocket.community.client.message.response.RequestResponse
import io.obswebsocket.community.client.message.response.config.SetStreamServiceSettingsResponse
import io.obswebsocket.community.client.message.response.inputs.PressInputPropertiesButtonResponse
import io.obswebsocket.community.client.message.response.sceneitems.GetGroupSceneItemListResponse
import io.obswebsocket.community.client.message.response.sceneitems.GetSceneItemListResponse
import io.obswebsocket.community.client.message.response.sceneitems.GetSceneItemTransformResponse
import io.obswebsocket.community.client.message.response.sceneitems.SetSceneItemTransformResponse
import io.obswebsocket.community.client.message.response.scenes.GetGroupListResponse
import io.obswebsocket.community.client.message.response.scenes.GetSceneListResponse
import io.obswebsocket.community.client.message.response.ui.GetStudioModeEnabledResponse
import org.slf4j.LoggerFactory
import java.util.*
import kotlin.collections.HashMap


class OBSClient(
private val obsStatus: StatusLight,
Expand Down Expand Up @@ -205,6 +208,7 @@ class OBSClient(
}

private fun pushCrop(containers: HashMap<String, Int>, top: Int, left: Int, right: Int, bottom: Int) {
if (!isConnected) return
for (container in containers.keys) {
val sourceID = containers[container]!!
obsRemoteController.getSceneItemTransform(container, sourceID) { tResponse: GetSceneItemTransformResponse ->
Expand Down Expand Up @@ -234,7 +238,7 @@ class OBSClient(

fun setStreamKey(key: String?) {
if (!isConnected) return
val settings = JsonObject()
val settings: JsonObject = JsonObject()
settings.addProperty("bwtest", false)
settings.addProperty("key", key)
settings.addProperty("server", "auto")
Expand All @@ -249,6 +253,13 @@ class OBSClient(
}
}

fun reloadLayout() {
if (!isConnected) return
obsRemoteController.sendRequest(PressInputPropertiesButtonRequest.builder().inputName("PreRaceLayout").propertyName("refreshnocache").build()) { _: PressInputPropertiesButtonResponse -> return@sendRequest }
obsRemoteController.sendRequest(PressInputPropertiesButtonRequest.builder().inputName("WebLayout").propertyName("refreshnocache").build()) { _: PressInputPropertiesButtonResponse -> return@sendRequest }
obsRemoteController.sendRequest(PressInputPropertiesButtonRequest.builder().inputName("PostRaceLayout").propertyName("refreshnocache").build()) { _: PressInputPropertiesButtonResponse -> return@sendRequest }
}

companion object {
private val log = LoggerFactory.getLogger(OBSClient::class.java.name)
}
Expand Down
9 changes: 7 additions & 2 deletions src/main/resources/html/FourPlayer.html
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
color: white;
font-family: "Roboto", sans-serif;
font-weight: 700;
font-size: 2.5rem;
}

iframe {
Expand Down Expand Up @@ -87,7 +88,7 @@
}

.hidden {
display: none;
visibility: hidden;
}

#layout {
Expand Down Expand Up @@ -156,13 +157,17 @@
height: 49px;
width: 477px;
z-index: 1;
overflow: hidden;
text-align: center;
}

.player_name {
position: absolute;
height: 49px;
width: 249px;
z-index: 1;
overflow: hidden;
text-align: center;
}

#t1_name {
Expand Down Expand Up @@ -283,7 +288,7 @@
src="https://images.alttprleague.com/static/league/img/player-default.png"
alt="logo"
/>
<div class="team_name resize_center" id="t1_name">Team 1</div>
<div class="team_name resize_center" id="t1_name" data-path="players.team1.player1.name">Team 1</div>
<div class="player_name resize_center" id="p1_name">Player 1</div>
<div class="player_name resize_center" id="p3_name">Player 3</div>
<div class="left_wins hidden" data-wins="0" id="t1_wins">
Expand Down
11 changes: 9 additions & 2 deletions src/main/resources/html/TwoPlayer.html
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=1920, initial-scale=1.0" />
<title>TwoPlayer</title>
<script src="https://images.alttprleague.com/RestreamTool/js/textFit.js"></script>
<!-- <script src="https://images.alttprleague.com/RestreamTool/js/textFit.js"></script>-->
<script src="https://images.alttprleague.com/RestreamTool/js/common.js" defer></script>
<style>
@import url("https://fonts.googleapis.com/css2?family=Roboto:wght@700&display=swap");
Expand All @@ -24,6 +24,7 @@
color: white;
font-family: "Roboto", sans-serif;
font-weight: 700;
font-size: 2rem;
}

iframe {
Expand Down Expand Up @@ -84,7 +85,7 @@
}

.hidden {
display: none;
visibility: hidden;
}

#layout {
Expand Down Expand Up @@ -146,12 +147,18 @@
position: absolute;
height: 72px;
width: 490px;
overflow: hidden;
text-align: center;
font-size: 3rem;
}

.player_name {
position: absolute;
height: 76px;
width: 436px;
overflow: hidden;
text-align: center;
font-size: 3rem;
}

#t1_name {
Expand Down

0 comments on commit 4785261

Please sign in to comment.