Skip to content

Instantly share code, notes, and snippets.

@miguelmota
Last active November 18, 2021 20:25
Show Gist options
  • Star 13 You must be signed in to star a gist
  • Fork 5 You must be signed in to fork a gist
  • Save miguelmota/6403122 to your computer and use it in GitHub Desktop.
Save miguelmota/6403122 to your computer and use it in GitHub Desktop.
Screenshots with getUserMedia API. Blog post: http://www.miguelmota.com/blog/screenshots-with-getusermedia-api/
<!-- Video element (live stream) -->
<label>Video Stream</label>
<video autoplay id="video" width="640" height="480"></video>
<!-- Canvas element (screenshot) -->
<label>Screenshot (base 64 dataURL)</label>
<canvas id="canvas" width="640" height="480"></canvas>
<!-- Capture button -->
<button id="capture-btn">Capture!</button>
<!-- Image URL output -->
<label>Image URL</label>
<input type="text" id="image-url-input" disabled>
// Take a screenshot using getUserMedia API.
// Give credit where credit is due. The code is heavily inspired by
// HTML5 Rocks' article "Capturing Audio & Video in HTML5"
// http://www.html5rocks.com/en/tutorials/getusermedia/intro/
(function() {
// Our element ids.
var options = {
video: '#video',
canvas: '#canvas',
captureBtn: '#capture-btn',
imageURLInput: '#image-url-input'
};
// Our object that will hold all of the functions.
var App = {
// Get the video element.
video: document.querySelector(options.video),
// Get the canvas element.
canvas: document.querySelector(options.canvas),
// Get the canvas context.
ctx: canvas.getContext('2d'),
// Get the capture button.
captureBtn: document.querySelector(options.captureBtn),
// This will hold the video stream.
localMediaStream: null,
// This will hold the screenshot base 64 data url.
dataURL: null,
// This will hold the converted PNG url.
imageURL: null,
// Get the input field to paste in the imageURL.
imageURLInput: document.querySelector(options.imageURLInput),
initialize: function() {
var that = this;
// Check if navigator object contains getUserMedia object.
navigator.getUserMedia = navigator.getUserMedia || navigator.webkitGetUserMedia || navigator.mozGetUserMedia || navigator.msGetUserMedia;
// Check if window contains URL object.
window.URL = window.URL || window.webkitURL;
// Check for getUserMedia support.
if (navigator.getUserMedia) {
// Get video stream.
navigator.getUserMedia({
video: true
}, this.gotStream, this.noStream);
// Bind capture button to capture method.
this.captureBtn.onclick = function () {
that.capture();
};
} else {
// No getUserMedia support.
alert('Your browser does not support getUserMedia API.');
}
},
// Stream error.
noStream: function (err) {
alert('Could not get camera stream.');
console.log('Error: ', err);
},
// Stream success.
gotStream: function (stream) {
// Feed webcam stream to video element.
// IMPORTANT: video element needs autoplay attribute or it will be frozen at first frame.
if (window.URL) {
video.src = window.URL.createObjectURL(stream);
} else {
video.src = stream; // Opera support.
}
// Store the stream.
localMediaStream = stream;
},
// Capture frame from live video stream.
capture: function () {
var that = this;
// Check if has stream.
if (localMediaStream) {
// Draw whatever is in the video element on to the canvas.
that.ctx.drawImage(video, 0, 0);
// Create a data url from the canvas image.
dataURL = canvas.toDataURL('image/png');
// Call our method to save the data url to an image.
that.saveDataUrlToImage();
}
},
saveDataUrlToImage: function () {
var that = this;
var options = {
// Change this to your own url.
url: 'http://example.com/dataurltoimage'
};
// Only place where we need jQuery to make an ajax request
// to our server to convert the dataURL to a PNG image,
// and return the url of the converted image.
that.imageURLInput.value = 'Fetching url ...';
$.ajax({
url: options.url,
type: 'POST',
dataType: 'json',
data: { 'data_url': dataURL },
complete: function(xhr, textStatus) {
// Request complete.
},
// Request was successful.
success: function(response, textStatus, xhr) {
console.log('Response: ', response);
// Conversion successful.
if (response.status_code === 200) {
imageURL = response.data.image_url;
// Paste the PNG image url into the input field.
that.imageURLInput.value = imageURL;
that.imageURLInput.removeAttribute('disabled');
}
},
error: function(xhr, textStatus, errorThrown) {
// Some error occured.
console.log('Error: ', errorThrown);
imageURLInput.value = 'An error occured.';
}
});
}
};
// Initialize our application.
App.initialize();
// Expose to window object for testing purposes.
window.App = App;
})();
<?php
// Data URL to image.
// exit immediately if the data url was not passed.
if (!isset($_REQUEST['data_url'])) {
exit();
}
// Get the data url.
$img = $_REQUEST['data_url'];
// Clean up the data url string a bit.
$img = str_replace('data:image/png;base64,', '', $img);
$img = str_replace(' ', '+', $img);
// Decode the image.
$decodedImage = base64_decode($img);
// Generate a random filename.
$filename = md5(time()).'.png';
// Save the file to the server and generate a response.
if (file_put_contents($_SERVER['DOCUMENT_ROOT'] . '/uploads/' . $filename, $decodedImage)) {
$imageURL = 'http://' . $_SERVER['HTTP_HOST'] . '/uploads/' . $filename;
$response = array(
'status_code' => 200,
'data' => array(
'image_url' => $imageURL
)
);
} else {
$response = array(
'status_code' => 500
);
}
// Return JSON response.
header("Content-Type: application/json");
echo json_encode($response);
?>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment