web socket example to stream screen to html 5 player
2013-10-22
Here is a working example using web socket to stream screen to html 5 player. The server is in java, I use websockify.py to route the websocket to java socket.
package com.videotojpeg;
import java.awt.Dimension;
import java.awt.Graphics2D;
import java.awt.Rectangle;
import java.awt.RenderingHints;
import java.awt.Robot;
import java.awt.Toolkit;
import java.awt.image.BufferedImage;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.Socket;
import javax.imageio.ImageIO;
import org.apache.commons.codec.binary.Base64;
import com.github.sarxos.webcam.Webcam;
public class ClientServiceThread implements Runnable {
Socket myClientSocket;
Webcam webcam = Webcam.getDefault();
public ClientServiceThread() {
super();
}
ClientServiceThread(Socket s) {
myClientSocket = s;
webcam.setViewSize(new Dimension(480, 400));
webcam.open();
}
public void run() {
InputStream in = null;
OutputStream out = null;
ByteArrayOutputStream baos = new ByteArrayOutputStream();
System.out.println("Accepted Client Address - " + myClientSocket.getInetAddress().getHostName());
try {
in = myClientSocket.getInputStream();
out = myClientSocket.getOutputStream();
int x = 1;
while (true) {
byte bytes2[] = new byte[1];
for (int z = 0; z < 11; z++) {
in.read(bytes2);
System.out.print((char) bytes2[0]);
}
System.out.println();
System.out.println("start cap");
BufferedImage image = resize(new Robot().createScreenCapture(new Rectangle(Toolkit.getDefaultToolkit().getScreenSize())), 640, 480);
// BufferedImage image = new Robot().createScreenCapture(new Rectangle(Toolkit.getDefaultToolkit().getScreenSize()));
System.out.println("end cap");
System.out.println("start encode");
baos.reset();
ImageIO.write(image, "jpg", baos);
// ImageIO.write(image, "png", new File("testing.png"));
baos.flush();
byte[] bytes = baos.toByteArray();
baos.close();
// out.write("fssss".getBytes());
byte header[] = (String.format("%09d", Base64.encodeBase64(bytes).length)).getBytes();
System.out.println("end encode");
System.out.println("start transmit");
out.write(header);
out.flush();
out.write(Base64.encodeBase64(bytes));
out.flush();
System.out.println("end transmit");
System.out.println("reply :" + bytes.length + "," + bytes + ", encoded len=" + Base64.encodeBase64(bytes).length); x++;
}
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
in.close();
out.close();
myClientSocket.close();
System.out.println("...Stopped");
} catch (IOException ioe) {
ioe.printStackTrace();
}
}
}
public static BufferedImage resize(BufferedImage img, int newW, int newH) {
int w = img.getWidth();
int h = img.getHeight();
BufferedImage dimg = new BufferedImage(newW, newH, img.getType());
Graphics2D g = dimg.createGraphics();
g.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BILINEAR);
g.drawImage(img, 0, 0, newW, newH, 0, 0, w, h, null);
g.dispose();
return dimg;
}
}
html 5 player
<html>
<title>Custom Draw</title>
<div id="output" style="display:none">output</div>
<canvas id="myCanvas" width="720" height="600" style="border:1px solid #000000;"></canvas>
<script type="text/javascript" src="jquery-2.0.3.min.js"></script>
<script>
var width=720;
var height=600;
var c=document.getElementById("myCanvas");
var ctx=c.getContext("2d");
var imgData=ctx.createImageData(1440,900);
var x=0;
function draw(){
for (var i=0;i<imgData.data.length;i+=4){
imgData.data[i+0]=Math.random()*255;
imgData.data[i+1]=Math.random()*255;
imgData.data[i+2]=Math.random()*255;
imgData.data[i+3]=255;
}
ctx.putImageData(imgData,0,0);
$('#output').html(x);
console.log(x);
x++;
}
//setInterval(draw,10);
////////////////////////////////////////////////////////////////////////////////
var blob;
var readSize=0;
var started=false;
var imageSize=0;
var image64="";
websocket = new WebSocket("ws://192.168.163.121:8887", "binary");
websocket.binaryType = "arraybuffer";
websocket.onopen = function(evt) { onOpen(evt) };
websocket.onclose = function(evt) { onClose(evt) };
websocket.onmessage = function(evt) { onMessage(evt) };
websocket.onerror = function(evt) { onError(evt) };
function onOpen(evt){
websocket.send("hello peter");
}
function onClose(evt){
//$('#output').html("close");
}
function onMessage(evt){
blob=evt;
var r=String.fromCharCode.apply(null, new Uint8Array(blob.data));
if (started==false){
if (r==9){
imageSize=parseInt(r);
}else{
imageSize=parseInt(r.substring(0,9));
image64+=r.substring(9);
readSize+=parseInt(r.length-9);
}
console.log("imageSize="+imageSize);
started=true;
}else{
//$('#output').html(r.length);
//console.log("r.length="+r.length);
image64+=r;
readSize+=parseInt(r.length);
}
console.log("readSize="+readSize+", r.length="+r.length);
if (readSize==imageSize){
img=new Image();
img.onload=function(){
ctx.drawImage(img,0,0,img.width,img.height,0,0,width,height);
websocket.send("hello peter");
}
console.log("loaded image, length="+image64.length);
img.src='data:image/jpg;base64,'+image64;
readSize=0;
started=false;
image64="";
}
}
function onerror(evt){
}
</script>
</html>