Home Salesforce Capture Screen using Lightning Component

Capture Screen using Lightning Component

by Dhanik Lal Sahni

Capturing screen of application was requirement in one of my project. We have used lightning component with Web API to capture screens. In this article, We will see the Screen Capture API and its getDisplayMedia()method to capture part or all of a screen for streaming.

Capturing screen contents

navigator.mediaDevices.getDisplayMedia() will capture screen content as live MediaStream . This function returns promise with live screen contents.

 navigator.mediaDevices.getDisplayMedia(displayMediaOptions)
                .then( mediaStream => {	
                    videoElem.srcObject = mediaStream;
                    videoElem.onloadedmetadata = e => {
                    videoElem.play();
                    videoElem.pause();
};
})

mediaStream containing the captured display imagery. It can be assigned on video element to show captured screen.

<video id="video" autoplay="true"></video>

Object displayMediaOptions contains the MediaStreamConstraints to pass into getDisplayMedia() function. These constraints available in MediaTrackConstraints for configuring a screen capture stream:

cursor : Indicates whether or not to capture the mouse cursor, and if so, whether to do so all the time.

logicalSurface : A Boolean values to indicate to capture offscreen areas of the source.

As we have captured screen, now we can download this image or we can save this in salesforce record object or we can send this to someone using email.

Below code will capture screen in canvas and from canvas we will convert it to dataURI.

canvas.width = videoElem.videoWidth;
canvas.height = videoElem.videoHeight;
canvas.getContext('2d').drawImage(video, 0, 0);
var dataUrl=canvas.toDataURL('image/jpg').replace(/^data:image\/(png|jpg);base64,/, '');
<canvas style="display:none;" id="canvas"></canvas>

Below code will download image from captured screen.

var image = canvas.toDataURL("image/png").replace("image/png", "image/octet-stream"); 
downloadImage(image, 'CapturedScreen.jpeg');


function downloadImage(data, filename = 'untitled.jpeg') {
            var a = document.createElement('a');
            a.href = data;
            a.download = filename;
            document.body.appendChild(a);
            a.click();
}

Below code will send email to user from captured screen.

{
    var dataUrl = canvas.toDataURL('image/jpg').replace(/^data:image\/(png|jpg);base64,/, '');
    
    var action = cmp.get("c.sendErrorEmail");
    action.setParams({
        data: dataUrl
    });
    
    // Create a callback that is executed after 
    // the server-side action returns
    action.setCallback(this, function(response) {
        var state = response.getState();
        debugger;
        if (state === "SUCCESS") {
            var data = response.getReturnValue();
            if (data != null) {
                alert('Email Sent');
            }
        } else if (state === "INCOMPLETE") {
            // do something
        } else if (state === "ERROR") {
            var errors = response.getError();
            if (errors) {
                if (errors[0] && errors[0].message) {
                    console.log("Error message: " + errors[0].message);
                }
            } else {
                //console.log("Unknown error");
            }
        }
    });
    $A.enqueueAction(action);
}

Apex code which will send email to user.

  @Auraenabled
    public static boolean sendErrorEmail(string data)
    {
        system.debug(data);
        if(data!=null)
        {
            list<Messaging.singleEmailMessage> mails=new list<Messaging.SingleEmailMessage>();
            Messaging.singleEmailMessage mail=new Messaging.SingleEmailMessage();
            
            list<Messaging.EmailFileAttachment> lstefa = new list<Messaging.EmailFileAttachment>();
            
            Messaging.EmailFileAttachment efa = new Messaging.EmailFileAttachment();
            
            efa.setfilename('ErrorFile.jpg');
            efa.setinline(true);
            efa.contenttype='image/jpg';
            Blob body = Encodingutil.base64Decode(data.substring(data.indexOf(',') + 1));
            efa.setbody(body);
            lstefa.add(efa);
            mail.setfileattachments(lstefa);
            mail.setToAddresses(new List<string>{'dhanik.sahni@conduent.com'});
            mail.setSubject('Errors');
            mail.setPlainTextBody('Error in Application.');
            mails.add(mail);
            messaging.sendEmail(mails);
        }
        return true; 
    }

Complete Source Code :

Demo Time:

You may also like

6 comments

Pradeep April 21, 2020 - 1:38 pm

Hi, looks great but for some reason its not working in my orgs. need help. thanks.

Reply
Dhanik Lal Sahni May 3, 2020 - 8:15 am

Hello Pradeep,
This will work till version 39 in Lightning component. After that lightning is blocking those external libraries. Please change lightning component version to 39 or use it in VF. It will work. Let me know, if you need any help.

Thank You,
Dhanik

Reply
chetan June 14, 2020 - 2:38 pm

can we use this in lwc or will it be supported

Reply
Dhanik Lal Sahni June 14, 2020 - 7:56 pm

No this was only for lighting component. You can use some other api like https://screenshotlayer.com/ which should work in LWC.

I will try to post a blog on this for LWC soon.

Thank You,
Dhanik

Reply
UMESH December 22, 2020 - 11:23 pm

Is there any other way to get Screenshot of particular section or div & save automatically after that on button click in Lightning?
Please guide me.

Reply
Dhanik Lal Sahni December 26, 2020 - 10:40 am

Hey Umesh,

Yes, it is possible. Once you are getting image binary, save that in your object record as attachment. See post https://salesforce.stackexchange.com/questions/46486/create-attachment-in-apex-to-store-encoded-signature for saving record.

You can use data element (line#74) of captureImageWebCamController.js to store value in record.

Thank You,
Dhanik

Reply

Leave a Comment