HTML 5 live video streaming from multiple sources - javascript

I have created a live video feed on a webpage with HTML 5, it works find but i am wondering is it possible to get video from many different sources.
How it works is it uses the built in webcam, grabs the video feed from that and adds it to the HTML of the page.
Is there any way I can duplicate this but grab video sources from another webcam? (i.e Have multiple live video feeds on the one page)
index.html
<!Doctype html>
<head>
<title>LiveStream</title>
<link rel="stylesheet" href="css/main.css">
</head>
<body>
<div class="booth">
<video id="video" width="400" height="300" autoplay controls></video>
<canvas id="canvas" width="400" width="300">
<script src="video.js"></script>
</div>
</body>
video.js
(function(){
var canvas = document.getElementById('canvas'),
context = canvas.getContext('2d'),
video = document.getElementById('video'),
vendorUrl = window.URL || window.webkitURL;
navigator.getMedia = navigator.getUserMedia ||
navigator.webkitGetUserMedia ||
navigator.mozGetUserMedia ||
navigator.msGetUserMedia;
navigator.getMedia({
video: true,
audio: true
}, function(stream){
video.src = vendorUrl.createObjectURL(stream);
video.play();
}, function(error){
//Error occured!
});
})();
I have tried the following with MediaDevices.enumerateDevices but it isn't working!
(function(){
var canvas = document.getElementById('canvas'),
context = canvas.getContext('2d'),
video = document.getElementById('video'),
vendorUrl = window.URL || window.webkitURL;
navigator.getMedia = navigator.getUserMedia ||
navigator.webkitGetUserMedia ||
navigator.mozGetUserMedia ||
navigator.msGetUserMedia ||
navigator.mediaDevices.enumerateDevices()
.then(function(devices) {
devices.forEach(function(device) {
var canvas = document.getElementById('canvas'),
context = canvas.getContext('2d'),
video = document.getElementById('video'),
vendorUrl = window.URL || window.webkitURL;
});
})
navigator.getMedia({
video: true,
audio: true
}, function(stream){
video.src = vendorUrl.createObjectURL(stream);
video.play();
}, function(error){
//Error occured!
});
}
)();

Important Note
The code below has not been tested in real conditions
I only have one webcam attached to my computer and it may fail on some systems !
You just have to make a second call to the getUserMedia, and in the prompt choose an other device.
There may have been some way in some implementations to choose the device, using video constraints, but I think it's not in the still in draft specs anymore.
Here is a way, using a button, which will create a new video element with a new stream each time :
(function() {
// We declare once what our video elements should look like
var video = document.createElement('video');
video.width = 400;
video.height = 300;
video.autoplay = true;
video.controls = true;
// Where will those be appended in doc
var container = document.querySelector('.booth'),
butt = document.querySelector('button'),
vendorUrl = window.URL || window.webkitURL;
navigator.getMedia = navigator.getUserMedia ||
navigator.webkitGetUserMedia ||
navigator.mozGetUserMedia ||
navigator.msGetUserMedia;
function requestCam() {
navigator.getMedia({
video: true,
audio: true
}, function(stream) {
// clone our model video
var videoEl = video.cloneNode(true);
container.appendChild(videoEl);
// wait for the stream has been loaded in the video (kind of useless with autoplay = true)
videoEl.onloadedmetadata = function() {
this.play();
};
videoEl.src = vendorUrl.createObjectURL(stream);
}, function(error) {
console.log(error);
});
}
// attach the function to the button
butt.addEventListener('click', requestCam, false);
})();
button {
position: absolute;
}
<div class="booth">
<button>Add a new stream</button>
</div>
Fiddle for chrome which blocks stack-snippetĀ® getUserMedia() requests
To avoid the use of a button, you could chain your call to requestCam, but you'll have to call it after the last one was either approved or denied.
One way would be to insert it in the callback of the getUserMedia() ; but you may need to add some counter to avoid an infinite chain of calls.
(function() {
var video = document.createElement('video');
video.width = 400;
video.height = 300;
video.autoplay = true;
video.controls = true;
var container = document.querySelector('.booth'),
vendorUrl = window.URL || window.webkitURL;
navigator.getMedia = navigator.getUserMedia ||
navigator.webkitGetUserMedia ||
navigator.mozGetUserMedia ||
navigator.msGetUserMedia;
var maxVideos = 3;
function requestCam(count) {
// we made it ? stop right now.
if(count >= maxVideos) return;
navigator.getMedia({
video: true,
audio: true
}, function(stream) {
var videoEl = video.cloneNode(true);
container.appendChild(videoEl);
videoEl.onloadedmetadata = function() {this.play();};
videoEl.src = vendorUrl.createObjectURL(stream);
// increment our counter
requestCam(++count);
}, function(error) {
console.log(error);
});
}
// make our first call with count=0
requestCam(0);
})();
<div class="booth">
</div>
Fiddle for chrome

