I make an HTML5-CSS-JS Android (and iOS) Application and i try to get access to the mobile device camera.
I tried two ways to get access to camera and both ways work fine when i use them from a Browser, but when i build my .APK file and i open my App none of them is working the same way as from a Browser:
First 1) I tried Input Tag and when i click to choose/browse it allows me only to select an Existing file NOT to capture or record a new one:
<input type="file" accept="image/*" capture="camera"/>
Then 2) I found (navigator.getUserMedia) this code on web that works also from a browser but when i open my App it seems like no working and not requesting for device hardware access at all:
navigator.getUserMedia = navigator.getUserMedia ||
navigator.webkitGetUserMedia ||
navigator.mozGetUserMedia;
if (navigator.getUserMedia) {
navigator.getUserMedia({ audio: true, video: { width: 1280, height: 720 } },
function(stream) {
var video = document.querySelector('video');
video.src = window.URL.createObjectURL(stream);
video.onloadedmetadata = function(e) {
video.play();
};
},
function(err) {
console.log("The following error occured: " + err.name);
}
);
} else {
console.log("getUserMedia not supported");
}
/*****************************************************************/
function init()
{
if(navigator.webkitGetUserMedia)
{
navigator.webkitGetUserMedia({video:true}, onSuccess, onFail);
}
else
{
alert('webRTC not available');
}
}
function onSuccess(stream)
{
document.getElementById('camFeed').src = webkitURL.createObjectURL(stream);
}
function onFail()
{
alert('could not connect stream');
}
function takePhoto()
{
var c = document.getElementById('photo');
var v = document.getElementById('camFeed');
c.getContext('2d').drawImage(v, 0, 0, 320, 240);
}
<div style="width:352px; height:625px; margin:0 auto; background-color:#fff;" >
<div>
<video id="camFeed" width="320" height="240" autoplay>
</video>
</div>
<div>
<canvas id="photo" width="320" height="240">
</canvas>
</div>
<div style="margin:0 auto; width:82px;">
<input type="button" value="Take Photo" onclick="takePhoto();">
</div>
</div>
Anyone has an idea of how can I access camera on Android or iOS?
I tried it with and without camera permissions but this was not the problem.
Help... Thank you in Advance. (If my question is not clear comment please.)
Here is the basic code, it will allow you to record/capture the file.
HTML:
<input id="reviewVideoCapture" type="file" accept="video/*"/>
JS (Using JQuery):
var videoFile = $('#reviewVideoCapture').get(0).files[0];
Use this if you want to upload the video somewhere:
<form enctype="multipart/form-data" action="/api/photo" method="POST" >
<input id="reviewVideoCapture" type="file" accept="video/*"/>
<input id="submitFormButton" type="submit">
</form>
Even though this works, I would still not recommend doing it this way. The results on mobile are buggy and hard to work with. The better way is to use cordova/ionic. A good example on how to do this can be found here:
https://github.com/yafraorg/ionictests
Related
I really want it to take a snapshot and send it to the server by just one click (once cam access approved for the website) or by just opening the link. I have accomplished that by taking a snapshot of a videostream of the html5 video element - see example. However, the quality is webcam video stream snapshot quality.
How do I really take an actual foto with proper quality?
Must only run on android.
btw:
<input id="myFileInput1" class="button" type="file" accept="image/*" capture>
is not an option, since it requires clicking, (choosing cam), open camera, taking picture, approving pic
<body style="text-align: center;">
<div style="display:none;">
<video id="player" autoplay></video>
</div>
<div style="display: inline-block; margin: 0 auto;">
<canvas id="canvas" width=853 height=1280></canvas>
</div>
<script>
const player = document.getElementById('player');
const canvas = document.getElementById('canvas');
const context = canvas.getContext('2d');
//8833ee7a5bcb161baa10970d674b8b003e769c40c452ed7ad7e31d235f0825c1
const constraints = {
video: {
optional: [{sourceId: "46884cf8fc3dc74cdefa932000380ae5d85b863a502428115bbdeb5d784be233"}]
},
};
setTimeout(() => {
context.drawImage(player, 0, 0, canvas.width, canvas.height);
// Stop all video streams.
player.srcObject.getVideoTracks().forEach(track => track.stop());
}, 1500);
navigator.mediaDevices.getUserMedia(constraints)
.then((stream) => {
// Attach the video stream to the video element and autoplay.
player.srcObject = stream;
});
</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!
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 :)
I would like to do the mobile camera capture by HTML5 like this
I have try to use below method but it needs to click somewhere for opening the camera that mean I could not preview the image in live.
<input id="fileselect" type="file" accept="image/*" capture="camera">
I also found the other method which is used a function called "getUserMedia" but it is not support on IOS8.
So how can I implement the mobile camera capture with HTML5?
Please help.
Below is a simple example of use of HTML5 to put a video viewer on the screen that also allows you to capture still images.
It has been tested on Chrome Version 40.0.2214.93 or later.
It has been done in an MVC app. If your replace the markup in your Index.cshtml with this code it should run OK. The only other dependency is the jquery.
#{
ViewBag.Title = "Home Page";
}
<style>
.videostream, #cssfilters-stream, #screenshot {
width: 307px;
height: 250px;
}
.videostream, #cssfilters-stream {
background: rgba(255,255,255,0.5);
border: 1px solid #ccc;
}
#screenshot {
vertical-align: top;
}
</style>
<div style="text-align:center;">
#*<div style="text-align:center;">*#
<div style="float:left;">
<video id="basic-stream" class="videostream" autoplay></video>
<p><button id="capture-button">Capture video</button></p>
</div>
<div style="float:left; padding-left:20px;">
<button id="SaveImageBtn" style="vertical-align:top; margin-top:100px; margin-right:20px;">Save -></button>
<canvas id="outputCanvas" class="videostream"></canvas>
</div>
</div>
<script src="~/Scripts/jquery-1.8.2.js"></script>
<script src="~/Scripts/jquery-ui-1.8.24.js"></script>
<script>
var video = document.querySelector('#basic-stream');
var button = document.querySelector('#capture-button');
var localMediaStream = null;
var canvas = document.querySelector('outputCanvas');
$(document).ready(function () {
$("#capture-button").click(function () {
RunIt();
});
$("#SaveImageBtn").click(function () {
var cvs = $("#outputCanvas")[0];
var ctx = cvs.getContext('2d');
ctx.drawImage(video, 0, 0, 300, 150);
console.log("Got here 01");
});
var videoObj = {"video": true};
var errBack = function (error) { alert("An error");};
function RunIt() {
navigator.webkitGetUserMedia(
{ "video": true, "audio": true },
function (s) {
video.src =
window.webkitURL.createObjectURL(s);
video.controls = true;
localMediaStream = s;
video.play();
},
function (e) { console.log(e); }
);
};
});
</script>
Try using some placeholder image.
I'm coding like this for HTML5, and it's working fine.
<video id="video" controls="controls" autoplay="autoplay" name="media"><source src="http://media.w3.org/2010/05/sintel/trailer.mp4" type="video/mp4"></video>
<button onclick="document.getElementById('video').playbackRate+=0.1">playbackRate+=0.1</button>
<button onclick="document.getElementById('video').playbackRate-=0.1">playbackRate-=0.1</button><br>
for JWplayer, how can I speed down/up playback speed just like above?
<script type="text/javascript">
jwplayer("myElement").setup({
file: "http://media.w3.org/2010/05/sintel/trailer.mp4",
title: "test",
height: 400,
width: 600,
autostart: true,
autoplay: true,
});
jwplayer("myElement").onTime(function(time){
showComments(Math.round(time.position));
})
</script>
As described in this post JW Player support control over playback speed only when it is in html5 render mode and it that case you can control it through options of the video tag it renders. It would look like this:
<script type="text/javascript">
function changePlaybackRate(rateChange) {
if (jwplayer().getRenderingMode() == "html5") {
var videoTag = document.querySelector('video');
if (videoTag.playbackRate) {
videoTag.playbackRate += rateChange;
}
}
//Small hack to work around a Firefox bug
if(navigator.userAgent.toLowerCase().indexOf('firefox') > -1) {
jwplayer().seek(jwplayer().getPosition());
}
};
</script>
<button onclick="changePlaybackRate(0.1)">playbackRate+=0.1</button>
<button onclick="changePlaybackRate(-0.1)">playbackRate-=0.1</button>
There is not support in JW Player for playback speed control when the browser doesn't support it nativly through HTML5 (for example in case of using Flash player)