⬆️ ⬇️

Create autarky in the browser using the webcam



Hello. Not so long ago on one of the web projects, I needed the opportunity to get photos from a webcam. After some time, on another project, the same need arose, and again a third project appeared on the horizon, with similar functionality. In order not to go every time on html5 Rocks , and to look, "how it is and what," I decided to write a plugin.

Actually, in this article I want to present the result of my work: html5-webcam-avatar - jquery plugin for creating avatars from a webcam.







What can a plugin?



What can not?



That is, the plugin uses only javascript and native browser capabilities, no fallbacks are provided.

I would recommend using it as an additional feature on my website. Check whether the appropriate features are supported and connect the plugin.

')

How it works?

Modern browsers are already trying to work with a webcam and microphone. In javascript this is implemented via the corresponding api.

Sample code from the site html5 Rocks

window.URL = window.URL || window.webkitURL; navigator.getUserMedia = navigator.getUserMedia || navigator.webkitGetUserMedia || navigator.mozGetUserMedia || navigator.msGetUserMedia; //... if (navigator.getUserMedia) { navigator.getUserMedia({audio: true, video: true}, function(stream) { video.src = window.URL.createObjectURL(stream); }, onFailSoHard); } else { video.src = 'somevideo.webm'; // fallback. } 


It's simple. We check whether the navigator.getUserMedia function is defined and execute the appropriate code. Otherwise, we perform some fallback function. All this can be read more on the above site. I want to talk about some things that are not obvious and not described there.



First , the behavior of the stream object is different in different browsers. In chrome, in order to pass it to the src parameter of the video tag, you must convert it to objectURL using window.URL.createObjectURL . In opera, as I understand it, the stream object is automatically converted, and for example the window.URL properties — I just did not find it. Therefore, we write directly: video.src = stream . Well, firefox has a window.URL property and a createObjectURL method. However, such code window.URL.createObjectURL(stream) - gives an error, but here’s how video.src = stream works.
NB
In general, in firefox 18, I still could not get my plugin to work, although the getUserMedia property was already there, but firefox 19 recently came out and my plugin worked.


Therefore, my code is as follows:

 navigator.getUserMedia && navigator.getUserMedia({video: true}, function(stream) { try { video.src = window.URL.createObjectURL(stream); //for webkit } catch (e) { video.src = stream; //for opera and firefox } }, function() { alert('-     '); }); 




The second point , about which I would like to tell, is the work with the player itself. The fact is that for convenience, I decided to make it possible to stop the video, and then make a snapshot. So, stopping the video in chrome and firefox - it is normal. In opera, along with the video stop, the stream from the webcam also stops. That is, when we make a snapshot in opera during a pause, we get a version of a work by a famous artist (black square). The solution to this problem is obvious in principle. Before you pause the video, we save the dataUrl to some temporary storage, and then, when creating the snapshot, we take it out of the storage if the video is paused or we create the dataUrl again.

It looks like this to me:

 // play/pause -      video.addEventListener('click', function() { if (video.paused) { video.play(); } else { $(video).data('data-url', getSnapshotDataUrl()); //     data-url video.pause(); } }); ... var getDataUrl = function() { var data_url = video.paused ? $video.data('data-url') : getSnapshotDataUrl(); return data_url; } 


Here, getSnapshotDataUrl is a function that throws the current frame of the video to the canvas, element canvas, and then the toDataURL method is called on the canvas.



Now I’ll tell you about the plugin itself.

In general, it turns out not one, but two plugins. The first to get photos from the web camera html5WebCam . The second is for cropping photos html5Crop . Yes, they can be used separately.

Everything works as follows - we hang the plugin on any element. for example button . Now the element listens to the click event and starts the procedure for creating an avatar. When the avatar is ready, we will get it in the onCrop , or onsnapshot callback function.

 $(document).ready(function() { $("#create_snapshot").html5WebCam({ oncrop: function(cropped_url) { // cropped_url - base64 image var $img = $("<img/>"); $img.attr('src', cropped_url); $('body').append($img); }, }); }); 


The plugin uses simple modal windows that are easily configured via the attached css file. If this solution does not suit you, you can use your modal windows (on the demo site there is an example with the jquery-ui Dialog).



There are other customizable options, here is their list.

 //html5WebCam NOT_SUPPORT_FEATURE: '      ', CAMERA_NOT_FOUND: '     ', CLICK_TO_PAUSE: '  /', TAKE_SNAPSHOT: ' ', CANCEL: '', max_video_size: 600, modal_class: 'html5-webcam-avatar-modal', use_native_modal: true, use_native_button: true, onDomCreated: function($html) { }, onsnapshot: function(snapshot) {}, use_crop: true, oncrop: function(cropped_url) {}, oncancel: function() {}, alertFn: function(msg) { alert(msg); } //html5Crop CROP_NAME: '', CANCEL: '', MIN_IMG_SIDE_ERROR: '      ', CANVAS_NOT_SUPPORTED: 'canvas not supported in this browser', square_mode: true, max_crop_side: 400, min_crop_side: 50, max_img_side: 600, min_img_side: 100, init_crop_side: 100, dot_side: 10, use_native_modal: true, use_native_button: true, onDomCreated: function($ui) {}, oncancel: function() {}, oncrop: function(cropped_url) {}, alertFn: function(msg) { alert(msg); }, modal_class: 'html5-webcam-avatar-modal' 


I think the names understand what they are for. I just want to note, all the parameters for html5Crop - you need to set in html5WebCam - when sharing them, that is, if use_crop: true (the default is exactly this way).



Demo and plugin - here

Waiting for questions, suggestions, criticism and advice in the comments.

Source: https://habr.com/ru/post/170983/



All Articles