Screen Recording Using Javascript And Vue.js Tutorial

screend recorder vue tutorial

We will use MediaDevices Web APIs to screen record and preview the video, downloading and uploading it using Vue 3 and Javascript.

Most of task management web applications provide a screen recording feature to record your computer screen and send it to another user. Have you ever wondered how they do that? It seems like coding for edges to create this feature or at least that is what I thought when a client asked me to program a screen recorder in the application. so I found out that the powerful web browsers we use nowadays provide MediaDevices Web APIs to screen records. It’s so simple and easy. so least do this step-by-step using Vue.js for cleaner code.

Create a Vue 3 application using Vite

Let’s create a new Vue.js application using Vite. Follow the below commands to set up the application and visit http://localhost:5173/ to make sure the application is installed correctly.

npm create vite@latest my-vue-app -- --template vue

cd my-vue-app

npm install  

npm run dev

Screen recorder in Vue 3

Clear everything in ‘\src\App.vue’ let’s start coding but first we need to understand the steps that we need to do.

We have two important things first the the streaming data that we get and second the recorder class. To start recording we should pass the streaming data to the recorder class to control it. to do that we will create two variables stream and recorder

<script setup>
import { ref } from 'vue'

let stream = '';
let recorder = '';


</script>

Then we need to create a new function to start recording and by starting recording, we will pass the streaming data to the stream variable and the recorder class to the recorder variable

<script setup>
import { ref } from 'vue'

let stream = '';
let recorder = '';
const startRecord = async ()=>{
     try {
       stream = await navigator.mediaDevices.getDisplayMedia();
       recorder = new MediaRecorder(stream);
     } catch (error) {       
       console.error('Error obtaining display media:', error);    
     }
} 
</script>

We got the streaming data from the mediaDevices APIs and we instantiate MediaRecorder class for controlling the recording processing. We should put the code between try and catch to debug the errors.

We should create some trackers for the recording we follow the event listener of the MediaRecorder. We have ‘start’, ‘error’, and ‘dataavailable’ when the video data is available to use.

To start the record call the start function recorder.start(), and to get the video tracks stream.getVideoTracks(); and we can listen to its ‘end’ event to stop recording

Let’s use them with the startRecord function the see the code.


let stream = '';
let recorder = '';

const startRecord = async ()=>{
    videoLink.value = ''
    videoBlob.value = null; 
    
    try {
         stream = await navigator.mediaDevices.getDisplayMedia();
         recorder = new MediaRecorder(stream);
        
        recorder.addEventListener('start', () => {
            console.log('Recording started');
        });

        recorder.addEventListener('dataavailable', (event) => {
            console.log('Video recorded successfully');
        });

        recorder.addEventListener('error', (error) => {
            console.log('Recording error');
        });

        recorder.start(); 

        const [ video ] = stream.getVideoTracks();
        video.addEventListener("ended", () => {
            console.log('Recording ended');
        });

    } catch (error) {
        console.error('Error obtaining display media:', error);
    }
}

We need to get the recorded video link to preview on the webpage after recording to do that we will add this variable const videoLink = ref(''); and at the ‘dataavailable’ listener we add this code videoLink.value = URL.createObjectURL(evt.data);

const videoLink = ref('');
//
const startRecord = async ()=>{
//
  recorder.addEventListener('dataavailable', (event) => {
     videoLink.value = URL.createObjectURL(event.data);
  });
//
}
//

Now you can pass this variable as a source link in the video HTML element videoLink.

If you want to download the video that you recorded just create a a link element and click it as the following code

const videoLink = ref('');
//
const startRecord = async ()=>{
//
  recorder.addEventListener('dataavailable', (event) => {
     videoLink.value = URL.createObjectURL(event.data);
    //auto download            
    const a = document.createElement("a");  
    a.href = URL.createObjectURL(event.data);
    a.download = "capture.webm";
    a.click();
});
//
}
//

You re-run the serve and test the recording after finishing you should see the auto download of the video.

