HTML5 Camera and Android

In the last days i implemented a small Android app that is able to give you a very simple HTML5 camera streaming feature for your smartphone without installing any additional client software. The idea behind this app is, that the HTML5Cam app opens a simple HTTP server that is serves a HTML5 camera updating page from your smartphone. In order to implement this HTTP server feature within my app i used and modified the NanoHTTPD server that consists of single Java 1.1 compatible Java source file, thanks to the great work of Jarno Elonen!

tabshop

The HTML5 cam page consists of a single page that uses the canvas element to dynamically refresh and update the camera image that is served by the Android app. I modified the NanoHTTPD  server to serve files directly out of the compressed assets folder that comes with your app package (apk). So the HTML5 camera page as well as all its styles, images and other resources resides within the assets folder. The source of the HTML5 camera page looks like as follows:

<!DOCTYPE html>
<html>
<head>
<meta charset="ISO-8859-1">
<title>Smartlab Cam</title>
<script type="text/javascript">
	var pwd = "";

	function start() {	
		pwd = prompt("Password");

		setTimeout("update()", 1000);

		var drawingCanvas = 
			document.getElementById('canvas');

		drawingCanvas.width  = window.innerWidth;
		drawingCanvas.height = window.innerHeight / 2;
	}

	function update () {
		var drawingCanvas = 
			document.getElementById('canvas');

		// Check the element is in the DOM and 
		// the browser supports canvas
		if(drawingCanvas.getContext) {
			// init a 2-dimensional 
			// drawing context
			var context = 
				drawingCanvas.getContext('2d');
			//Canvas commands go here

			var cam = new Image();
			cam.onload = function() {
				context.drawImage(cam, 0, 0, 
					cam.width, cam.height);
			}
			cam.src = 'cam.jpg?pwd=' + pwd;
			setTimeout("update()", 500);
		}

	}
</script>

</head>
<body onload="start()">

	<a href="http://www.smartlab.at">
		<img src="header.jpg"/>
	</a>

	<canvas id="canvas">
		<p>Your browser doesn't 
		support canvas.
		</p>
	</canvas>
</body>
</html>

If you open your HTML5 compatible browser and type in the address of your smartphone on port 8080 you get following visual output:

The HTML5Cam app opens a NanoHTTPD server on port 8080 (Android does not allow any server socket port numbers below 1000) and serves this HTML5 camera page and all necessary resources that are found within the compressed assets folder.

To capture the camera image, the app enables the camera preview by creating a live preview SurfaceView:

final SurfaceView preview = (SurfaceView) findViewById(R.id.preView);
previewHolder = preview.getHolder();
previewHolder.addCallback(surfaceCallback);
previewHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
camera.setPreviewCallback(this);

By implementing and register (setPreviewCallback()) a PreviewCallback listener we can get the notification whenever the preview captured a valid camera image:

public void onPreviewFrame(byte[] data, Camera camera) {
	Camera.Parameters parameters = camera.getParameters();	
    Size size = parameters.getPreviewSize();

    final YuvImage image = new YuvImage(data, parameters.getPreviewFormat(),
		size.width, size.height, null);
    // store image for HTTP request delivery
	mBoundService.setImage(image);
}

You can get the full source code without warranty from here: HTML5Cam.

Leave a Reply