Today we will create a web camera recorder with javascript
Basic html page
<!doctype html> | |
<html lang="en"> | |
<head> | |
<meta charset="utf-8"> | |
<meta name="viewport" content="width=device-width, initial-scale=1"> | |
<!-- Bootstrap CSS --> | |
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-1BmE4kWBq78iYhFldvKuhfTAU6auU8tT94WrHftjDbrCEXSU1oBoqyl2QvZ6jIW3" crossorigin="anonymous"> | |
<title>Web camera recorder</title> | |
</head> | |
<body> | |
<!-- Option 1: Bootstrap Bundle with Popper --> | |
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/js/bootstrap.bundle.min.js" integrity="sha384-ka7Sk0Gln4gmtz2MlQnikT1wXgYsOg+OMhuP+IlRH9sENBO0LRn5q+8nbTov4+1p" crossorigin="anonymous"></script> | |
</body> | |
</html> |
Create a javascript file index.js
and add a reference to the html at line 15:
<script src="index.js"></script>
Next we will create a video element inside a bootstrap container:
<div class="container">
<video autoplay playsinline webkit-playsinline muted id="videoelement"
style="max-width: 100%;height: auto;"></video>
</div>
Now that we have a bootstrap html template lets add javascript that does the job:
var videoelement = document.getElementById("videoelement"); | |
var localStreamConstraints = { | |
audio: true, | |
video: { width: 1920, height: 1080 }, | |
}; | |
if (videoelement) { | |
navigator.mediaDevices | |
.getUserMedia(localStreamConstraints) | |
.then(gotStream) | |
.catch(function (e) { | |
if (confirm("An error with camera occured:(" + e.name + ") Do you want to reload?")) { | |
location.reload(); | |
} | |
}); | |
} | |
//if found stream found | |
function gotStream(stream) { | |
videoelement.srcObject = stream | |
} |
Code explanation
At line 9 we prompt the user for permission to use camera and microphone
If the user accepts then at line 10 the
gotStream
function is executed.gotStream
add as source of video the stream of camera and microphoneIf the user denies the permission or stream is inaccessible then at line 11 we prompt the user to reload the page in order to try again
Lets add two buttons one for starting recording and one for stoping it line 17 and 18(this is also the final html page):
<!doctype html> | |
<html lang="en"> | |
<head> | |
<meta charset="utf-8"> | |
<meta name="viewport" content="width=device-width, initial-scale=1"> | |
<!-- Bootstrap CSS --> | |
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/css/bootstrap.min.css" rel="stylesheet" | |
integrity="sha384-1BmE4kWBq78iYhFldvKuhfTAU6auU8tT94WrHftjDbrCEXSU1oBoqyl2QvZ6jIW3" crossorigin="anonymous"> | |
<title>Web camera recorder</title> | |
</head> | |
<body> | |
<div class="container text-center"> | |
<div class="btn-group" role="group"> | |
<button type="button" id="recbutton" class="btn btn-secondary">Rec</button> | |
<button type="button" id="stopbutton" class="btn btn-secondary">Stop</button> | |
</div> | |
</div> | |
<div class="container"> | |
<video autoplay playsinline webkit-playsinline muted id="videoelement" | |
style="max-width: 100%;height: auto;"></video> | |
</div> | |
<!-- Option 1: Bootstrap Bundle with Popper --> | |
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/js/bootstrap.bundle.min.js" | |
integrity="sha384-ka7Sk0Gln4gmtz2MlQnikT1wXgYsOg+OMhuP+IlRH9sENBO0LRn5q+8nbTov4+1p" | |
crossorigin="anonymous"></script> | |
<script src="index.js"></script> | |
</body> | |
</html> |
Media recorder
Lets get back to our javascript file to do the magic
First we must add a
MediaRecorder
object and initialize it when we get the stream at line 26At line 33 an event listener is added to the rec button. On click the recording starts
At line 41 the recording stops when the stop button is clicked.
After the recording has stopped the
handleDataAvailable
is executed and thedownload
function downloads the recorded chunks as webm file.
var videoelement = document.getElementById("videoelement"); | |
var localStreamConstraints = { | |
audio: true, | |
video: { width: 1920, height: 1080 }, | |
}; | |
var mediarecorder | |
var options = { mimeType: "video/webm; codecs=vp9" }; | |
var recordedChunks=[] | |
if (videoelement) { | |
console.log("we have the video") | |
navigator.mediaDevices | |
.getUserMedia(localStreamConstraints) | |
.then(gotStream) | |
.catch(function (e) { | |
if (confirm("An error with camera occured:(" + e.name + ") Do you want to reload?")) { | |
location.reload(); | |
} | |
}); | |
} | |
//if found stream found | |
function gotStream(stream) { | |
console.log("Adding local stream."); | |
videoelement.srcObject = stream | |
mediarecorder=new MediaRecorder(stream,options) | |
mediarecorder.ondataavailable = handleDataAvailable; | |
mediarecorder.onstop = download | |
} | |
var recbtn=document.getElementById("recbutton") | |
if(recbtn){ | |
recbtn.addEventListener('click',()=>{ | |
mediarecorder.start() | |
}) | |
} | |
var stopbtn=document.getElementById("stopbutton") | |
if(stopbtn){ | |
stopbtn.addEventListener('click',()=>{ | |
mediarecorder.stop() | |
}) | |
} | |
function handleDataAvailable(event) { | |
if (event.data.size > 0) { | |
recordedChunks.push(event.data); | |
console.log(event.data) | |
} | |
} | |
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); | |
} |
Thanks for your time.
Leave a question or comment below.
Top comments (0)