Raspberry Pi acting as a "syphon server"

Hi everybody,

I'm working on a little project where I want my raspberry Pi 3B to generate graphics, and then send it to my laptop over network (ethernet), so i can compose it there with other sources for a bigger thing.
As the TCPSyphon works only in the way that the raspberry is a client, but not server, I'm trying to find alternative solutions...
I've managed something, using Daniel Shiffman's Streaming with UDP , sending PGraphics instead of video, but even with a really low resolution for the test (320x240), the process is really really slow.
I think it just take to much time for the raspberry to put each frame in a buffer and encode it.
Does somebody think there's a way to improve this code, or just go towards a complete different solution? I think this functionality could be interesting for many people...
Thanks!

import javax.imageio.*;
import java.awt.image.*;
import java.io.*;
import java.net.*;
import java.util.*;

// This is the port we are sending to
int clientPort = 9100; 
// This is our object that sends UDP out
DatagramSocket ds; 
// Capture object
Capture cam;
PGraphics canvas;

String client = "169.254.209.178";

float time;
float incr = 0.1;

void setup() {
  size(320, 240);
  // Setting up the DatagramSocket, requires try/catch
  try {
    ds = new DatagramSocket();
  } 
  catch (SocketException e) {
    e.printStackTrace();
  }
  canvas = createGraphics(320, 240);
}

void draw() {
  time +=incr;
  canvas.beginDraw();
  canvas.background(0);
  canvas.fill(255);
  canvas.ellipse(map(cos(time), -1, 1, 0, width), height/2, 45, 45);
  canvas.endDraw();
  image(canvas, 0, 0);
  broadcast(canvas);
}


// Function to broadcast a PImage over UDP
// Special thanks to: http://ubaa.net/shared/processing/udp/
// (This example doesn't use the library, but you can!)
void broadcast(PGraphics img) {

  // We need a buffered image to do the JPG encoding
  BufferedImage bimg = new BufferedImage( img.width, img.height, BufferedImage.TYPE_INT_RGB );

  // Transfer pixels from localFrame to the BufferedImage
  img.loadPixels();
  bimg.setRGB( 0, 0, img.width, img.height, img.pixels, 0, img.width);

  // Need these output streams to get image as bytes for UDP communication
  ByteArrayOutputStream baStream    = new ByteArrayOutputStream();
  BufferedOutputStream bos      = new BufferedOutputStream(baStream);

  // Turn the BufferedImage into a JPG and put it in the BufferedOutputStream
  // Requires try/catch
  try {
    ImageIO.write(bimg, "jpg", bos);
  } 
  catch (IOException e) {
    e.printStackTrace();
  }

  // Get the byte array, which we will send out via UDP!
  byte[] packet = baStream.toByteArray();

  // Send JPEG data as a datagram
  println("Sending datagram with " + packet.length + " bytes");
  try {
    ds.send(new DatagramPacket(packet, packet.length, InetAddress.getByName(client), clientPort));
  } 
  catch (Exception e) {
    e.printStackTrace();
  }
}

Answers

  • Perhaps just transfer the pixels that got changed and update the display window using the pixels array?

  • Thanks for your suggestion gohai, I ended up just using some screen sharing solution actually

Sign In or Register to comment.