mirror of
https://github.com/Maschell/StreamingPluginClient.git
synced 2024-12-18 01:01:52 +01:00
First commit
This commit is contained in:
commit
c6ca27edd5
18
.circleci/circle.yml
Normal file
18
.circleci/circle.yml
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
machine:
|
||||||
|
java:
|
||||||
|
version: oraclejdk8
|
||||||
|
|
||||||
|
compile:
|
||||||
|
override:
|
||||||
|
- mvn package -Dci-build=true
|
||||||
|
|
||||||
|
general:
|
||||||
|
artifacts:
|
||||||
|
- "ci"
|
||||||
|
|
||||||
|
deployment:
|
||||||
|
nightlies:
|
||||||
|
branch: master
|
||||||
|
commands:
|
||||||
|
- go get github.com/tcnksm/ghr
|
||||||
|
- ghr -t $GITHUB_TOKEN -u $CIRCLE_PROJECT_USERNAME -r $CIRCLE_PROJECT_REPONAME -prerelease -b 'Nightly release - Use caution! We recommend downloading a stable release from the README.' `echo "v0.1-nightly-$(git rev-parse --short=7 HEAD)"` ci/
|
18
README.MD
Normal file
18
README.MD
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
# Streaming Plugin Client
|
||||||
|
|
||||||
|
A Java client for the [Wii U Streaming Plugin](https://github.com/Maschell/StreamingPluginWiiU).
|
||||||
|
|
||||||
|
# Usage
|
||||||
|
|
||||||
|
Start the plugin via the [WiiUPluginSystemLoader](https://github.com/Maschell/WiiUPluginSystem) on your WiiU. Now start Java client by either
|
||||||
|
- provide the ip address of your Wii U as a argument. Example: ``java -jar StreamingPluginClient[...].jar --ip 192.168.0.11`
|
||||||
|
- **or** just double click on the .jar. A little dialog should appear where you can enter the IP address of your Wii U console.
|
||||||
|
|
||||||
|
Requires Java 8.
|
||||||
|
|
||||||
|
# Building
|
||||||
|
|
||||||
|
This is a maven project. Use following command to create a .jar with dependencies in the `target` folder.
|
||||||
|
```
|
||||||
|
mvn package
|
||||||
|
```
|
86
pom.xml
Normal file
86
pom.xml
Normal file
@ -0,0 +1,86 @@
|
|||||||
|
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||||
|
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||||
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
<groupId>StreamingPluginClient</groupId>
|
||||||
|
<artifactId>StreamingPluginClient</artifactId>
|
||||||
|
<version>0.0.1-SNAPSHOT</version>
|
||||||
|
|
||||||
|
<name>StreamingPluginClient</name>
|
||||||
|
<url>https://github.com/Maschell/StreamingPluginClient</url>
|
||||||
|
|
||||||
|
<profiles>
|
||||||
|
<profile>
|
||||||
|
<id>normal-build</id>
|
||||||
|
<activation>
|
||||||
|
<activeByDefault>true</activeByDefault>
|
||||||
|
</activation>
|
||||||
|
<properties>
|
||||||
|
<jar_dir>./target</jar_dir>
|
||||||
|
</properties>
|
||||||
|
</profile>
|
||||||
|
<profile>
|
||||||
|
<id>ci-build</id>
|
||||||
|
<activation>
|
||||||
|
<property>
|
||||||
|
<name>ci-build</name>
|
||||||
|
<value>true</value>
|
||||||
|
</property>
|
||||||
|
</activation>
|
||||||
|
<properties>
|
||||||
|
<jar_dir>./ci</jar_dir>
|
||||||
|
</properties>
|
||||||
|
</profile>
|
||||||
|
</profiles>
|
||||||
|
|
||||||
|
<build>
|
||||||
|
<sourceDirectory>src</sourceDirectory>
|
||||||
|
<plugins>
|
||||||
|
<plugin>
|
||||||
|
<artifactId>maven-compiler-plugin</artifactId>
|
||||||
|
<version>3.7.0</version>
|
||||||
|
<configuration>
|
||||||
|
<source>1.8</source>
|
||||||
|
<target>1.8</target>
|
||||||
|
</configuration>
|
||||||
|
</plugin>
|
||||||
|
<plugin>
|
||||||
|
<artifactId>maven-assembly-plugin</artifactId>
|
||||||
|
<executions>
|
||||||
|
<execution>
|
||||||
|
<id>make-assembly</id>
|
||||||
|
<configuration>
|
||||||
|
<archive>
|
||||||
|
<manifest>
|
||||||
|
<mainClass>de.mas.wiiu.streaming.Main</mainClass>
|
||||||
|
</manifest>
|
||||||
|
</archive>
|
||||||
|
<descriptorRefs>
|
||||||
|
<descriptorRef>jar-with-dependencies</descriptorRef>
|
||||||
|
</descriptorRefs>
|
||||||
|
<!-- Stick jar in root dir, if you want -->
|
||||||
|
<outputDirectory>${jar_dir}</outputDirectory>
|
||||||
|
<finalName>StreamingPluginClient-${project.version}-nightly</finalName>
|
||||||
|
</configuration>
|
||||||
|
<phase>package</phase>
|
||||||
|
<goals>
|
||||||
|
<goal>attached</goal>
|
||||||
|
</goals>
|
||||||
|
</execution>
|
||||||
|
</executions>
|
||||||
|
</plugin>
|
||||||
|
</plugins>
|
||||||
|
</build>
|
||||||
|
<dependencies>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.projectlombok</groupId>
|
||||||
|
<artifactId>lombok</artifactId>
|
||||||
|
<version>1.16.20</version>
|
||||||
|
</dependency>
|
||||||
|
<!-- https://mvnrepository.com/artifact/commons-cli/commons-cli -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>commons-cli</groupId>
|
||||||
|
<artifactId>commons-cli</artifactId>
|
||||||
|
<version>1.4</version>
|
||||||
|
</dependency>
|
||||||
|
</dependencies>
|
||||||
|
</project>
|
196
src/main/java/de/mas/wiiu/streaming/ImageStreamer.java
Normal file
196
src/main/java/de/mas/wiiu/streaming/ImageStreamer.java
Normal file
@ -0,0 +1,196 @@
|
|||||||
|
/*******************************************************************************
|
||||||
|
* Copyright (c) 2018 Maschell
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
|
* in the Software without restriction, including without limitation the rights
|
||||||
|
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
* copies of the Software, and to permit persons to whom the Software is
|
||||||
|
* furnished to do so, subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in all
|
||||||
|
* copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
* SOFTWARE.
|
||||||
|
*******************************************************************************/
|
||||||
|
|
||||||
|
package de.mas.wiiu.streaming;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.net.SocketException;
|
||||||
|
import java.net.SocketTimeoutException;
|
||||||
|
import java.net.UnknownHostException;
|
||||||
|
import java.nio.ByteBuffer;
|
||||||
|
import java.util.zip.CRC32;
|
||||||
|
|
||||||
|
import javax.swing.JOptionPane;
|
||||||
|
|
||||||
|
import de.mas.wiiu.streaming.gui.IImageProvider;
|
||||||
|
import de.mas.wiiu.streaming.gui.ImageProvider;
|
||||||
|
import de.mas.wiiu.streaming.network.TCPClient;
|
||||||
|
import de.mas.wiiu.streaming.network.UDPClient;
|
||||||
|
import de.mas.wiiu.streaming.utilities.Utilities;
|
||||||
|
import lombok.Synchronized;
|
||||||
|
import lombok.extern.java.Log;
|
||||||
|
|
||||||
|
@Log
|
||||||
|
public class ImageStreamer {
|
||||||
|
|
||||||
|
private final ImageProvider imageProvider = new ImageProvider();
|
||||||
|
private final TCPClient tcpClient;
|
||||||
|
private final UDPClient udpClient;
|
||||||
|
|
||||||
|
public ImageStreamer(String ip) throws SocketException {
|
||||||
|
tcpClient = new TCPClient(ip, 8092, 200);
|
||||||
|
udpClient = new UDPClient(9445);
|
||||||
|
new Thread(udpClient, "UDPClient").start();
|
||||||
|
udpClient.setOnDataCallback(this::udpDataHandler);
|
||||||
|
|
||||||
|
new Thread(() -> {
|
||||||
|
while (true) {
|
||||||
|
if (!tcpClient.isConnected()) {
|
||||||
|
System.out.print("Connecting..");
|
||||||
|
try {
|
||||||
|
tcpClient.connect();
|
||||||
|
System.out.println("success!");
|
||||||
|
} catch (IllegalArgumentException | UnknownHostException e1) {
|
||||||
|
JOptionPane.showMessageDialog(null, "Make sure to enter a valid ip address.", e1.getClass().getName(), JOptionPane.WARNING_MESSAGE);
|
||||||
|
System.exit(-1);
|
||||||
|
} catch (SocketTimeoutException e) {
|
||||||
|
System.out.println("time out...");
|
||||||
|
} catch (IOException e) {
|
||||||
|
// TODO Auto-generated catch block
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
sendPing();
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
Thread.sleep(1000);
|
||||||
|
} catch (InterruptedException e) {
|
||||||
|
// TODO Auto-generated catch block
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}).start();
|
||||||
|
|
||||||
|
new Thread(() -> {
|
||||||
|
while (true) {
|
||||||
|
if (tcpClient.isConnected()) {
|
||||||
|
System.out.println("FPS:" + framesThisSecond);
|
||||||
|
framesThisSecond = 0;
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
Thread.sleep(1000);
|
||||||
|
} catch (InterruptedException e) {
|
||||||
|
// TODO Auto-generated catch block
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}).start();
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean sendTCP(byte[] rawCommand) {
|
||||||
|
boolean result = false;
|
||||||
|
try {
|
||||||
|
tcpClient.send(rawCommand);
|
||||||
|
result = true;
|
||||||
|
} catch (Exception e) {
|
||||||
|
result = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
void sendPing() {
|
||||||
|
if (sendTCP(new byte[] { 0x15 })) {
|
||||||
|
byte pong;
|
||||||
|
try {
|
||||||
|
pong = tcpClient.recvByte();
|
||||||
|
if (pong == 0x16) {
|
||||||
|
// log.info("Ping...Pong!");
|
||||||
|
} else {
|
||||||
|
log.info("Got no valid response to a Ping. Disconnecting.");
|
||||||
|
tcpClient.abort();
|
||||||
|
}
|
||||||
|
} catch (IOException e) {
|
||||||
|
log.info("Failed to get PONG. Disconnecting.");
|
||||||
|
tcpClient.abort();
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
log.info("Sending the PING failed");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private final Object lock = new Object();
|
||||||
|
|
||||||
|
private DataState state = DataState.UNKNOWN;
|
||||||
|
private int curcrc32 = 0;
|
||||||
|
private int curJPEGSize = 0;
|
||||||
|
private byte[] jpegBuffer = {};
|
||||||
|
private int curLenPos = 0;
|
||||||
|
|
||||||
|
private int framesThisSecond = 0;
|
||||||
|
|
||||||
|
@Synchronized("lock")
|
||||||
|
private void udpDataHandler(byte[] data) {
|
||||||
|
if (state == DataState.UNKNOWN) {
|
||||||
|
// System.out.println("GET CRC");
|
||||||
|
if (data.length == 4) {
|
||||||
|
ByteBuffer wrapped = ByteBuffer.wrap(data); // big-endian by default
|
||||||
|
curcrc32 = wrapped.getInt(); // 1
|
||||||
|
state = DataState.CRC32_RECEIVED;
|
||||||
|
} else {
|
||||||
|
|
||||||
|
state = DataState.UNKNOWN;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
} else if (state == DataState.CRC32_RECEIVED) {
|
||||||
|
// System.out.println("GET Size");
|
||||||
|
if (data.length == 8) {
|
||||||
|
ByteBuffer wrapped = ByteBuffer.wrap(data); // big-endian by default
|
||||||
|
curJPEGSize = (int) wrapped.getLong();
|
||||||
|
jpegBuffer = new byte[curJPEGSize];
|
||||||
|
state = DataState.RECEIVING_IMAGE;
|
||||||
|
curLenPos = 0;
|
||||||
|
} else {
|
||||||
|
// System.out.println("...");
|
||||||
|
state = DataState.UNKNOWN;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
} else if (state == DataState.RECEIVING_IMAGE) {
|
||||||
|
// System.out.println("GET IMAGE");
|
||||||
|
System.arraycopy(data, 0, jpegBuffer, curLenPos, data.length > curJPEGSize ? curJPEGSize : data.length);
|
||||||
|
|
||||||
|
curJPEGSize -= data.length;
|
||||||
|
curLenPos += data.length;
|
||||||
|
if (curJPEGSize <= 0) {
|
||||||
|
CRC32 crc = new CRC32();
|
||||||
|
crc.update(jpegBuffer);
|
||||||
|
if ((int) crc.getValue() == curcrc32) {
|
||||||
|
imageProvider.updateImage(Utilities.byteArrayToImage(jpegBuffer));
|
||||||
|
framesThisSecond++;
|
||||||
|
} else {
|
||||||
|
System.out.println("Hash mismatch, dropping frame.");
|
||||||
|
}
|
||||||
|
state = DataState.UNKNOWN;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public IImageProvider getImageProvider() {
|
||||||
|
return imageProvider;
|
||||||
|
}
|
||||||
|
|
||||||
|
public enum DataState {
|
||||||
|
UNKNOWN, CRC32_RECEIVED, RECEIVING_IMAGE, IMAGE_RECEIVED
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
75
src/main/java/de/mas/wiiu/streaming/Main.java
Normal file
75
src/main/java/de/mas/wiiu/streaming/Main.java
Normal file
@ -0,0 +1,75 @@
|
|||||||
|
/*******************************************************************************
|
||||||
|
* Copyright (c) 2018 Maschell
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
|
* in the Software without restriction, including without limitation the rights
|
||||||
|
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
* copies of the Software, and to permit persons to whom the Software is
|
||||||
|
* furnished to do so, subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in all
|
||||||
|
* copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
* SOFTWARE.
|
||||||
|
*******************************************************************************/
|
||||||
|
|
||||||
|
package de.mas.wiiu.streaming;
|
||||||
|
|
||||||
|
import java.net.BindException;
|
||||||
|
import java.net.SocketException;
|
||||||
|
|
||||||
|
import javax.swing.JOptionPane;
|
||||||
|
import javax.swing.SwingUtilities;
|
||||||
|
|
||||||
|
import org.apache.commons.cli.CommandLine;
|
||||||
|
import org.apache.commons.cli.CommandLineParser;
|
||||||
|
import org.apache.commons.cli.DefaultParser;
|
||||||
|
import org.apache.commons.cli.HelpFormatter;
|
||||||
|
import org.apache.commons.cli.Options;
|
||||||
|
|
||||||
|
import de.mas.wiiu.streaming.gui.StreamWindow;
|
||||||
|
|
||||||
|
public class Main {
|
||||||
|
|
||||||
|
public static void main(String[] args) throws Exception {
|
||||||
|
CommandLineParser parser = new DefaultParser();
|
||||||
|
|
||||||
|
Options options = new Options();
|
||||||
|
options.addOption("ip", "ip", true, "IP address of your Wii U Console.");
|
||||||
|
|
||||||
|
CommandLine line = parser.parse(options, args);
|
||||||
|
String ip = null;
|
||||||
|
|
||||||
|
if (line.hasOption("ip")) {
|
||||||
|
ip = line.getOptionValue("ip");
|
||||||
|
} else {
|
||||||
|
HelpFormatter formatter = new HelpFormatter();
|
||||||
|
formatter.printHelp("streamingTool", options);
|
||||||
|
ip = JOptionPane.showInputDialog(null, "Please enter the local IP address of your Wii U", "Wii U streaming client", JOptionPane.PLAIN_MESSAGE);
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
new Main(ip);
|
||||||
|
} catch (BindException e) {
|
||||||
|
JOptionPane.showMessageDialog(null, "Can't bind socket. The client is probably already running.", e.getClass().getName(),
|
||||||
|
JOptionPane.WARNING_MESSAGE);
|
||||||
|
System.exit(-1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public Main(String ip) throws SocketException {
|
||||||
|
ImageStreamer imageStreamer = new ImageStreamer(ip);
|
||||||
|
|
||||||
|
SwingUtilities.invokeLater(new Runnable() {
|
||||||
|
public void run() {
|
||||||
|
new StreamWindow(imageStreamer.getImageProvider());
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
31
src/main/java/de/mas/wiiu/streaming/gui/IImageProvider.java
Normal file
31
src/main/java/de/mas/wiiu/streaming/gui/IImageProvider.java
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
/*******************************************************************************
|
||||||
|
* Copyright (c) 2018 Maschell
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
|
* in the Software without restriction, including without limitation the rights
|
||||||
|
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
* copies of the Software, and to permit persons to whom the Software is
|
||||||
|
* furnished to do so, subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in all
|
||||||
|
* copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
* SOFTWARE.
|
||||||
|
*******************************************************************************/
|
||||||
|
|
||||||
|
package de.mas.wiiu.streaming.gui;
|
||||||
|
import java.awt.Image;
|
||||||
|
import java.util.function.Consumer;
|
||||||
|
|
||||||
|
public interface IImageProvider {
|
||||||
|
|
||||||
|
void setOnImageChange(Consumer<Image> function);
|
||||||
|
|
||||||
|
}
|
61
src/main/java/de/mas/wiiu/streaming/gui/ImagePanel.java
Normal file
61
src/main/java/de/mas/wiiu/streaming/gui/ImagePanel.java
Normal file
@ -0,0 +1,61 @@
|
|||||||
|
/*******************************************************************************
|
||||||
|
* Copyright (c) 2018 Maschell
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
|
* in the Software without restriction, including without limitation the rights
|
||||||
|
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
* copies of the Software, and to permit persons to whom the Software is
|
||||||
|
* furnished to do so, subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in all
|
||||||
|
* copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
* SOFTWARE.
|
||||||
|
*******************************************************************************/
|
||||||
|
|
||||||
|
package de.mas.wiiu.streaming.gui;
|
||||||
|
|
||||||
|
import java.awt.Dimension;
|
||||||
|
import java.awt.Graphics;
|
||||||
|
import java.awt.Image;
|
||||||
|
|
||||||
|
import javax.swing.JPanel;
|
||||||
|
|
||||||
|
public final class ImagePanel extends JPanel {
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
private static final long serialVersionUID = -127096088663141229L;
|
||||||
|
private Image image;
|
||||||
|
private final int preferedWidth;
|
||||||
|
private final int preferedHeight;
|
||||||
|
|
||||||
|
public ImagePanel(int width, int height) {
|
||||||
|
super(true);
|
||||||
|
preferedWidth = width;
|
||||||
|
preferedHeight = height;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setImage(Image image) {
|
||||||
|
this.image = image;
|
||||||
|
repaint();
|
||||||
|
}
|
||||||
|
|
||||||
|
public Dimension getPreferredSize() {
|
||||||
|
return new Dimension(preferedWidth, preferedHeight);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void paint(Graphics g) {
|
||||||
|
super.paint(g);
|
||||||
|
if (image != null) {
|
||||||
|
g.drawImage(image, 0, 0, getWidth(), getHeight(), 0, 0, image.getWidth(this), image.getHeight(this), this);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
43
src/main/java/de/mas/wiiu/streaming/gui/ImageProvider.java
Normal file
43
src/main/java/de/mas/wiiu/streaming/gui/ImageProvider.java
Normal file
@ -0,0 +1,43 @@
|
|||||||
|
/*******************************************************************************
|
||||||
|
* Copyright (c) 2018 Maschell
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
|
* in the Software without restriction, including without limitation the rights
|
||||||
|
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
* copies of the Software, and to permit persons to whom the Software is
|
||||||
|
* furnished to do so, subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in all
|
||||||
|
* copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
* SOFTWARE.
|
||||||
|
*******************************************************************************/
|
||||||
|
|
||||||
|
package de.mas.wiiu.streaming.gui;
|
||||||
|
|
||||||
|
import java.awt.Image;
|
||||||
|
import java.util.function.Consumer;
|
||||||
|
|
||||||
|
public final class ImageProvider implements IImageProvider {
|
||||||
|
|
||||||
|
private Consumer<Image> onImageChangeFunction = null;
|
||||||
|
|
||||||
|
public void updateImage(Image image) {
|
||||||
|
if (onImageChangeFunction != null) {
|
||||||
|
onImageChangeFunction.accept(image);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setOnImageChange(Consumer<Image> function) {
|
||||||
|
this.onImageChangeFunction = function;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
42
src/main/java/de/mas/wiiu/streaming/gui/StreamWindow.java
Normal file
42
src/main/java/de/mas/wiiu/streaming/gui/StreamWindow.java
Normal file
@ -0,0 +1,42 @@
|
|||||||
|
/*******************************************************************************
|
||||||
|
* Copyright (c) 2018 Maschell
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
|
* in the Software without restriction, including without limitation the rights
|
||||||
|
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
* copies of the Software, and to permit persons to whom the Software is
|
||||||
|
* furnished to do so, subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in all
|
||||||
|
* copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
* SOFTWARE.
|
||||||
|
*******************************************************************************/
|
||||||
|
|
||||||
|
package de.mas.wiiu.streaming.gui;
|
||||||
|
import javax.swing.JFrame;
|
||||||
|
import javax.swing.WindowConstants;
|
||||||
|
|
||||||
|
public class StreamWindow {
|
||||||
|
private final ImagePanel image = new ImagePanel(1280, 720);
|
||||||
|
|
||||||
|
public StreamWindow(IImageProvider imageProvider) {
|
||||||
|
JFrame editorFrame = new JFrame("Stream");
|
||||||
|
editorFrame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
|
||||||
|
|
||||||
|
imageProvider.setOnImageChange((bi) -> image.setImage(bi));
|
||||||
|
editorFrame.add(image);
|
||||||
|
|
||||||
|
editorFrame.pack();
|
||||||
|
editorFrame.setLocationRelativeTo(null);
|
||||||
|
editorFrame.setVisible(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
119
src/main/java/de/mas/wiiu/streaming/network/TCPClient.java
Normal file
119
src/main/java/de/mas/wiiu/streaming/network/TCPClient.java
Normal file
@ -0,0 +1,119 @@
|
|||||||
|
/*******************************************************************************
|
||||||
|
* Copyright (c) 2017,2018 Ash (QuarkTheAwesome) & Maschell
|
||||||
|
* Taken from the HID to VPAD Networkclient. Modified for the StreamingPluginClient.
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
|
* in the Software without restriction, including without limitation the rights
|
||||||
|
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
* copies of the Software, and to permit persons to whom the Software is
|
||||||
|
* furnished to do so, subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in all
|
||||||
|
* copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
* SOFTWARE.
|
||||||
|
*******************************************************************************/
|
||||||
|
package de.mas.wiiu.streaming.network;
|
||||||
|
|
||||||
|
import java.io.DataInputStream;
|
||||||
|
import java.io.DataOutputStream;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.net.InetSocketAddress;
|
||||||
|
import java.net.Socket;
|
||||||
|
import java.nio.ByteBuffer;
|
||||||
|
|
||||||
|
import lombok.Synchronized;
|
||||||
|
import lombok.extern.java.Log;
|
||||||
|
|
||||||
|
@Log
|
||||||
|
final public class TCPClient {
|
||||||
|
private final Object lock = new Object();
|
||||||
|
|
||||||
|
private Socket sock;
|
||||||
|
private DataInputStream in;
|
||||||
|
private DataOutputStream out;
|
||||||
|
|
||||||
|
private final String ip;
|
||||||
|
private final int port;
|
||||||
|
private final int timeout;
|
||||||
|
|
||||||
|
public TCPClient(String ip, int port, int timeout) {
|
||||||
|
this.ip = ip;
|
||||||
|
this.port = port;
|
||||||
|
this.timeout = timeout;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Synchronized("lock")
|
||||||
|
public void connect() throws IOException {
|
||||||
|
sock = new Socket();
|
||||||
|
sock.connect(new InetSocketAddress(ip, port), timeout);
|
||||||
|
in = new DataInputStream(sock.getInputStream());
|
||||||
|
out = new DataOutputStream(sock.getOutputStream());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Synchronized("lock")
|
||||||
|
public boolean abort() {
|
||||||
|
try {
|
||||||
|
sock.close();
|
||||||
|
} catch (IOException e) {
|
||||||
|
log.info(e.getMessage()); // TODO: handle
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Synchronized("lock")
|
||||||
|
public void send(byte[] rawCommand) throws IOException {
|
||||||
|
try {
|
||||||
|
out.write(rawCommand);
|
||||||
|
out.flush();
|
||||||
|
} catch (IOException e) {
|
||||||
|
throw e;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void send(int value) throws IOException {
|
||||||
|
send(ByteBuffer.allocate(4).putInt(value).array());
|
||||||
|
}
|
||||||
|
|
||||||
|
public void send(byte _byte) throws IOException {
|
||||||
|
send(ByteBuffer.allocate(1).put(_byte).array());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Synchronized("lock")
|
||||||
|
public byte recvByte() throws IOException {
|
||||||
|
return in.readByte();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Synchronized("lock")
|
||||||
|
short recvShort() throws IOException {
|
||||||
|
try {
|
||||||
|
return in.readShort();
|
||||||
|
} catch (IOException e) {
|
||||||
|
log.info(e.getMessage());
|
||||||
|
throw e;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Synchronized("lock")
|
||||||
|
int recvInt() throws IOException {
|
||||||
|
try {
|
||||||
|
return in.readInt();
|
||||||
|
} catch (IOException e) {
|
||||||
|
log.info(e.getMessage());
|
||||||
|
throw e;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Synchronized("lock")
|
||||||
|
public boolean isConnected() {
|
||||||
|
return (sock != null && sock.isConnected() && !sock.isClosed());
|
||||||
|
}
|
||||||
|
}
|
65
src/main/java/de/mas/wiiu/streaming/network/UDPClient.java
Normal file
65
src/main/java/de/mas/wiiu/streaming/network/UDPClient.java
Normal file
@ -0,0 +1,65 @@
|
|||||||
|
/*******************************************************************************
|
||||||
|
* Copyright (c) 2018 Maschell
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
|
* in the Software without restriction, including without limitation the rights
|
||||||
|
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
* copies of the Software, and to permit persons to whom the Software is
|
||||||
|
* furnished to do so, subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in all
|
||||||
|
* copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
* SOFTWARE.
|
||||||
|
*******************************************************************************/
|
||||||
|
|
||||||
|
package de.mas.wiiu.streaming.network;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.net.DatagramPacket;
|
||||||
|
import java.net.DatagramSocket;
|
||||||
|
import java.net.SocketException;
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.function.Consumer;
|
||||||
|
|
||||||
|
import lombok.extern.java.Log;
|
||||||
|
|
||||||
|
@Log
|
||||||
|
public final class UDPClient implements Runnable {
|
||||||
|
private final DatagramSocket sock;
|
||||||
|
|
||||||
|
public UDPClient(int port) throws SocketException {
|
||||||
|
sock = new DatagramSocket(port);
|
||||||
|
}
|
||||||
|
|
||||||
|
private Consumer<byte[]> onDataCallback = null;
|
||||||
|
|
||||||
|
public void setOnDataCallback(Consumer<byte[]> function) {
|
||||||
|
onDataCallback = function;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
log.info("UDPClient running.");
|
||||||
|
byte[] receiveData = new byte[1400];
|
||||||
|
while (true) {
|
||||||
|
DatagramPacket receivePacket = new DatagramPacket(receiveData, receiveData.length);
|
||||||
|
try {
|
||||||
|
sock.receive(receivePacket);
|
||||||
|
} catch (IOException e) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
byte[] data = Arrays.copyOf(receivePacket.getData(), receivePacket.getLength());
|
||||||
|
if (onDataCallback != null) {
|
||||||
|
onDataCallback.accept(data);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
56
src/main/java/de/mas/wiiu/streaming/utilities/Utilities.java
Normal file
56
src/main/java/de/mas/wiiu/streaming/utilities/Utilities.java
Normal file
@ -0,0 +1,56 @@
|
|||||||
|
/*******************************************************************************
|
||||||
|
* Copyright (c) 2018 Maschell
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
|
* in the Software without restriction, including without limitation the rights
|
||||||
|
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
* copies of the Software, and to permit persons to whom the Software is
|
||||||
|
* furnished to do so, subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in all
|
||||||
|
* copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
* SOFTWARE.
|
||||||
|
*******************************************************************************/
|
||||||
|
|
||||||
|
package de.mas.wiiu.streaming.utilities;
|
||||||
|
import java.awt.image.BufferedImage;
|
||||||
|
import java.io.ByteArrayInputStream;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.InputStream;
|
||||||
|
|
||||||
|
import javax.imageio.ImageIO;
|
||||||
|
|
||||||
|
public class Utilities {
|
||||||
|
private Utilities() {
|
||||||
|
//
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String ByteArrayToString(byte[] ba) {
|
||||||
|
if (ba == null)
|
||||||
|
return null;
|
||||||
|
StringBuilder hex = new StringBuilder(ba.length * 2);
|
||||||
|
for (byte b : ba) {
|
||||||
|
hex.append(String.format("%02X", b));
|
||||||
|
}
|
||||||
|
return hex.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static BufferedImage byteArrayToImage(byte[] bytes) {
|
||||||
|
BufferedImage bufferedImage = null;
|
||||||
|
try {
|
||||||
|
InputStream inputStream = new ByteArrayInputStream(bytes);
|
||||||
|
bufferedImage = ImageIO.read(inputStream);
|
||||||
|
} catch (IOException ex) {
|
||||||
|
System.out.println(ex.getMessage());
|
||||||
|
}
|
||||||
|
return bufferedImage;
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user