If you want to upload to the server you must pass the event data to a new variable videoBlob.value = event.data and then pass it to a new form data class new FormData();

const videoLink = ref('');
const videoBlob = ref(null);
//
const startRecord = async ()=>{
//
  recorder.addEventListener('dataavailable', (event) => {
     //uploading data
     videoBlob.value = event.data;

     //video link
     videoLink.value = URL.createObjectURL(event.data);

    //auto download            
    const a = document.createElement("a");  
    a.href = URL.createObjectURL(event.data);
    a.download = "capture.webm";
    a.click();
});
//
}
//

I created a flag variable for recording const isRecording = ref(false); to use with start and end events, and we can stop recording by calling the stop function recorder.stop();

Here is the enter code for start and stop recording.

<script setup>
import { ref } from 'vue'

// recording
const videoLink = ref('');
const videoBlob = ref(null);
const isRecording = ref(false);

let stream = '';
let recorder = '';


const startRecord = async ()=>{
    videoLink.value = ''
    videoBlob.value = null; 
    
    try {
         stream = await navigator.mediaDevices.getDisplayMedia();
         recorder = new MediaRecorder(stream);
        
        recorder.addEventListener('start', () => {
            isRecording.value = true;  
            console.log('Recording started');
        });

        recorder.addEventListener('dataavailable', (event) => {
           //uploading data
            videoBlob.value = event.data; // Store the recorded video blob

            //video link
            videoLink.value = URL.createObjectURL(event.data);

            //auto download
            const a = document.createElement("a");
            a.href = URL.createObjectURL(event.data);
            a.download = "capture.webm";
            a.click();
            console.log('Video recorded successfully');
        });

        recorder.addEventListener('error', (error) => {
            
        });

        recorder.start();

        const [ video ] = stream.getVideoTracks();
        video.addEventListener("ended", () => {
            isRecording.value = false;  
            recorder.stop();
        });


    } catch (error) {
        console.error('Error obtaining display media:', error);
    }
}

const stopRecording = async () =>{
    recorder.stop();
    isRecording.value = false;  
}

Here is the HTML template code and the CSS for start and stop buttons with video preview.

<template>
  <div class="">
      <button class="btn-start" v-if="!isRecording" @click="startRecord">Start record</button>
      <button class="btn-stop" v-if="isRecording" @click="stopRecording">Stop record</button>
      <div v-if="videoLink">
          <div>Video preview</div>
          <video  controls class="w-100">
              <source :src="videoLink" type="video/webm">
              Your browser does not support the video tag.
          </video>
      </div>
  </div>
  
</template>
<style scoped>
.w-100{
  width: 100%;
}
.btn-start {
  /* Styles for the start button */
  background-color: green;
  color: white;
  border: none;
  padding: 15px 32px;
  text-align: center;
  text-decoration: none;
  display: inline-block;
  font-size: 16px;
  margin: 4px 2px;
  cursor: pointer;
}

.btn-stop {
  /* Styles for the stop button */
  background-color: red;
  color: white;
  border: none;
  padding: 15px 32px;
  text-align: center;
  text-decoration: none;
  display: inline-block;
  font-size: 16px;
  margin: 4px 2px;
  cursor: pointer;
}
</style>

This is the bonus function to upload the video to the server after stopping recording.

const uploadVideo = async () => {
  
  if (!videoBlob.value) {
    console.warn('No video recorded to upload');
    return;
  }

  console.log(videoBlob.value);
  const formData = new FormData();
  formData.append('video', videoBlob.value); // Set appropriate filename
  try {
    axios.post('/save-video',formData, {
         headers: {
                'Content-Type': 'multipart/form-data'
            }
      })
      .then((res) => {
          
    

      })
      .catch( (error) => {
          

      });
  } catch (error) {
    console.error('Error uploading video:', error);
  }
};

Conclusion

Nowadays browsers provide a powerful API to screen recording the computer screen and manipulate the video data as we want for example we can upload, download, and preview the video.

Thank you for reading I hope that was useful for you.

Leave a Reply

Your email address will not be published. Required fields are marked *