Web Sockets - Sharing Images

File and FileReader

A form element for selecting and uploading a file has existing in HTML for some time. We can use this input type file form element as a way to send a file from user to server or user to user via a Web Socket.

<input type="file" name="fileinput" id="fileinput">
		

To know when a file has been selected, we can use the "onchange" event:

var fileElement = document.getElementById('fileinput');
fileElement.onchange = function() {	
	// do something
};
		

To actually read the file, we can use a FileReader object:

var fileReader = new FileReader();
					
// The onload event is triggered once the file is read
fileReader.onload = function(evt){
		
		// evt.target.result contains the file in base64 format
		// Browsers can interpret that as a "data url" so we can set the source of an image object
		document.getElementById('imagefile').src = evt.target.result;
		// Might also be able to use fileReader.result

		// and/or we can send via Socket.io
		socket.emit('image', evt.target.result);
	};

var fileElement = document.getElementById('fileinput');
fileElement.onchange = function() {	
	// fileElement.files is an array of all of the selected files
	var file = fileElement.files[0];  
	
	// Tell the fileReader to go ahead and read it.
	fileReader.readAsDataURL(file);
};
		

Here is a full example

More Information:
How to send images through Web Sockets with Node.js and Socket.io
FileReader - API

WebRTC

WebRTC stands for Web Real Time Communication. We'll get more into this next week but I want to get started with one portion:

getUserMedia

getUserMedia is a method specified as part of WebRTC that allows access to the microphone and webcam of users.

// These help with cross-browser functionality
window.URL = window.URL || window.webkitURL || window.mozURL || window.msURL;
navigator.getUserMedia = navigator.getUserMedia || navigator.webkitGetUserMedia || navigator.mozGetUserMedia || navigator.msGetUserMedia;

// The video element on the page to display the webcam
var video = document.getElementById('thevideo');

// if we have the method
if (navigator.getUserMedia) {
	navigator.getUserMedia({video: true}, function(stream) {
			video.src = window.URL.createObjectURL(stream) || stream;
			video.play();
		}, function(error) {alert("Failure " + error.code);});
}		
		

One cool aspect of this is that you can draw the video on to a canvas as well (perhaps to manipulate it):

// Canvas element on the page
var thecanvas = document.getElementById('thecanvas');
var thecontext = thecanvas.getContext('2d');

var draw = function() {
	// Draw the video onto the canvas
	thecontext.drawImage(video,0,0,video.width,video.height);
	
	
	document.getElementById('imagefile').src = dataUrl;
	
	// Draw again in 3 seconds
	setTimeout(draw,3000);	
};

draw();			
		

From the canvas, you can create an image and send that via Socket.io to everyone else, making a poor persons video server (based on the send image example above, same server)(:

// Create a data URL from the canvas, similar to our FileReader readAsDataURL method 
var dataUrl = thecanvas.toDataURL('image/webp', 1);

// Optionally draw it to an image object to make sure it works
document.getElementById('imagefile').src = dataUrl;

// Send it via our socket server the same way as we send the image
socket.emit('image', dataUrl);
		
		

Here is a full example

More Information: Capturing Audio and Video in HTML5