SCREEN RECORDING IN REACTJS

12-02-2019    Hari Kondlapudi    Views 69

Screen Recording is far more powerful than any combination of screen capture and video editors. It's worthwhile to take a moment to understand its design and workings.

Adding screen recording to a web application makes users save content, find issues and solutions that relate to the digital screen. The main advantage of screen recording is that teach us how to do something on your computer in a step by step procedure and also can stop, forward, rewind videos, approach in this way helps the student, teacher or learner to analyze the content what’s is going on easily.

Implement screen recording with javascript library react.js is an open-source library that is used for building user interfaces, fast, scalable, simple, reusable UI components for single-page-applications.

Steps to create your first react project
            npx create-react-app my-app
            cd my-app
            npm start

Npms need to install:

            npm i reactstrap
            npm i recordrtc
            npm i bootstrap
           

Code For Screen Recording:

Code starts from here App.js is a parent component to every child component. Import your router.jsx file, CSS files folder, and also import bootstrap CSS because it includes every tag of bootstrap.
        
//App.js
import React from 'react';
import './App.scss';
import 'bootstrap/dist/css/bootstrap.css';
import Router from './Router'

function App() {
  return (
 <  div className="App"  >
      <  Router /  >
    < /div   >   
  );
}

export default App;

In the router, file import your components to change them based on a path if the path is ‘/’ that will be your first component to display

The purpose of the router is it allows your web application to navigate between different components, changing their browser URL and also keeps the UI in sync with the URL.

//Router.js
import React from 'react';
import { Route, Switch, BrowserRouter, } from 'react-router-dom';
import ScreenRecord from './ScreenRecording';
const Router = () => (
    <  BrowserRouter  >
        <  Switch >
            <  Route exact path="/" component={ScreenRecord} /   >
            <  Route path='/screenrecording' component={ScreenRecord} /  >
        <  /Switch   >
    <  / BrowserRouter   >
);export default Router;

Technology:
The technology behind screen recording is WEBRTC, an open-source library created by google to achieve Real-Time Communication easily, which includes audio, video, and data transferring in web applications and mobile applications.

It uses UDP(user datagram protocol) is a communication protocol that is faster and connectionless.WEBRTC supports major browsers like Apple, Google, Microsoft, Mozilla, and Opera.

The below code is for screen recording implemented by using recordrtc module it includes audio+video+screen recording.

//ScreenRecording.jsx
import React from 'react';
import RecordRTC from 'recordrtc';
import ScreenRecordPreviewModal from './ScreenRecordPreviewModal';
import { Button, Row, Col, Container, Card, CardBody } from 'reactstrap';
import Topbar from './Topbar';
let recorder;

class ScreenRecording extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      recordedVideoUrl: null,
      isOpenVideoModal: false,
      screen: null,
      camera: null,
      recorder: null,
      startDisable: false,
      stopDisable: true,
      loadModal: false,
    }
  }
  //to enable audio and video pass true to disable pass false
  captureCamera = (cb) => {
    navigator.mediaDevices.getUserMedia({
      audio: true,
      video: false,//make it true for video
    }).then(cb);
  }
