OBS studio is cool but lets create our very own screen recorder using JavaScript.
And guess what? Its not limited to just recording the browser screen. Yes, you've read that right. Although JavaScript runs on browser, we can use JS to record not only the active tab but any tab or entire screen. So lets get started.
First thing we'd need is a HTML file, in that we will have a record button and a video element where we can play the recorded video.
<!DOCTYPE html>
<html>
<head>
<title>Parcel Sandbox</title>
<meta charset="UTF-8" />
</head>
<body>
<video class="video" width="600px" controls></video>
<button class="record-btn">record</button>
<script src="./index.js"></script>
</body>
</html>
And we'd also need a JS file so lets create the index.js also
let btn = document.querySelector(".record-btn");
btn.addEventListener("click", function () {
console.log("hello");
});
So now if we open it the browser and click on the button we should see hello
in console.
Alright now instead of console.log
lets get the stream of users display
let btn = document.querySelector(".record-btn");
btn.addEventListener("click", async function () {
let stream = await navigator.mediaDevices.getDisplayMedia({
video: true
});
});
So now if you click on the button you'll see this popup.
Now you might think we are done select a window or screen and click share and it should start recording. But its a bit more complicated than that. We have to record the video our self. We are going to use MediaRecorder to record our video.
let btn = document.querySelector(".record-btn")
btn.addEventListener("click", async function () {
let stream = await navigator.mediaDevices.getDisplayMedia({
video: true
})
//needed for better browser support
const mime = MediaRecorder.isTypeSupported("video/webm; codecs=vp9")
? "video/webm; codecs=vp9"
: "video/webm"
let mediaRecorder = new MediaRecorder(stream, {
mimeType: mime
})
//we have to start the recorder manually
mediaRecorder.start()
})
So as our screen get recorded mediaRecorder
will give us data in chunks we need to store those data in a variable.
let btn = document.querySelector(".record-btn")
btn.addEventListener("click", async function () {
let stream = await navigator.mediaDevices.getDisplayMedia({
video: true
})
//needed for better browser support
const mime = MediaRecorder.isTypeSupported("video/webm; codecs=vp9")
? "video/webm; codecs=vp9"
: "video/webm"
let mediaRecorder = new MediaRecorder(stream, {
mimeType: mime
})
let chunks = []
mediaRecorder.addEventListener('dataavailable', function(e) {
chunks.push(e.data)
})
//we have to start the recorder manually
mediaRecorder.start()
})
And now when we click on the stop sharing button we want the recorded video to be played in our video element so lets do that.
let btn = document.querySelector(".record-btn")
btn.addEventListener("click", async function () {
let stream = await navigator.mediaDevices.getDisplayMedia({
video: true
})
//needed for better browser support
const mime = MediaRecorder.isTypeSupported("video/webm; codecs=vp9")
? "video/webm; codecs=vp9"
: "video/webm"
let mediaRecorder = new MediaRecorder(stream, {
mimeType: mime
})
let chunks = []
mediaRecorder.addEventListener('dataavailable', function(e) {
chunks.push(e.data)
})
mediaRecorder.addEventListener('stop', function(){
let blob = new Blob(chunks, {
type: chunks[0].type
})
let video = document.querySelector(".video")
video.src = URL.createObjectURL(blob)
})
//we have to start the recorder manually
mediaRecorder.start()
})
Now as a finishing touch lets automatically download the recorded video.
let btn = document.querySelector(".record-btn")
btn.addEventListener("click", async function () {
let stream = await navigator.mediaDevices.getDisplayMedia({
video: true
})
//needed for better browser support
const mime = MediaRecorder.isTypeSupported("video/webm; codecs=vp9")
? "video/webm; codecs=vp9"
: "video/webm"
let mediaRecorder = new MediaRecorder(stream, {
mimeType: mime
})
let chunks = []
mediaRecorder.addEventListener('dataavailable', function(e) {
chunks.push(e.data)
})
mediaRecorder.addEventListener('stop', function(){
let blob = new Blob(chunks, {
type: chunks[0].type
})
let url = URL.createObjectURL(blob)
let video = document.querySelector("video")
video.src = url
let a = document.createElement('a')
a.href = url
a.download = 'video.webm'
a.click()
})
//we have to start the recorder manually
mediaRecorder.start()
})
And there now we have a fully functional screen recorder app.
Make sure to read my other articles.
Oldest comments (49)
Nice tutorial!
I'm really glad that you liked it.
YOU ARE AWESOME MAN!!
Do you have a YouTube channel, blog or something like that?
Many many Thank.
Yes, I have a YouTube channel.
But I am introvert so I struggle to talk which is why my videos are not that good. But I'm trying to improve
youtu.be/mD_QQvJYQAI
Really awesome tutorial !
I am glad you liked it.
This was a good article. Step by step articles like this are really a good idea. Good Job.
Many thanks, I apprecate your valuable comment a loy
awesome, this is a great extension to all the zoom clone tutorials π
Glad you liked it
Very nice article, thank you.
Yes
developers.google.com/web/fundamen...
But its hard to to both at once
Nice tutorial, i was wondering how to do this, your step-by-step tutorial is awesome
I am really glad that you liked it
That's really great!!
Glad you found this helpful
It's pretty cool !!! thank you man
You're most welcome
Great article! Keep it up! However, I have question...
Why you need to create chunks when
e.data
indataavailable
is already a blob?Isn't that part kinda unnecessary?
Couldn't we just use it like this?
as you keep recording the
dataavailable
event will run multiple time. So basically instead you giving you the entire video once recording is done it will give you data in small parts as the video is being recorded.Ok cool! Thank you
Great Tutorial here.. Please i cant fin where the recorded files are been saved.
In your downloads folders.
hello
I am web developer. I have to build new site.
but I have to capture image from stream-video when user click capture button.
Also I have to extract from that images.
Help me.
stackoverflow.com/questions/259705...
Very clear explanation. Loved it
Many many Thanks
The minute I saw the tutorial, the next thing I knew was that I'm gonna make this thing my self. Created in React and deployed. Thank you once again.
Damn thats really great.
If you want something way more challenging you can try this
Damn. You just earned a follower and my respect. Keep those challenges coming coach.
Thanks a lot.
I also followed you back.
Nice
Thank you
wow