How to Record a Video using WebRTC in the Browser

WebRTC (Web Real-Time Communication) is a free and open-source project providing web browsers and mobile applications with real-time communication (RTC) via application programming interfaces (APIs). It provides an API named getUserMedia to access the device’s cameras and microphones.

Sometimes, we may need to record a video to save the content we get from the camera and the microphone, like the seconds when a new barcode is detected or a person enters the camera.

There are several ways to record a video:

  1. Use the MediaStream Recording API.
  2. Use the RecordRTC library.

RecordRTC’s compatibility is better which works on browsers on Android, iOS and PC devices. In this article, we are going to use WebRTC to open a camera and record a video of it with RecordRTC.

It can be used with Dynamsoft Barcode Reader to create web barcode scanner apps, which is useful in the following aspects:

  1. Record the video before successfully reading a barcode to test the performance.
  2. Record the video of the seconds when a barcode is read for double checking in the future.

Create a Page to Open a Camera

  1. Create a new HTML file with the following content.

    <!DOCTYPE html>
    <html lang="en">
      <head>
        <title>RecordRTC Simple Demos</title>
        <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
        <meta charset="utf-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no">
        <style>
        </style>
      </head>
      <body>
      </body>
    </html>
    
  2. Ask for permissions of cameras and microphones.

    window.onload = function(){
      askForPermissions();
    }
    
    async function askForPermissions(){
      var stream;
      try {
        var constraints = {video: true, audio: true}; //ask for camera and microphone permission
        stream = await navigator.mediaDevices.getUserMedia(constraints);  
      } catch (error) {
        console.log(error);
        var constraints = {video: true, audio: false}; //ask for camera permission only if no microphones detected
        stream = await navigator.mediaDevices.getUserMedia(constraints);
        hasMicrophone = false;
      }
      closeStream(stream);
    }
    
    function closeStream(stream){
      try{
        if (stream){
          stream.getTracks().forEach(track => track.stop());
        }
      } catch (e){
        alert(e.message);
      }
    }
    
  3. List camera devices in a select.

    HTML:

    <select id="select-camera"></select>
    

    JavaScript:

    var cameraSelect = document.getElementById("select-camera");
    var devices;
       
    async function listDevices(){
      devices = await getCameraDevices()
      for (let index = 0; index < devices.length; index++) {
        const device = devices[index];
        cameraSelect.appendChild(new Option(device.label ?? "Camera "+index,device.deviceId));
      }
    }
       
    async function getCameraDevices(){
      await askForPermissions();
      var devices = await navigator.mediaDevices.enumerateDevices();
      var cameraDevices = [];
      for (var i=0;i<devices.length;i++){
        var device = devices[i];
        if (device.kind == 'videoinput'){
          cameraDevices.push(device);
        }
      }
      return cameraDevices;
    }
    
  4. List predefined resolutions in a select.

    <select id="select-resolution">
      <option selected>640x480</option>
      <option>1280x720</option>
      <option>1920x1080</option>
      <option>3840x2160</option>
    </select>
    
  5. Open the selected camera with the selected resolution.

    HTML:

    <div id="video-container">
      <video class="absolute" controls autoplay playsinline></video>
    </div>
    

    JavaScript:

    var video = document.querySelector('video');
    function captureCamera(callback) {
      var constraints = {
        audio:false,
        video:true
      }
      if (cameraSelect.selectedOptions[0]) {
        var device = devices[cameraSelect.selectedIndex];
        var deviceID = device.deviceId;
        console.log(deviceID);
        constraints = {
          video: {deviceId: deviceID},
          audio: hasMicrophone
        }
      }
      if (resolutionSelect.selectedOptions[0]) {
        let desiredWidth = resolutionSelect.selectedOptions[0].label.split("x")[0];
        let desiredHeight = resolutionSelect.selectedOptions[0].label.split("x")[1];
        if (constraints["video"]["deviceId"]) {
          constraints["video"]["width"] = desiredWidth;
          constraints["video"]["height"] = desiredHeight;
        }else{
          constraints = {width:desiredWidth,height:desiredHeight};
        }
      }
      navigator.mediaDevices.getUserMedia(constraints).then(function(camera) {
        video.srcObject = camera;
      }).catch(function(error) {
        alert('Unable to capture your camera. Please check console logs.');
        console.error(error);
      });
    }
    

Record the Video

  1. Include the library of RecordRTC.

    <script src="https://www.WebRTC-Experiment.com/RecordRTC.js"></script>
    
  2. Create a Recorder instance using the camera stream.

    var recorder = RecordRTC(camera, {
      type: 'video'
    });
    
  3. Start recording.

    recorder.startRecording();
    // keep camera for stopping
    recorder.camera = camera;
    
  4. Stop recording.

    recorder.stopRecording(stopRecordingCallback);
    

    After the recording is stopped, stop the camera and play the recorded video.

    function stopRecordingCallback() {
      video.src = video.srcObject = null;
      video.muted = false;
      video.volume = 1;
      video.src = URL.createObjectURL(recorder.getBlob());
         
      recorder.camera.stop();
      recorder.destroy();
      recorder = null;
    }
    
  5. Add a button to download the video.

    JavaScript:

    document.getElementById("btn-download").onclick = function() {
      if (!interval) {
        var a = document.createElement("a");
        a.href = video.src;
        document.body.appendChild(a);
        a.click();
        a.remove()
      }
    };
    

Source Code

All right, we’ve now finished the demo. We can add other features like reading the barcode at the same time. Get the source code to have a try:

https://github.com/tony-xlh/Record-using-WebRTC