Related

How to access both webcams mediastream in chrome browser simultaneously? [duplicate]

guys i have two cameras that is
-the web camera
-the laptop camera
i want to stream those camera in a website
i already have some reference
here is some code that is working on jsfiddle
here
<video id="video" width="640" height="480" autoplay></video>
<button id="snap" class="sexyButton">Snap Photo</button>
<canvas id="canvas" width="640" height="480"></canvas>
<script>
// Put event listeners into place
window.addEventListener("DOMContentLoaded", function() {
// Grab elements, create settings, etc.
var canvas = document.getElementById("canvas"),
context = canvas.getContext("2d"),
video = document.getElementById("video"),
videoObj = { "video": true },
errBack = function(error) {
console.log("Video capture error: ", error.code);
};
// Put video listeners into place
if(navigator.getUserMedia) { // Standard
navigator.getUserMedia(videoObj, function(stream) {
video.src = stream;
video.play();
}, errBack);
} else if(navigator.webkitGetUserMedia) { // WebKit-prefixed
navigator.webkitGetUserMedia(videoObj, function(stream){
video.src = window.webkitURL.createObjectURL(stream);
video.play();
}, errBack);
} else if(navigator.mozGetUserMedia) { // WebKit-prefixed
navigator.mozGetUserMedia(videoObj, function(stream){
video.src = window.URL.createObjectURL(stream);
video.play();
}, errBack);
}
// Trigger photo take
document.getElementById("snap").addEventListener("click", function() {
context.drawImage(video, 0, 0, 640, 480);
});
}, false);
</script>
that example can only connects and select 1 camera
i want to select and view two of my camera, any suggestion or solution guys?
you can also give me the JS fiddle
You can create two different streams, one for each camera, and show them simultaneously in two <video> tags.
The list of available devices is available using navigator.mediaDevices.enumerateDevices(). After filtering the resulting list for only videoinputs, you have access to the deviceIds without needing permission from the user.
With getUserMedia you can then request a stream from the camera with id camera1Id using
navigator.mediaDevices.getUserMedia({
video: {
deviceId: { exact: camera1Id }
}
});
The resulting stream can be fed into a <video> (referenced here by vid) by calling vid.srcObject = stream.
I have done this for two streams from two webcams simultaneously.
You cannot access two cameras simultaneously. The API would indicate otherwise, but something underlying seems to prevent it from working as expected. You can verify this by opening https://simpl.info/getusermedia/sources/ or http://googlechrome.github.io/webrtc/samples/web/content/getusermedia-source/ in two completely seperate windows, despite being able to select two streams only one is active at once - if you pick the same one in both windows, then it shows in both places.
The only workaround I was able to do was to flip-flop between the two streams, then draw the video to a canvas. Doing this I was able to do captures at around 1 fps, unfortunately the camera resets between frames, on one of my cameras I had to put in a delay to allow the auto white balance to kick in to get a decent image.
function webcam() {
if (!navigator.getUserMedia) {
navigator.getUserMedia = navigator.getUserMedia || navigator.webkitGetUserMedia || navigator.mozGetUserMedia || navigator.msGetUserMedia;
}
if (!navigator.getUserMedia) {
return alert('getUserMedia not supported in this browser.');
}
var canvas = document.getElementById('canvas');
var context = canvas.getContext('2d');
var audioSource;
var cw = Math.floor(canvas.clientWidth / 2);
var ch = Math.floor(canvas.clientHeight/2);
//canvas.width = cw;
//canvas.height = ch;
//off dom video player
var video = document.createElement("video");
video.autoplay="autoplay";
video.addEventListener('playing', function(){
//delay for settling...
setTimeout(draw,1000,this,context,(currentSource*canvas.clientWidth/2),cw,ch);
},false);
function captureVideo() {
console.log("Capturing " + currentSource,videosources[currentSource]);
var mediaOptions = {
audio: {
optional: [{sourceId: audioSource}]
},
video: {
optional: [
{sourceId: videosources[currentSource].id}
]
}};
navigator.getUserMedia(mediaOptions, success, errorCallback);
}
var currentSource=0;
var videosources = [];
var lastStream;
function errorCallback(error){
console.log("navigator.getUserMedia error: ", error);
}
function success(stream) {
console.log("the stream" + currentSource,stream);
video.src = window.URL.createObjectURL(stream);
video.play();
lastStream=stream;
}
function next(){
if(lastStream){
lastStream.stop();
}
video.src = "";
if(currentSource < videosources.length-1){
currentSource+=1;
}
else
{
currentSource=0;
}
captureVideo();
}
function draw(v,c,l,w,h) {
if(v.paused || v.ended) return false;
console.log("drawing",l)
c.drawImage(v,l,0,w,h);
setTimeout(next,500);
}
MediaStreamTrack.getSources(function (sourceInfos) {
for (var i = 0; i != sourceInfos.length; ++i) {
var sourceInfo = sourceInfos[i];
if (sourceInfo.kind === 'audio') {
console.log(sourceInfo.id, sourceInfo.label || 'microphone');
audioSource=sourceInfo.id;
} else if (sourceInfo.kind === 'video') {
console.log(sourceInfo.id, sourceInfo.facing, sourceInfo.label || 'camera');
videosources.push(sourceInfo);
} else {
console.log('Some other kind of source: ', sourceInfo);
}
}
console.log("sources",videosources)
next();
});
}