//access your screen width and height  using window object adjusting camera position ,height and width  //after that pass screen and camera to recordrtc/and call startrecording method using recorder object to //start screen recording
startScreenRecord = async () => {
    await this.setState({ stopDisable: false, startDisable: true })
    this.captureScreen((screen) => {
      this.captureCamera(async (camera) => {
        screen.width = window.screen.width;
        screen.height = window.screen.height;
        screen.fullcanvas = true;
        camera.width = 320;
        camera.height = 240;
        camera.top = screen.height - camera.height;
        camera.left = screen.width - camera.width;
        this.setState({
          screen: screen,
          camera: camera
        })
        recorder = RecordRTC([screen, camera], {
          type: 'video',
        });
        recorder.startRecording();
        recorder.screen = screen;
      });
    })
  };
  //to capture screen  we need to make sure that which media devices are captured and add listeners to // start and stop stream
  captureScreen = (callback) => {
    this.invokeGetDisplayMedia((screen) => {
      this.addStreamStopListener(screen, () => {
      });
      callback(screen);
    }, (error) => {
      console.error(error);
      alert('Unable to capture your screen. Please check console logs.\n' + error);
      this.setState({ stopDisable: true, startDisable: false })
    });
  }
  //tracks stop
  stopLocalVideo = async (screen, camera) => {
    [screen, camera].forEach(async (stream) => {
      stream.getTracks().forEach(async (track) => {
        track.stop();
      });
    });
  }
  //getting media items
  invokeGetDisplayMedia = (success, error) => {
    var displaymediastreamconstraints = {
      video: {
        displaySurface: 'monitor', // monitor, window, application, browser
        logicalSurface: true,
        cursor: 'always' // never, always, motion
      }
    };
    // above constraints are NOT supported YET
    // that's why overridnig them
    displaymediastreamconstraints = {
      video: true,
      audio: true,
    };
    if (navigator.mediaDevices.getDisplayMedia) {
      navigator.mediaDevices.getDisplayMedia(displaymediastreamconstraints).then(success).catch(error);
    } else {
      navigator.getDisplayMedia(displaymediastreamconstraints).then(success).catch(error);
    }
  }
  //adding event listener
  addStreamStopListener = (stream, callback) => {
    stream.addEventListener('ended', () => {
      callback();
      callback = () => { };
    }, false);
    stream.addEventListener('inactive', () => {
      callback();
      callback = () => { };
    }, false);
    stream.getTracks().forEach((track) => {
      track.addEventListener('ended', () => {
        callback();
        callback = () => { };
      }, false);
      track.addEventListener('inactive', () => {
        callback();
        callback = () => { };
      }, false);
    });
    stream.getVideoTracks()[0].onended = () => {
      this.stop();
    };
  }
  // stop screen recording
  stop = async () => {
    await this.setState({ startDisable: true })
    recorder.stopRecording(this.stopRecordingCallback);
  }
  //destory screen recording
  stopRecordingCallback = async () => {
    await this.stopLocalVideo(this.state.screen, this.state.camera);
    let recordedVideoUrl;
    if (recorder.getBlob()) {
      this.setState({
        recordPreview: recorder.getBlob()
      })
      recordedVideoUrl = URL.createObjectURL(recorder.getBlob());
    }
    this.setState({
      recordedVideoUrl: recordedVideoUrl,
      screen: null,
      isOpenVideoModal: true,
      startDisable: false,
      stopDisable: true,
      camera: null,
    })
    recorder.screen.stop();
    recorder.destroy();
    recorder = null;
  }
  // stop audio recording
  stopLocalVideo = async (screen, camera) => {
    [screen, camera].forEach(async (stream) => {
      stream.getTracks().forEach(async (track) => {
        track.stop();
      });
    });
  }
  //close video modal
  videoModalClose = () => {
    this.setState({
      isOpenVideoModal: false
    })
  }
  //open load alert 
  openModal = async () => {
    await this.setState({ loadModal: false })
  }
  render() {
 window.onbeforeunload = this.openModal;
  return (
   <  div  >
      <  Topbar sr={true}  /  >
      <  Container className="pt-3">
       <  div className="centerCard">
       <  div className="shadow">
        <  Card   >
        <  CardBody  >
         <  Row  >
             < Col sm={12}  >
            <  h3 className='text-dark pb-2 textShadowHead text-center'>Screen Recording< /  h3  >
            < h5 className="text-primary my-2">Follow the below steps to do screen recording< /  h5  >
            < p className="mt-0 mb-1 textShadowPara">* To start recording click on start recording<  / p  >
            < p className="mt-0 mb-1 textShadowPara pr-1">* Select the screen type to start recording<  / p  >
            < p className="mt-0 mb-1 textShadowPara pl-1">* Click on share button to confirm recording<  / p  >
            < p className="pb-3 mt-0 mb-1 textShadowPara">* To stop recording click on stop recording<  / p  >
               <  / Col  >
              < /Row>
                    < Col sm={12} className="text-center"  >
    <  Button color='primary' outline onClick={() => this.startScreenRecord()} disabled={this.state.startDisable}  >Start Recording < /Button  >
    < Button color='primary' onClick={() => this.stop()} disabled={this.state.stopDisable}  >Stop Recording< /Button  >

                  {this.state.startDisable && < h3 className='text-success pt-2'>Recording..< /h3 }
                  {this.state.startDisable && < h3 className='text-warning pt-2'>Please dont refersh page.< /h3 >}
                    <  / Col  >
                  <  / Row  >
                <  / CardBody  >
              <  / Card  >
            <  / div  >
          <  / div  >
          <  ScreenRecordPreviewModal
          isOpenVideoModal={this.state.isOpenVideoModal}
         videoModalClose={this.videoModalClose}
          recordedVideoUrl={this.state.recordedVideoUrl}
            downloadScreenRecordVideo={this.downloadScreenRecordVideo}
            recorder={this.state.recordPreview}
          /  >
           <  / Container  >
      <  / div  >
   )
  }
}export default ScreenRecording;

