How to make a Video Recorder with Javascript and Bootstrap
Tags: videorecorder, html, css, javascript
Published: 2021-10-09 22:18:41

Hi Everyone! 
In this post, I will be showing you how to make a video recorder with Javascript and Bootstrap. Remember to Follow me if you want more projects. 
Let's get started. 

Devices that will use this app must have a working camera and access to the microphone. This project will contain absolutely no CSS but will look nice because I will use Bootstrap instead.  I have also added a echo cancellation and download video feature in the project. Below is the HTML Markup: 

```html
<!DOCTYPE html>
<html>
  <head>
    <title>Video Recorder in Javascript</title>
    <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.1.1/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-F3w7mX95PdgyTmZZMECAngseQB83DfGTowi0iMjiWaeVhAn4FJkqJByhZMI3AhiU" crossorigin="anonymous">
  </head>
  <body>
    <div id="container mx-auto">
      <video id="gum" class="mx-auto w-50 d-flex justify-content-center" autoplay muted></video>
      <video id="recorded" class="mx-auto w-50 d-flex justify-content-center" playsinline loop></video>

      <div class="my-5">
        <button class="btn btn-primary" id="start">Start camera</button>
        <button class="btn btn-success" id="record" disabled>Record</button>
        <button class="btn btn-warning" id="play" disabled>Play</button>
        <button class="btn btn-secondary" id="download" disabled>Download</button>
      </div>

      <div class="m-3">
        <h4 class="text-info">Video Stream Options</h4>
        <div class="form-check form-switch">
  <input class="form-check-input" type="checkbox" id="echoCancellation">
  <label class="form-check-label text-center" for="flexSwitchCheckDefault">Echo Cancellation</label>
</div>
      </div>

      <div>
        <span id="errorMsg"></span>
      </div>
    </div>

    <!--Linking the Scripts to our HTML File-->
    <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.1.1/dist/js/bootstrap.bundle.min.js" integrity="sha384-/bQdsTh/da6pkI1MST/rWKFNjaCP5gBSY4sEBT38Q/9RBh9AH40zEOg7Hlq2THRZ" crossorigin="anonymous"></script>
    <script src="app.js></script>
  </body>
</html>
```

Next we are going to add the Javascript so the user will be able to record a video.

```javascript
        'use strict';

/* globals MediaRecorder */

let mediaRecorder;
let recordedBlobs;

const errorMsgElement = document.querySelector('span#errorMsg');
const recordedVideo = document.querySelector('video#recorded');
const recordButton = document.querySelector('button#record');
const playButton = document.querySelector('button#play');
const downloadButton = document.querySelector('button#download');


recordButton.addEventListener('click', () => {
  if (recordButton.textContent === 'Record') {
    startRecording();
  } else {
    stopRecording();
    recordButton.textContent = 'Record';
    playButton.disabled = false;
    downloadButton.disabled = false;
  }
});


playButton.addEventListener('click', () => {
  const superBuffer = new Blob(recordedBlobs, {type: 'video/webm'});
  recordedVideo.src = null;
  recordedVideo.srcObject = null;
  recordedVideo.src = window.URL.createObjectURL(superBuffer);
  recordedVideo.controls = true;
  recordedVideo.play();
});


downloadButton.addEventListener('click', () => {
  const blob = new Blob(recordedBlobs, {type: 'video/mp4'});
  const url = window.URL.createObjectURL(blob);
  const a = document.createElement('a');
  a.style.display = 'none';
  a.href = url;
  a.download = 'w3-coder-recorder-test.mp4';
  document.body.appendChild(a);
  a.click();
  setTimeout(() => {
    document.body.removeChild(a);
    window.URL.revokeObjectURL(url);
  }, 100);
});

function handleDataAvailable(event) {
  console.log('handleDataAvailable', event);
  if (event.data && event.data.size > 0) {
    recordedBlobs.push(event.data);
  }
}

function startRecording() {
  recordedBlobs = [];
  let options = {mimeType: 'video/webm;codecs=vp9,opus'};
  try {
    mediaRecorder = new MediaRecorder(window.stream, options);
  } catch (e) {
    console.error('Exception while creating MediaRecorder:', e);
    errorMsgElement.innerHTML = `Exception while creating MediaRecorder: ${JSON.stringify(e)}`;
    return;
  }

  console.log('Created MediaRecorder', mediaRecorder, 'with options', options);
  recordButton.textContent = 'Stop Recording';
  playButton.disabled = true;
  downloadButton.disabled = true;
  mediaRecorder.onstop = (event) => {
    console.log('Recorder stopped: ', event);
    console.log('Recorded Blobs: ', recordedBlobs);
  };
  mediaRecorder.ondataavailable = handleDataAvailable;
  mediaRecorder.start();
  console.log('MediaRecorder started', mediaRecorder);
}

function stopRecording() {
  mediaRecorder.stop();
}

function handleSuccess(stream) {
  recordButton.disabled = false;
  console.log('getUserMedia() got stream:', stream);
  window.stream = stream;

  const gumVideo = document.querySelector('video#gum');
  gumVideo.srcObject = stream;
}

async function init(constraints) {
  try {
    const stream = await navigator.mediaDevices.getUserMedia(constraints);
    handleSuccess(stream);
  } catch (e) {
    console.error('navigator.getUserMedia error:', e);
    errorMsgElement.innerHTML = `navigator.getUserMedia error:${e.toString()}`;
  }
}

document.querySelector('button#start').addEventListener('click', async () => {
  const hasEchoCancellation = document.querySelector('#echoCancellation').checked;
  const constraints = {
    audio: {
      echoCancellation: {exact: hasEchoCancellation}
    },
    video: {
      width: 1280, height: 720
    }
  };
  console.log('Using media constraints:', constraints);
  await init(constraints);
});
```

That's it! You have now successfully created a Video Recorder with Javascript and Bootstrap. 

[Live Demo] (https://abhinav-gupta-w3.w3spaces.com/recorder.html)
[Full Code](https://github.com/Abhi-Develops/video-recorder)