making a page to take snapshots with the webcam. but suddenly it stopped working on every computer. Did i make a typo i cant see myself, or does anyone has an idea too fix this??
added the draw in bit aswell
// 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 },
image_format= "jpeg",
jpeg_quality= 85,
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();
$("#snap").show();
}, errBack);
} else if(navigator.webkitGetUserMedia) { // WebKit-prefixed
navigator.webkitGetUserMedia(videoObj, function(stream){
video.src = window.URL.createObjectURL(stream);
video.play();
$("#snap").show();
}, errBack);
} else if(navigator.mozGetUserMedia) { // moz-prefixed
navigator.mozGetUserMedia(videoObj, function(stream){
video.src = window.URL.createObjectURL(stream);
video.play();
$("#snap").show();
}, errBack);
}
// Get-Save Snapshot - image
document.getElementById("snap").addEventListener("click", function() {
context.drawImage(video, 0, 0, 640, 480);
// the fade only works on firefox?
$("#video").fadeOut("slow");
$("#canvas").fadeIn("slow");
$("#snap").hide();
$("#reset").show();
$("#upload").show();
You never draw your video to the canvas in this part of the code.
Also, navigator.getUserMedia is not the "standard" anymore, it has been updated to navigator.mediaDevices.getUserMedia which will return a Promise.
var ctx = c.getContext('2d');
var vid = document.createElement('video');
vid.oncanplay = function() {
c.width = this.videoWidth;
c.height = this.videoHeight;
draw();
}
navigator.mediaDevices.getUserMedia({
video: true
}).then((stream) => {
vid.srcObject = stream;
vid.play();
});
function draw() {
ctx.drawImage(vid, 0, 0);
requestAnimationFrame(draw);
}
<canvas id="c"></canvas>
And a fiddle for chrome since it doesn't allow gUM in SO-snippets.
Ps : if you need to support older implementations, check the official WebRTC polyfill, adapter.js
Related
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();
});
}
My script:
var srgt_socket = false;
var canvas = document.getElementById('canvas');
var context = canvas.getContext('2d');
var video = document.getElementById('video');
window.srgt_socket = new WebSocket("ws://185.25.150.192:1987");
window.srgt_socket.addEventListener('open', function (event) {
window.srgt_socket.send('Hello Server!');
start_send();
});
window.srgt_socket.addEventListener('close', function (event) {
console.log('closing');
});
function start_send() {
var mediaConfig = { video: true };
var errBack = function(e) {
console.log('An error has occurred!', e)
};
// Put video listeners into place
if(navigator.mediaDevices && navigator.mediaDevices.getUserMedia) {
navigator.mediaDevices.getUserMedia(mediaConfig).then(function(stream) {
video.src = window.URL.createObjectURL(stream);
video.play();
});
}
/* Legacy code below! */
else if(navigator.getUserMedia) { // Standard
navigator.getUserMedia(mediaConfig, function(stream) {
video.src = stream;
video.play();
}, errBack);
} else if(navigator.webkitGetUserMedia) { // WebKit-prefixed
navigator.webkitGetUserMedia(mediaConfig, function(stream){
video.src = window.webkitURL.createObjectURL(stream);
video.play();
}, errBack);
} else if(navigator.mozGetUserMedia) { // Mozilla-prefixed
navigator.mozGetUserMedia(mediaConfig, function(stream){
video.src = window.URL.createObjectURL(stream);
video.play();
}, errBack);
}
setInterval(function(){
context.drawImage(video, 0, 0, 320, 100);
let canvas = document.getElementById('canvas');
let img = document.getElementById('img');
img.src = canvas.toDataURL("image/png");
let data = {
src : canvas.toDataURL("image/png"),
}
window.srgt_socket.send(JSON.stringify(data));
}, 33);
}
I'm using websocket. On server side I use node.js. I don't know why connection is closed after a while (it works for few miliseconds). Data is send then connection is closing. I'm runing this script from localhost.
Right now, I am trying to create a "snapchat" kind of web app, for my education.
The app makes use of HTML5 tags, like video and canvas.
Then i use getUserMedia to get the camera output, but my problem is that i can't get the video tag to fill the whole screen.
I have tried everything from width: 100%; height: 100%;, height: 100vh, jquery, but that messed up the getUserMedia function, so it didn't even work.
Right now, this is my code:
HTML File:
<!doctype html>
<html lang="da">
<head>
<title>Camera output</title>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link href="css/style.css" type="text/css" rel="stylesheet">
<script src="jquery-3.1.1.min.js"></script>
</head>
<body>
<video id="video" autoplay></video>
<button id="snap" class="snapButton">Snap Photo</button>
<canvas id="canvas" width="640" height="480"></canvas>
<script src="js/script.js" type="text/javascript"></script>
</body>
</html>
CSS File:
* {
margin: 0;
padding: 0;
}
#video {
-webkit-transition: all 1s ease;
-moz-transition: all 1s ease;
-o-transition: all 1s ease;
transition: all 1s ease;
transform-origin: center center;
}
JS File:
function setElementFullScreen(selector) {
var ele= $(selector);
// Set left/top, can be done in directly in css
ele.css('top',0).css('left',0);
// Set size from window
ele.height($(window).height()).width($(window).width());
}
$(document).ready(function () {
setElementFullScreen('video');
});
// Add resize event
$(window).on('resize', function () {
setElementFullScreen('video');
});
// Put event listeners into place
window.addEventListener("DOMContentLoaded", function() {
// Grab elements, create settings, etc.
var canvas = document.getElementById('canvas');
var context = canvas.getContext('2d');
var video = document.getElementById('video');
var mediaConfig = { video: true };
var errBack = function(e) {
console.log('An error has occurred!', e)
};
// Put video listeners into place
if(navigator.mediaDevices && navigator.mediaDevices.getUserMedia) {
navigator.mediaDevices.getUserMedia(mediaConfig).then(function(stream) {
video.src = window.URL.createObjectURL(stream);
video.play();
});
}
/* Legacy code below! */
else if(navigator.getUserMedia) { // Standard
navigator.getUserMedia(mediaConfig, function(stream) {
video.src = stream;
video.play();
}, errBack);
} else if(navigator.webkitGetUserMedia) { // WebKit-prefixed
navigator.webkitGetUserMedia(mediaConfig, function(stream){
video.src = window.webkitURL.createObjectURL(stream);
video.play();
}, errBack);
} else if(navigator.mozGetUserMedia) { // Mozilla-prefixed
navigator.mozGetUserMedia(mediaConfig, 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);
So my question is: Is there any way to make the video tag fill every bit of a phone screen? I tried on desktop, it had no problem with filling in horizontally.
Thanks in advance.
Try this,
<video id="video" autoplay></video>
<script>
var elem = document.getElementById("myvideo");
if(elem.requestFullscreen) {
elem.requestFullscreen();
}
</script>
This will ask the browser to use full screen on video playback. I think you'll have some issues with browser compatibility on mobile devices.
Reference:
https://developer.mozilla.org/en-US/docs/Web/API/Fullscreen_API
Edit:
Seems to be your ele.height($(window).height()).width($(window).width()); giving you trouble. Try logging window.height() and window.width() to your debugging console to determine what it returns.
If you haven't already, look at this:
https://www.w3schools.com/tags/canvas_drawimage.asp
Here is a tutorial with similar application examples:
https://www.html5rocks.com/en/tutorials/getusermedia/intro/
Here you have a snipplet with working example.
function setElementFullScreen(selector) {
var ele = $(selector);
// Get window size
var maxWidth = $(window).width();
var maxHeight = $(window).height();
// Get video size
var videoWidth = ele.width();
var videoHeight = ele.height();
// Calcul relative size
if (maxWidth > maxHeight) {
var relatifWidth = videoWidth / (videoHeight / maxHeight);
var relatifHeight = maxHeight;
} else {
var relatifWidth = maxWidth;
var relatifHeight = videoHeight / (videoWidth / maxWidth);
}
// Check if result size is not bigger than canvas size
if (relatifWidth > maxWidth) {
relatifWidth = maxWidth;
relatifHeight = (relatifWidth * videoHeight) / videoWidth;
} else if (relatifHeight > maxHeight) {
relatifHeight = maxHeight;
relatifWidth = (relatifHeight * videoWidth) / videoHeight;
}
// Set size from window
ele.height(relatifHeight).width(relatifWidth);
}
$(document).ready(function () {
setElementFullScreen('#video');
// Put event listeners into place
window.addEventListener("DOMContentLoaded", function () {
// Grab elements, create settings, etc.
var canvas = document.getElementById('canvas');
var context = canvas.getContext('2d');
var video = document.getElementById('video');
var mediaConfig = {video: true};
var errBack = function (e) {
console.log('An error has occurred!', e)
};
// Put video listeners into place
if (navigator.mediaDevices && navigator.mediaDevices.getUserMedia) {
navigator.mediaDevices.getUserMedia(mediaConfig).then(function (stream) {
video.src = window.URL.createObjectURL(stream);
video.play();
});
}
/* Legacy code below! */
else if (navigator.getUserMedia) { // Standard
navigator.getUserMedia(mediaConfig, function (stream) {
video.src = stream;
video.play();
}, errBack);
} else if (navigator.webkitGetUserMedia) { // WebKit-prefixed
navigator.webkitGetUserMedia(mediaConfig, function (stream) {
video.src = window.webkitURL.createObjectURL(stream);
video.play();
}, errBack);
} else if (navigator.mozGetUserMedia) { // Mozilla-prefixed
navigator.mozGetUserMedia(mediaConfig, 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);
});
// Add resize event
$(window).on('resize', function () {
setElementFullScreen('video');
});
video {
margin: 0;
padding: 0;
top: 0;
left: 0;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<video id="video" autoplay>
<source src="http://techslides.com/demos/sample-videos/small.mp4" type="video/mp4">
</video>
<br>
<button id="snap" class="snapButton">Snap Photo</button>
<br>
<canvas id="canvas" width="640" height="480"></canvas>
I'm trying to take a webcam feed - (landscape format), cut out the middle bit (portrait format) and have it render to a canvas so that it fills the screen portrait 1080px by 1920px (for this I scale the bit I cut out by 3.8). I then need to flip this canvas so the image is mirrored. I've succeeded in cutting out the middle bit, and rendering this to the canvas... I just cant figure out how to flip it.
Edit
Thank you to all the people who have pointed me at context.scale(-1, 1) - my problem is, I'm already using scale... I think my issues are to do with saving the context, but everything I try has failed to work?
<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: {
mandatory: {
minWidth: 1280,
minHeight: 720,
/*Added by Chad*/
maxWidth: 1280,
maxHeight: 720
}
}
},
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.URL.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);
}
/*
video : video source tag
320,0 : the shift coords
320,180 : the canvas size
0,0 : no shift in the canvas
640,360 : important ! it’s the native resolution of video source
*/
context.scale(3.8,3.8);
function loop(){
context.drawImage(video, 450, 0, 1080, 1920, 0, 0, 720, 1280);
setTimeout(loop, 1000 / 30);
}
loop();
}, false);
</script>
<video id="video" height="1080" width="1920" autoplay></video>
<canvas id="canvas" height="1920" width="1080"></canvas>
// 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: {
mandatory: {
minWidth: 1280,
minHeight: 720,
/*Added by Chad*/
maxWidth: 1280,
maxHeight: 720
}
}
},
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.URL.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);
}
/*
video : video source tag
320,0 : the shift coords
320,180 : the canvas size
0,0 : no shift in the canvas
640,360 : important ! it’s the native resolution of video source
*/
context.scale(-3.8,3.8);
context.translate(-720,0);
function loop(){
context.drawImage(video, 450, 0, 1080, 1920, 0, 0, 720, 1280);
setTimeout(loop, 1000 / 30);
}
loop();
}, false);
You shouldn't do the crop using the ctx.scale and ctx.translate methods.
Instead, on load of your video, calculate the cropping positions and then in the call of your drawing loop, apply those calculated positions.
When done, it's easy to apply the context.scale(-1, 1); as proposed by #Mahout.
Note that you'll also need to context.translate(canvas.width, 0); before applying the scale().
I refactored your code because the way you were requesting the video mandatories is out of date (as is chrome about it).
I changed your loop too, in order to call it only when the video has loaded, no need to try to draw anything that doesn't exists yet, and I changed your setTimeout with the requestAnimationFrame method, which fires approximatly at 30fps.
// Put event listeners into place
window.addEventListener("DOMContentLoaded", function() {
// Grab elements, create settings, etc.
var canvas = document.getElementById("canvas"),
context = canvas.getContext("2d"),
// we don't need to append the video to the document
video = document.createElement("video"),
videoObj =
navigator.getUserMedia || navigator.mozGetUserMedia ? // our browser is up to date with specs ?
{
video: {
width: { min: 1280, max: 1280 },
height: { min: 720, max: 720 },
require: ['width', 'height']
}
}:
{
video: {
mandatory: {
minWidth: 1280,
minHeight: 720,
maxWidth: 1280,
maxHeight: 720
}
}
},
errBack = function(error) {
console.log("Video capture error: ", error.code);
};
// create a crop object that will be calculated on load of the video
var crop;
// create a variable that will enable us to stop the loop.
var raf;
navigator.getUserMedia = navigator.getUserMedia || navigator.webkitGetUserMedia || navigator.mozGetUserMedia;
// Put video listeners into place
navigator.getUserMedia(videoObj, function(stream) {
video.srcObject = stream;
video.onplaying = function(){
var croppedWidth = ( Math.min(video.videoHeight, canvas.height) / Math.max(video.videoHeight,canvas.height)) * Math.min(video.videoWidth, canvas.width),
croppedX = ( video.videoWidth - croppedWidth) / 2;
crop = {w:croppedWidth, h:video.videoHeight, x:croppedX, y:0};
// call our loop only when the video is playing
raf = requestAnimationFrame(loop);
};
video.onpause = function(){
// stop the loop
cancelAnimationFrame(raf);
}
video.play();
}, errBack);
function loop(){
context.drawImage(video, crop.x, crop.y, crop.w, crop.h, 0, 0, canvas.width, canvas.height);
raf = requestAnimationFrame(loop);
}
// now that our video is drawn correctly, we can do...
context.translate(canvas.width, 0);
context.scale(-1,1);
}, false);
body,html{margin:0}
canvas{ border:1px solid;}
<canvas id="canvas" height="1920" width="1080"></canvas>
jsfiddle for chrome
For flipping horizontally you can use context.scale(-1, 1);.
From http://www.html5canvastutorials.com/advanced/html5-canvas-mirror-transform-tutorial/
EDIT
As a last resort, this CSS could be used
#canvas {
-moz-transform: scaleX(-1);
-o-transform: scaleX(-1);
-webkit-transform: scaleX(-1);
transform: scaleX(-1);
filter: FlipH;
-ms-filter: "FlipH";
}
If required, this could all be applied dynamically with javascript. Untested but should hopefully work!
Quick Answer (Tried and Tested):
let context = document.getElementById("canvas").getContext("2d");
context.translate(width, 0)
context.scale(-1, 1)
context.drawImage(image, 0, 0, width, height)
I want to start camera when clicking on the button and show the preview through javascript.
function emitStream() {
// Asking permission to get the user media.
// If permission granted, assign the stream to the HTML 5 video element.
navigator.webkitGetUserMedia({
video: true,
audio: true
}, function(stream) {
that._video = document.querySelector('video');
that._video.src = window.URL.createObjectURL(stream);
});
function takePicture() {
// Assigning the video stream to the canvas to create a picture.
that._canvas = document.querySelector('canvas');
var context = that._canvas.getContext('2d');
context.clearRect(0, 0, 0, 0);
context.drawImage(that._video, 0, 0, 400, 300);
}
}
This code is published or written by David Walsh - Camera and Video Control with HTML5 .. Try the following code----
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) { // Firefox-prefixed
navigator.mozGetUserMedia(videoObj, function(stream){
video.src = window.URL.createObjectURL(stream);
video.play();
}, errBack);
}
}, false);
The trigger to is as follows:---
document.getElementById("snap").addEventListener("click", function() {
context.drawImage(video, 0, 0, 640, 480);
});