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