After completion of screen recording by using the below code we canDisplay, pause, play, mute, unmute the recorded stream, and also can download it.

import React from 'react';
import { Modal, ModalBody, ModalHeader, Button, Row } from 'reactstrap';
import RecordRTC from 'recordrtc';

var isSafari = /^((?!chrome|android).)*safari/i.test(navigator.userAgent);

export default class ScreenRecordPreviewModal extends React.Component {
    constructor(props) {
        super(props);
        this.state = {
            isLoaded: false,
        }
    }
    // Download option for screen record
    downloadScreenRecordVideo = () => {
        let recorderBlob = this.props.recorder;
        if (!recorderBlob) {
            return;
        }
        if (isSafari) {
            if (recorderBlob && recorderBlob.getDataURL) {
                recorderBlob.getDataURL(function (dataURL) {
                    RecordRTC.SaveToDisk(dataURL, this.getFileName('mp4'));
                });
                return;
            }
        }
        if (recorderBlob) {
            var blob = recorderBlob;
            var file = new File([blob], this.getFileName('mp4'), {
                type: 'video/mp4'
            });
            RecordRTC.invokeSaveAsDialog(file);
        }
    };
    // Get file name 
    getFileName = (fileExtension) => {
        var d = new Date();
        var year = d.getFullYear();
        var month = d.getMonth();
        var date = d.getDate();
        return 'ScreenRecord-' + year + month + date + '-' + this.getRandomString() + '.' + fileExtension;
    }
    // Get random string for file name
    getRandomString = () => {
        if (window.crypto && window.crypto.getRandomValues && navigator.userAgent.indexOf('Safari') === -1) {
            var a = window.crypto.getRandomValues(new Uint32Array(3)),
                token = '';
            for (var i = 0, l = a.length; i < l; i++) {
                token += a[i].toString(36);
            }
            return token;
        } else {
            return (Math.random() * new Date().getTime()).toString(36).replace(/\./g, '');
        }
    }
    render() {
        return (
             <  Modal isOpen={this.props.isOpenVideoModal}  >
                < ModalHeader className="video__modal__header" toggle={this.props.videoModalClose} >
                    < button className="lnr lnr-cross video__modal__clsBtn formModalCloseButton" type="button"
                        onClick={this.props.videoModalClose}  />
                    < span className="bold-text">Preview Screen Record< /span >
                < /ModalHeader >
                < ModalBody >
                    < Row className='downloadButtonAlign' >
                        < Button color='primary' outline onClick={this.downloadScreenRecordVideo} >Download< /Button >
                    < / Row >
                    < video id="videorecord"
                        controls
                        // controlsList="nodownload"
                        autoPlay={this.state.isLoaded}
                        playsInline
                        width={'100%'} height={'100%'}
                        src={this.props.recordedVideoUrl} />
                < /ModalBody >
            < /Modal >
        )
    }
}

Add Comments

Submit Comments

More Blogs


What is Trade Finance Transaction?

Blockchain Technology In Trade Finance Transactions

Hari Kondlapudi        Views 376
block-chain-transform-your-business

BLOCKCHAIN TO TRANSFORM YOUR BUSINESS

Hari Kondlapudi        Views 345
block-chain-transform-your-business

LOCALIZATION WITH REACT

Hari Kondlapudi        Views 69

Contact Us

Address:

Do Systems Inc,
433 Plaza Real, Suite 275
Boca Raton, FL 33432 

Email: sales@dosystems.com
 
Copyright © Do Systems Inc. All rights reserved.