How do you enable the front camera on a Webview? I have enable the features in AndroidManifest.xml
<uses-feature android:name="android.hardware.camera" android:required="true" />
<uses-feature android:name="android.hardware.camera.front" android:required="true" />
The camera is not going to be used for taking photos or recording, just to switch on the front camera.
When I go to the website using the phone browser the phone camera works once allow the prompt message. How can this work with a webview?
In the html file has a Canvas and Video tag that displays webcam It doesn't record or take pictures it just shows you the camera view.
Here is the html code
<canvas id="inCanvas" width="500" height="500" style="display:none"></canvas>
<video id="inputVideo" width="100" height="100" autoplay loop ></video>
It work with webcam but not with webview in android.
I didnt quite understand, but i thing there could one of the following two, what you want.
1) access camera and just show the video on the screen(not capturing
image):
html:
<canvas id='canvas' width='100' height='100'></canvas>
js:
var onFailSoHard = function(e)
{
console.log('failed',e);
}
window.URL = window.URL || window.webkitURL ;
navigator.getUserMedia = navigator.getUserMedia || navigator.webkitGetUserMedia;
var video = document.querySelector('video');
if(navigator.getUserMedia)
{
navigator.getUserMedia({video: true},function(stream) {
video.src = window.URL.createObjectURL(stream);
},onFailSoHard);
}
var canvas = document.getElementById('canvas');
var ctx = canvas.getContext('2d');
setInterval(function(){
ctx.drawImage(video,0,0);
}, 100);
}
2) capture image from the camera:
here is the doc for that.
navigator.camera.getPicture(onSuccess, onFail, { quality: 50,
destinationType: Camera.DestinationType.DATA_URL
});
function onSuccess(imageData) {
var image = document.getElementById('myImage');
image.src = "data:image/jpeg;base64," + imageData;
}
function onFail(message) {
alert('Failed because: ' + message);
}
I would use something similar to the below as a script to access the phone camera.
<script>
var errorCallback = function(e) {
console.log('Rejected!', e);
};
// Not showing vendor prefixes.
navigator.getUserMedia({video: true, audio: true}, function(localMediaStream) {
var video = document.querySelector('video');
video.src = window.URL.createObjectURL(localMediaStream);
// Note: onloadedmetadata doesn't fire in Chrome when using it with getUserMedia.
// See crbug.com/110938.
video.onloadedmetadata = function(e) {
// Ready to go. Do some stuff.
};
}, errorCallback);
</script>
Used the following tutorial to help me.
Hope it sets yuo on the right track :)
Related
I am trying to record and download video of canvas element using official MediaStream Recording API
<!DOCTYPE html>
<html>
<body>
<h1>Lets test mediaRecorder</h1>
<canvas id="myCanvas" width="200" height="100" style="border:1px solid #d3d3d3;">
Your browser does not support the HTML canvas tag.
</canvas>
<script>
var c = document.getElementById("myCanvas");
var ctx = c.getContext("2d");
ctx.font = "30px Arial";
ctx.fillText("Hello World", 10, 50);
const stream = c.captureStream(25);
var recordedChunks = [];
console.log(stream);
var options = { mimeType: "video/webm; codecs=vp9" };
mediaRecorder = new MediaRecorder(stream, options);
mediaRecorder.ondataavailable = handleDataAvailable;
mediaRecorder.start();
function handleDataAvailable(event) {
console.log("data-available");
if (event.data.size > 0) {
recordedChunks.push(event.data);
console.log(recordedChunks);
download();
} else {
// ...
}
}
function download() {
var blob = new Blob(recordedChunks, {
type: "video/webm"
});
var url = URL.createObjectURL(blob);
var a = document.createElement("a");
document.body.appendChild(a);
a.style = "display: none";
a.href = url;
a.download = "test.webm";
a.click();
window.URL.revokeObjectURL(url);
}
// demo: to download after 10 sec
setTimeout(event => {
console.log("stopping");
mediaRecorder.stop();
}, 10000);
</script>
</body>
</html>
code is working and I am able to download test.webm but I guess that does not have any data as I am not seeing any content while playing this file in VLC Media Player
What I am missing to make it working?
You are facing a few bugs here.
First one is a bit excusable, Chrome doesn't generate seekable webm files. This is because of how media files are built and how the MediaRecorder API works. For them to be able to add this information they'd have to keep the chunk where the metadata is in order to add this information when the recording is done.
I'm not too sure what Firefox does differently here, but VLC prefers their file.
An other Chrome bug, a lot less excusable, is that they don't pass a new frame to the MediaRecorder until we draw on the source canvas again.
So since in your case you are not drawing anything after you started the MediaRecorder, you'll get nothing in the output...
To workaround that, simply drawing a frame right before we stop the recorder should have been enough, except that there is nothing letting us know exactly when the browser will push that frame to the recorder...
So the only working workaround here is to draw on the canvas continuously while we record it. The good thing is that it doesn't need to be painting anything new: we can trick the browser in thinking something new was painted by drawing a transparent rectangle.
A final note, while Chrome does support exporting the canvas with transparency, not all browsers can and even when supported most players have a default black background. So be sure to draw yourself a background in an other color when you record it.
All that said, here is a fixed demo:
var c = document.getElementById("myCanvas");
var ctx = c.getContext("2d");
// draw a white background
ctx.fillStyle = "white";
ctx.fillRect(0, 0, c.width, c.height);
ctx.fillStyle = "black";
ctx.font = "30px Arial";
ctx.fillText("Hello World", 10, 50);
const stream = c.captureStream(25);
var recordedChunks = [];
var options = {};
mediaRecorder = new MediaRecorder(stream, options);
mediaRecorder.ondataavailable = handleDataAvailable;
mediaRecorder.start();
// Chrome requires we draw on the canvas while recording
mediaRecorder.onstart = animationLoop;
function animationLoop() {
// draw nothing, but still draw
ctx.globalAlpha = 0;
ctx.fillRect(0, 0, 1, 1);
// while we're recording
if (mediaRecorder.state !== "inactive") {
requestAnimationFrame(animationLoop);
}
}
// wait for the stop event to export the final video
// the dataavailable can fire before
mediaRecorder.onstop = (evt) => download();
function handleDataAvailable(event) {
recordedChunks.push(event.data);
}
function download() {
var blob = new Blob(recordedChunks, {
type: "video/webm"
});
var url = URL.createObjectURL(blob);
// exporting to a video element for that demo
// the downloaded video will still not work in some programs
// For this one would need to fix the markers using something like ffmpeg.
var video = document.getElementById('video');
video.src = url;
// hack to make the video seekable in the browser
// see https://stackoverflow.com/questions/38443084/
video.onloadedmetadata = (evt) => {
video.currentTime = 10e6;
video.addEventListener("seeked", () => video.currentTime = 0, {
once: true
})
}
}
setTimeout(() => {
console.clear();
mediaRecorder.stop();
}, 10000);
console.log("please wait while recording (10s)");
<h1>Lets test mediaRecorder</h1>
<canvas id="myCanvas" width="200" height="100" style="border:1px solid #d3d3d3;">
Your browser does not support the HTML canvas tag.
</canvas>
<video controls id="video"></video>
basically people take a pic with their phone and I should crop the pic and add a watermark.
how can I add a watermark to my picture?
my code below
function takeSnapshot(){
// Here we're using a trick that involves a hidden canvas element.
var hidden_canvas = document.querySelector('canvas'),
context = hidden_canvas.getContext('2d');
var width = 480,
height = 480;
hidden_canvas.width = width;
hidden_canvas.height = height;
// Make a copy of the current frame in the video on the canvas.
context.drawImage(video, 100, 0, 480, 480, 0, 0, hidden_canvas.width, hidden_canvas.width);
// Turn the canvas image into a dataURL that can be used as a src for our photo.
return hidden_canvas.toDataURL('image/png');
}
html
<div class="container">
<div class="app">
Touch here to start the app.
<video id="camera-stream" width="640" height="480"></video>
<img id="snap">
<img src="http://localhost/selfie/face-pic.png" style="z-index:100;position:absolute; top:0;left:0;"/>
<p id="error-message"></p>
<div class="controls" style="z-index:200;">
<i class="material-icons">delete</i>
<i class="material-icons">camera_alt</i>
<i class="material-icons">file_download</i>
</div>
<!-- Hidden canvas element. Used for taking snapshot of video. -->
<canvas>
</canvas>
</div>
</div>
js
document.addEventListener('DOMContentLoaded', function () {
// References to all the element we will need.
var video = document.querySelector('#camera-stream'),
image = document.querySelector('#snap'),
start_camera = document.querySelector('#start-camera'),
controls = document.querySelector('.controls'),
take_photo_btn = document.querySelector('#take-photo'),
delete_photo_btn = document.querySelector('#delete-photo'),
download_photo_btn = document.querySelector('#download-photo'),
error_message = document.querySelector('#error-message');
// The getUserMedia interface is used for handling camera input.
// Some browsers need a prefix so here we're covering all the options
navigator.getMedia = ( navigator.getUserMedia ||
navigator.webkitGetUserMedia ||
navigator.mozGetUserMedia ||
navigator.msGetUserMedia);
if(!navigator.getMedia){
displayErrorMessage("Your browser doesn't have support for the navigator.getUserMedia interface.");
}
else{
// Request the camera.
navigator.getMedia(
{
video: true
},
// Success Callback
function(stream){
// Create an object URL for the video stream and
// set it as src of our HTLM video element.
video.srcObject=stream;
// Play the video element to start the stream.
video.play();
video.onplay = function() {
showVideo();
};
},
// Error Callback
function(err){
displayErrorMessage("There was an error with accessing the camera stream: " + err.name, err);
}
);
}
// Mobile browsers cannot play video without user input,
// so here we're using a button to start it manually.
start_camera.addEventListener("click", function(e){
e.preventDefault();
// Start video playback manually.
video.play();
showVideo();
});
take_photo_btn.addEventListener("click", function(e){
e.preventDefault();
var snap = takeSnapshot();
// Show image.
image.setAttribute('src', snap);
image.classList.add("visible");
// Enable delete and save buttons
delete_photo_btn.classList.remove("disabled");
download_photo_btn.classList.remove("disabled");
// Set the href attribute of the download button to the snap url.
download_photo_btn.href = snap;
// Pause video playback of stream.
video.pause();
});
delete_photo_btn.addEventListener("click", function(e){
e.preventDefault();
// Hide image.
image.setAttribute('src', "");
image.classList.remove("visible");
// Disable delete and save buttons
delete_photo_btn.classList.add("disabled");
download_photo_btn.classList.add("disabled");
// Resume playback of stream.
video.play();
});
function showVideo(){
// Display the video stream and the controls.
hideUI();
video.classList.add("visible");
controls.classList.add("visible");
}
function takeSnapshot(){
// Here we're using a trick that involves a hidden canvas element.
var hidden_canvas = document.querySelector('canvas'),
context = hidden_canvas.getContext('2d');
var width = 480,
height = 480;
hidden_canvas.width = width;
hidden_canvas.height = height;
// Make a copy of the current frame in the video on the canvas.
context.drawImage(video, 100, 0, 480, 480, 0, 0, hidden_canvas.width, hidden_canvas.width);
// Turn the canvas image into a dataURL that can be used as a src for our photo.
return hidden_canvas.toDataURL('image/png');
}
function displayErrorMessage(error_msg, error){
error = error || "";
if(error){
console.error(error);
}
error_message.innerText = error_msg;
hideUI();
error_message.classList.add("visible");
}
function hideUI(){
// Helper function for clearing the app UI.
controls.classList.remove("visible");
start_camera.classList.remove("visible");
video.classList.remove("visible");
snap.classList.remove("visible");
error_message.classList.remove("visible");
}
});
I am taking a snapshot of stream and displaying it as a canvas.
How can I save the captured snapshot to file on my server?
Ps: The below code is part of a jsp page and the project is hosted on server(tomcat). I don't want to save it on user system, just on the server hosting project.
<canvas id="snapshot" width=130 height=130 align="right"></canvas>
<video id="player" width="220" height="140" align="right"; controls autoplay></video>
<button id="capture">Capture</button>
<script>
var player = document.getElementById('player');
var snapshotCanvas = document.getElementById('snapshot');
var captureButton = document.getElementById('capture');
var videoTracks;
var handleSuccess = function(stream) {
// Attach the video stream to the video element and autoplay.
player.srcObject = stream;
videoTracks = stream.getVideoTracks();
};
captureButton.addEventListener('click', function() {
var context = snapshot.getContext('2d');
context.drawImage(player, 150, 150,320,240,0,0, snapshotCanvas.width, snapshotCanvas.height);
var imgdata = snapshot.toDataURL("image/png");
var newdata = imgdata.replace(/^data:image\/png/,'data:application/octet-stream');
});
navigator.mediaDevices.getUserMedia({video: true}).then(handleSuccess);
// Stop all video streams.
videoTracks.forEach(function(track) {track.stop()});
</script>
I have a web page that can show a live stream and then be able to snap shot the live stream.
I need to have a button that can save the image in the canvas with a specific file name of my own (it can be the date for today).
Badly need it. Thanks to those who will respond! :)
Here's the code:
<!DOCTYPE html>
<html>
<head>
<title>Video Live Stream</title>
<link rel="stylesheet" type="text/css" href="demo'.css"/>
</head>
<body>
<center>
<style>
<p>
video { border: 20px solid #ccc; display: block; margin: 0 0 -5px 0; }
#canvas { margin-top: 20px; border: 1px solid #ccc; display: block; }
</p>
</style>
</br>
<h3>Live Stream with Snap Shot</h3>
<div align="center">
<video style="position:relative;top:-75px;" id="video" width="600" height="600" autoplay="">
</video>
</div>
<div align="center">
<button style="position:relative;top:-60px;" id="snap" class="sexyButton">Snap Photo</button>
<canvas style="position:relative;top:-60px;" class="input" id="canvas" width="640" height="480"></canvas>
</div>
Download!
<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>
</center>
</body>
</html>
Automatic file Download
You can not guarantee a filename but you can suggest a filename. The client may override the filename as it is just a download request and subject to the clients download policies. Event if the user allows the file to save with the name given the browser may still change the name if the file exist in the download directory by appending to the filename (or other stuff depending on the browser).
Here is a simple download image function. It will attempt to save (via download) to the client's file system the image as a PNG with the given filename. Will take an image or canvas image.
Update
As pointed out by markE the download attribute that I use to set the filename is not supported on all browsers. So only browser that support the attribute will let you set the download name.
Further the function given will also not download if the MouseEvent object is not supported. I have added a legacy method fireEvent for older browsers namely IE otherwise the function will not download.
function saveAsPNG(image, filename){ // No IE <11 support. Chrome URL bug for large images may crash
var anchorElement, event, blob;
function image2Canvas(image){ // converts an image to canvas
function createCanvas(width, height){ // creates a canvas of width height
var can = document.createElement("canvas");
can.width = width;
can.height = height;
return can;
};
var newImage = createCanvas(img.width, img.height); // create new image
newImage.ctx = newImage.getContext("2d"); // get image context
newImage.ctx.drawImage(image, 0, 0); // draw the image onto the canvas
return newImage; // return the new image
}
if(image.toDataURL === undefined){ // does the image have the toDataURL function
image = image2Canvas(image); // No then convert to canvas
}
// if msToBlob and msSaveBlob then use them to save. IE >= 10
if(image.msToBlob !== undefined && navigator.msSaveBlob !== undefined){
blob = image.msToBlob();
navigator.msSaveBlob(blob, filename + ".png");
return;
}
anchorElement = document.createElement('a'); // Create a download link
anchorElement.href = image.toDataURL(); // attach the image data URL
// check for download attribute
if ( anchorElement.download !== undefined ) {
anchorElement.download = filename + ".png"; // set the download filename
if (typeof MouseEvent === "function") { // does the browser support the object MouseEvent
event = new MouseEvent( // yes create a new mouse click event
"click", {
view : window,
bubbles : true,
cancelable : true,
ctrlKey : false,
altKey : false,
shiftKey : false,
metaKey : false,
button : 0,
buttons : 1,
}
);
anchorElement.dispatchEvent(event); // simulate a click on the download link.
} else
if (anchorElement.fireEvent) { // if no MouseEvent object try fireEvent
anchorElement.fireEvent("onclick");
}
}
}
To use the function
saveAsPNG(canvas,"MyTest"); // Will attempt to save the canvas as "MyTest.png"
This does not guarantee that the file will be saved or that the filename will be what you want. If you want to guarantee a filename you must then save the file inside a zip file. This is a lot of work and still does not guarantee that the file will be saved. Security dictates that the client must have the right to accept or reject any download request. There is no way to side step this.
I just found a way to save the canvas image with the filename of your own. You can find it at
http://eligrey.com/demos/FileSaver.js/
edit the canvas part:
<section id="image-demo">
<form id="canvas-options">
<label>Filename: <input type="text" class="filename" id="canvas-filename" placeholder="filename"/>.png</label>
<input type="submit" value="Save"/>
<input type="button" id="canvas-clear" value="Clear"/>
</form>
and insert the following scripts:
<script type="application/ecmascript" async="" src="Blob.js"/>
<script type="application/ecmascript" async="" src="canvas-toBlob.js"/>
<script type="application/ecmascript" async="" src="FileSaver.js"/>
<script type="application/ecmascript">
It worked!
I am trying to take a snapshot from someone's webcam through javascript. The code works except the resultant image is stretched way too much to me readable.
I've messed around with the: ctx.drawImage(video, 0, 0);line
I've tried ctx.drawImage(video, 0, 0,1280,720); with no difference
I've tried ctx.drawImage(video, 0, 0,100,100); with major difference. It made the whole image appear but way too small for the eye.
Code:
<html>
<head>
<video autoplay></video>
<img src="" width=1280, height=720>
<canvas style="display:none;"></canvas>
<script>
var errorCallback = function(e) {
console.log('Reeeejected!', e);
video.src = 'failure.mp4'; // fallback.
};
navigator.getUserMedia = navigator.getUserMedia || navigator.webkitGetUserMedia || navigator.mozGetUserMedia || navigator.msGetUserMedia;
var video = document.querySelector('video');
var canvas = document.querySelector('canvas');
var ctx = canvas.getContext('2d');
var localMediaStream = null;
var hdConstraints = {
video: {
mandatory: {
minWidth: 1280,
minHeight: 720
}
}
};
function snapshot() {
if (localMediaStream) {
ctx.drawImage(video, 0, 0);
// "image/webp" works in Chrome.
// Other browsers will fall back to image/png.
document.querySelector('img').src = canvas.toDataURL('image/webp');
}
}
function success(stream) {
video.src = window.URL.createObjectURL(stream);
localMediaStream = stream;
}
video.addEventListener('click', snapshot, false);
navigator.getUserMedia(hdConstraints, success,errorCallback);
</script>
</head>
</html>
Result:
Video:
Image Output:
So in conjunction with #Loktar's comment, I determined that the secret was to set the canvas size in the html like so:
<canvas style="display:none;" width=1280 height=720></canvas>
This allows for a full screen (aspect correct) capture.
Hope this helps someone else!