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>