Save images data of canvas in JavaScript

I am trying to capture image from webcam into a canvas and I would like to store this image data as an pixel array. How can I store it, please?
this is how I am drawing the picture from webcam to a context:
context = canvas.getcontext('2d');
captureButton.addEventListerner('click', ()=> {
context.drawImage(player, 0, 0, canvas.width. canvas.height);}
player is defined in html as <video id='player' controls autoplay></video>
best regards
This is something I've already done in my library jsia, so I'll expand it out for you here:
This doesn't work on Stack Exchange because of security restrictions, but you can see it working at https://mellen.github.io/jsiaExamples/barcodeReader
var canvas = document.getElementById('canvas');
var ctx = canvas.getContext('2d');
var vid = document.getElementById('vid');
function setupVideoCallback(videoElement, callbackCapture, callbackError, timeBetweenFrames)
{
var localMediaStream = null;
navigator.getUserMedia = ( navigator.getUserMedia ||
navigator.webkitGetUserMedia ||
navigator.mozGetUserMedia ||
navigator.msGetUserMedia );
var um = navigator.mediaDevices.getUserMedia({video: true}).then(handleVid).catch(vidErr);
if(!um)
{
um = navigator.getUserMedia({video: true}, handleVid, vidErr);
}
function handleVid(stream)
{
videoElement.srcObject = stream;
localMediaStream = stream;
}
function vidErr(e)
{
callbackError(e)
}
function capture()
{
if(localMediaStream)
{
callbackCapture();
}
}
setInterval(capture, timeBetweenFrames);
}
function drawVideoOnCanvas()
{
canvas.width = vid.clientWidth;
canvas.height = vid.clientHeight;
ctx.drawImage(vid, 0, 0);
}
setupVideoCallback(vid, drawVideoOnCanvas, e => console.log(e), 10);
<canvas id="canvas"></canvas>
<video autoplay style="visibility:hidden" id="vid"></video>

Store captured images using webcam and jQuery and HTML?

I'm doing one project using html and java-script but i'm new to java-script but i know little bit about js functionality..my project is based on Webcam and Captured images from my webcam i have completed upto Webcam and i takes pictures from my webcam and Now im problem is i want to save my captured images using captured button Id i tried but i cant get exact result.if any one knows please help me..
Here is my coding:'cam-video.html'
<div class="container" id="videophoto">
<div class="row">
<div class="col-sm-6 col-md-6">
<div id="container">
<video id="videoel" width="400" height="300" preload="auto" loop playsinline autoplay>
</video>
<canvas id="overlay" width="400" height="300"></canvas>
</div>
<button id="capture" class="pic">Capture</button><br />
<!--<img src="examples/media/audrey.jpg" />-->
<div class="alert alert-success" id="success-alert">
<button type="button" class="close" data-dismiss="alert">x</button>
<img src="" id="photo" alt="photo">
Here is my javascript:'mine.js'
<script>
var vid = document.getElementById('videoel');
var vid_width = vid.width;
var vid_height = vid.height;
var overlay = document.getElementById('overlay');
var overlayCC = overlay.getContext('2d');
/*********** Setup of video/webcam and checking for webGL support *********/
function enablestart() {
var starttbutton = document.getElementById('starttbutton');
starttbutton.value = "start";
starttbutton.disabled = null;
}
var insertAltVideo = function(video) {
// insert alternate video if getUserMedia not available
if (supports_video()) {
if (supports_webm_video()) {
video.src = "./media/cap12_edit.webm";
} else if (supports_h264_baseline_video()) {
video.src = "./media/cap12_edit.mp4";
} else {
return false;
}
return true;
} else return false;
}
function adjustVideoProportions() {
// resize overlay and video if proportions of video are not 4:3
// keep same height, just change width
var proportion = vid.videoWidth/vid.videoHeight;
vid_width = Math.round(vid_height * proportion);
vid.width = vid_width;
overlay.width = vid_width;
}
function gumSuccess( stream ) {
// add camera stream if getUserMedia succeeded
if ("srcObject" in vid) {
vid.srcObject = stream;
} else {
vid.src = (window.URL && window.URL.createObjectURL(stream));
}
vid.onloadedmetadata = function() {
adjustVideoProportions();
vid.play();
}
vid.onresize = function() {
adjustVideoProportions();
if (trackingStarted) {
ctrack.stop();
ctrack.reset();
ctrack.start(vid);
}
}
}
function gumFail() {
// fall back to video if getUserMedia failed
insertAltVideo(vid);
document.getElementById('gum').className = "hide";
document.getElementById('nogum').className = "nohide";
alert("There was some problem trying to fetch video from your webcam, using a fallback video instead.");
}
navigator.getUserMedia = navigator.getUserMedia || navigator.webkitGetUserMedia || navigator.mozGetUserMedia || navigator.msGetUserMedia;
window.URL = window.URL || window.webkitURL || window.msURL || window.mozURL;
// set up video
if (navigator.mediaDevices) {
navigator.mediaDevices.getUserMedia({video : true}).then(gumSuccess).catch(gumFail);
} else if (navigator.getUserMedia) {
navigator.getUserMedia({video : true}, gumSuccess, gumFail);
} else {
insertAltVideo(vid);
document.getElementById('gum').className = "hide";
document.getElementById('nogum').className = "nohide";
alert("Your browser does not seem to support getUserMedia, using a fallback video instead.");
}
vid.addEventListener('canplay', enablestart, false);
/*********** Code for face tracking *********/
var ctrack = new clm.tracker();
ctrack.init();
var trackingStarted = false;
function startVideo() {
// start video
vid.play();
// start tracking
ctrack.start(vid);
// var time=setTimeout("alert('Two Faces Not Allowed')",3500);
trackingStarted = true;
// start loop to draw face
drawLoop();
}
function drawLoop() {
requestAnimFrame(drawLoop);
overlayCC.clearRect(0, 0, vid_width, vid_height);
//psrElement.innerHTML = "score :" + ctrack.getScore().toFixed(4);
if (ctrack.getCurrentPosition()) {
ctrack.draw(overlay);
document.getElementById('photo').setAttribute('src', data);
}
}
/*********** Code for stats **********/
stats = new Stats();
stats.domElement.style.position = 'absolute';
stats.domElement.style.top = '0px';
document.getElementById('container').appendChild( stats.domElement );
// update stats on every iteration
document.addEventListener('clmtrackrIteration', function(event) {
stats.update();
}, false);
</script>
<script type="text/javascript">
(function() {
var streaming = false,
video = document.querySelector('#video'),
canvas = document.querySelector('#canvas'),
buttoncontent = document.querySelector('#buttoncontent'),
photo = document.querySelector('#photo'),
startbutton = document.querySelector('#startbutton'),
width = 320,
height = 0;
navigator.getMedia = (navigator.getUserMedia ||
navigator.webkitGetUserMedia ||
navigator.mozGetUserMedia ||
navigator.msGetUserMedia);
navigator.getMedia({
video: true,
audio: false
},
function(stream) {
if (navigator.mozGetUserMedia) {
video.mozSrcObject = stream;
} else {
var vendorURL = window.URL || window.webkitURL;
video.src = vendorURL.createObjectURL(stream);
}
video.play();
},
function(err) {
console.log("An error occured! " + err);
}
);
video.addEventListener('canplay', function(ev) {
if (!streaming) {
height = video.videoHeight / (video.videoWidth / width);
video.setAttribute('width', width);
video.setAttribute('height', height);
canvas.setAttribute('width', width);
canvas.setAttribute('height', height);
streaming = true;
}
}, false);
function takepicture(data_uri) {
video.style.display = "none";
canvas.style.display = "block";
startbutton.innerText= "RETAKE";
canvas.width = width;
canvas.height = height;
canvas.getContext('2d').drawImage(videoel, 0, 0, width, height);
var data = canvas.toDataURL('image/png');
photo.setAttribute('src', data);
var data = canvas.toDataURL('image/webp');
document.getElementById('photo').setAttribute('src', data);
document.getElementById("two").value = data;
document.myForm.sub();
document.getElementById('capture').innerHTML =
'<h2>Here is your image:</h2>' +
'<img src="' + data_uri + '"/>';
document.myForm.sub();
}
startbutton.addEventListener('click', function(ev) {
if(startbutton.innerText==="CAPTURE")
{
takepicture();
}
else
{
video.style.display = "block";
canvas.style.display = "none";
startbutton.innerText= "CAPTURE";
}
ev.preventDefault();
}, false);
})();
</script>
<script>
$(document).ready(function(){
$("#startbutton").click(function(){
$("#choosephoto").hide(1000);
});
});
</script>
Here is the code that i have tried how to save my captured images from webcam..
function takepicture(data_uri) {
video.style.display = "none";
canvas.style.display = "block";
startbutton.innerText= "RETAKE";
canvas.width = width;
canvas.height = height;
canvas.getContext('2d').drawImage(videoel, 0, 0, width, height);
var data = canvas.toDataURL('image/png');
photo.setAttribute('src', data);
var data = canvas.toDataURL('image/webp');
document.getElementById('photo').setAttribute('src', data);
document.getElementById("two").value = data;
document.myForm.sub();
document.getElementById('capture').innerHTML =
'<h2>Here is your image:</h2>' +
'<img src="' + data_uri + '"/>';
document.myForm.sub();
}
//$
the above part of code is i have tried.Can anyone help Me please.

How to allow the access automatically to the webcam

I am trying to develop a web page that access to my webcam using the following JS code:
(function( $ ){
$.fn.html5_qrcode = function(qrcodeSuccess, qrcodeError, videoError) {
'use strict';
var height = this.height();
var width = this.width();
if (height == null) {
height = 250;
}
if (width == null) {
width = 300;
}
var vidTag = '<video id="html5_qrcode_video" width="' + width + 'px" height="' + height + 'px"></video>'
var canvasTag = '<canvas id="qr-canvas" width="' + (width - 2) + 'px" height="' + (height - 2) + 'px" style="display:none;"></canvas>'
this.append(vidTag);
this.append(canvasTag);
var video = $('#html5_qrcode_video').get(0);
var canvas;
var context;
var localMediaStream;
$('#qr-canvas').each(function(index, element) {
canvas = element;
context = element.getContext('2d');
});
var scan = function() {
if (localMediaStream) {
context.drawImage(video, 0, 0, 307,250);
try {
qrcode.decode();
} catch(e) {
qrcodeError(e);
}
setTimeout(scan, 500);
} else {
setTimeout(scan,500);
}
}//end snapshot function
window.URL = window.URL || window.webkitURL || window.mozURL || window.msURL;
navigator.getUserMedia = navigator.getUserMedia || navigator.webkitGetUserMedia || navigator.mozGetUserMedia || navigator.msGetUserMedia;
var successCallback = function(stream) {
video.src = (window.URL && window.URL.createObjectURL(stream)) || stream;
localMediaStream = stream;
video.play();
setTimeout(scan,1000);
}
// Call the getUserMedia method with our callback functions
if (navigator.getUserMedia) {
navigator.getUserMedia({video: true}, successCallback, videoError);
} else {
console.log('Native web camera streaming (getUserMedia) not supported in this browser.');
// Display a friendly "sorry" message to the user
}
qrcode.callback = qrcodeSuccess;
}; // end of html5_qrcode
})( jQuery );
I run my application and it works, but before that the cam is opened, I've got the access permission window, so I wander if there is any solution that allow me to open the webcam without ask.
For obvious reasons you can not turn people webcams on and start recording without consent.
Locally you can open up for specific features without asking with some vendors like Chrome by setting up policies. I have added abit of links in the comments

HTML5 Webcam Capture scaling problems in Chrome

I have a page which uses the HTML5 getUserMedia functionality to capture an image from the user's webcam. I am having serious inconsistencies in the scaling of the captured image when it is rendered to the canvas. Only the top corner of the image is actually rendered, as if rather than capturing the video element, it is slicing a piece from the underlying stream. Oddly enough, when I go to most other sites using this technology, I do not have this problem. I am running Chrome 29.0.1547.76 m on Windows 7, running on a 2011 MacBook Pro.
<!DOCTYPE html>
<html lang="en">
<head>
<script type="text/javascript">
var openCameraButton;
var takePictureButton;
var mediaStream;
var video;
var canvas;
var context;
navigator.getMedia = ( navigator.getUserMedia ||
navigator.webkitGetUserMedia ||
navigator.mozGetUserMedia ||
navigator.msGetUserMedia);
function onLoad(){
video = document.querySelector('video');
canvas = document.querySelector('canvas');
context = canvas.getContext('2d');
context.imageSmoothingEnabled = true;
context.webkitImageSmoothingEnabled = true;
context.mozImageSmoothingEnabled = true;
};
function openCamera(){
navigator.getMedia(
{ video:true, audio: false },
function(localMediaStream){
mediaStream = localMediaStream;
video.src=window.URL.createObjectURL(localMediaStream);
},
function(err){
alert('Unable to support live capture.');
}
);
}
function takePicture(){
var w = video.videoWidth;
var h = video.videoHeight;
context.drawImage(video,0,0,w,h);
canvas.style.display='block';
video.style.display='none';
}
</script>
</head>
<body onload="onLoad();">
<div>
<video autoplay style="width:640px; height:480px;"></video>
<canvas style="width:640px; height:480px; display:none;"></canvas>
</div>
<div>
<button id="openCameraButton" type="button" onclick="openCamera();" >Open Camera</button>
<button id="takePictureButton" type="button" onclick="takePicture();" >Take Picture</button>
</div>
</body>
</html>
Any ideas?
please try this:
function takePicture(){
var w = video.videoWidth;
var h = video.videoHeight;
canvas.width = w;
canvas.height = h;
context.drawImage(video,0,0,w,h);
canvas.style.display='block';
video.style.display='none';
}

Categories