Integrations, ML/AI and Design

In the previous post we saw a quick overview of WebRTC and tried understanding the reason why it is a game changing technology. In this post we will see one such potential use of WebRTC by integrating it to Salesforce, but before that let us see a demo and few use cases thereafter.

Demo

Click this link for a live demo of Screen sharing app using Salesforce and WebRTC integration. Once you select the application and hit share your will see the screen being shared in the canvas and a URL appears above the canvas that would be given to person with whom you want to share you screen. For this demo you can simply open the URL in a new window to see the shared screen. Make sure the mentioned extension is added to your chrome browser. Play around by changing the canvas size and screen place.

Salesforce WebRTC Private Room URL


Use cases

Sightcall.com promises to deliver a higher level of service and a better customer experience with the help of WebRTC support. A single touch from customers can connect them with a real person who is there to assist them and see problems as the customer sees it! Below are few such use cases that they proudly boast about.

  1. Live Visual Support - With live visual support in your Salesforce Service Cloud you can give your agents the ability to see what your customers see. Since agents and customers share screens and jointly navigate the same web pages at the same time, you enable your customer to show what’s wrong and help your agents to quickly resolves issues. This helps in closing claims faster and solve more problems by bringing your expert support agents closer to the problem.
  2. Pointer, Drawing and Annotations - Agents and customers can interact using the pointer to identify items of interest, circle buttons and/or free form draw.
  3. Recording - Customer support agents have the ability to record interactions with customers for quality control and training purposes.
  1. Reference - Agents can direct customers to useful information by simply opening a URL that opens a new browser tab directly to a web page
  2. Freeze frame - Agents can freeze/pause a screen in real time making it easier to review, draw and make annotations as the situation is discussed.
  3. Snapshot - Take a snap shot of a freeze frame or live video feed with annotations to preserve the information for future reference.

Code

Simply create a VF Page with the below code and preview the same. When the page loads it will ask which screen to share if you have two or more applications open. Select a screen and you will see the screen contents being displayed in the section as shown below.

<apex:page >
<html>

<head>
    <title>WebRTC Cropped Screen Sharing using RTCMultiConnection</title>
  
    
    <script src=""></script>
    <script src=""></script>
    
</head>

<body>
    <h1>
        Salesforce WebRTC Integration - Screen Sharing Demo
    </h1>
    <p>
        This demo works in Google Chrome Browser. You need to have <a href="" target="_blank">Screen Capturing Extension</a> in your browser to run this demo.
    </p>

    <div id="edit-panel">
        <div>
            <label for="x">X</label>
            <input type="number" name="x" id="x" value="0" />
        </div>
        <div>
            <label for="y">Y</label>
            <input type="number" name="y" id="y" value="0" />
        </div>
        <div>
            <label for="w">Width (-1 = Full size)</label>
            <input type="number" name="w" id="w" value="-1" />
        </div>
        <div>
            <label for="h">Height (-1 = Full size)</label>
            <input type="number" name="h" id="h" value="-1" />
        </div>
        <div>
            <button id="update">Update</button>
        </div>
    </div>

    <h2>Cropped Screen:</h2>
    <h1 id="private_url">
    </h1>
    <div id="LocalVideo"></div>

    <script>
    // this script tag is taken from: https://github.com/andersevenrud/webrtc-screenshare-crop-demo
    var CROP_X = 1;
    var CROP_Y = 1;
    var CROP_W = 1000; // default width
    var CROP_H = 500; // default height
    var VIDEO_WIDTH = 0;
    var VIDEO_HEIGHT = 0;
    var MAX_VIDEO_WIDTH = 1920;
    var MAX_VIDEO_HEIGHT = 1080;
    var _canvas;
    var _context;
    // Form elements
    document.getElementById("x").value = CROP_X;
    document.getElementById("y").value = CROP_Y;
    document.getElementById("w").value = CROP_W;
    document.getElementById("h").value = CROP_H;
    document.getElementById("update").addEventListener('click', function() {
        var x = document.getElementById("x").value << 0;
        var y = document.getElementById("y").value << 0;
        var w = document.getElementById("w").value << 0;
        var h = document.getElementById("h").value << 0;
        if (x >= 0) {
            CROP_X = x;
        }
        if (y >= 0) {
            CROP_Y = y;
        }
        CROP_W = w || 0;
        CROP_H = h || 0;
        if (_canvas) {
            if (_canvas.parentNode) {
                _canvas.parentNode.removeChild(_canvas);
            }
            _canvas = null;
            _context = null;
        }
        connection.send({
            CROP_X: CROP_X,
            CROP_Y: CROP_Y,
            CROP_W: CROP_W,
            CROP_H: CROP_H
        });
    });
    /**
     * Crops a video frame and shows it to the user
     */
    function CropFrame(ev, stream, video, callback) {
        if (!_canvas) {
            if (CROP_X < 0) {
                CROP_X = 0;
            }
            if (CROP_Y < 0) {
                CROP_Y = 0;
            }
            if (CROP_W <= 0) {
                CROP_W = VIDEO_WIDTH;
            }
            if (CROP_H <= 0) {
                CROP_H = VIDEO_HEIGHT;
            }
            if (CROP_W > MAX_VIDEO_WIDTH) {
                CROP_W = MAX_VIDEO_WIDTH;
            }
            if (CROP_H > MAX_VIDEO_HEIGHT) {
                CROP_W = MAX_VIDEO_HEIGHT;
            }
            _canvas = document.createElement('canvas');
            _canvas.width = CROP_W;
            _canvas.height = CROP_H;
            _context = _canvas.getContext('2d');
            document.getElementById("LocalVideo").appendChild(_canvas);
        }
        _context.drawImage(video, CROP_X, CROP_Y, CROP_W, CROP_H, 0, 0, CROP_W, CROP_H);
        // We need to scale down the image or else we get HTTP 414 Errors
        // Also we scale down because of RTC message length restriction
        var scanvas = document.createElement('canvas');
        scanvas.width = _canvas.width;
        scanvas.height = _canvas.height;
        var wRatio = _canvas.width / 320;
        var hRatio = _canvas.height / 240;
        var maxRatio = Math.max(wRatio, hRatio);
        if (maxRatio > 1) {
            scanvas.width = _canvas.width / maxRatio;
            scanvas.height = _canvas.height / maxRatio;
        }
        scanvas.getContext('2d').drawImage(_canvas, 0, 0, scanvas.width, scanvas.height);
        //callback(scanvas.toDataURL("image/jpeg"));
    }
    </script>

    <script>
    (function() {
        var params = {},
            r = /([^&=]+)=?([^&]*)/g;
        function d(s) {
            return decodeURIComponent(s.replace(/\+/g, ' '));
        }
        var match, search = window.location.search;
        while (match = r.exec(search.substring(1)))
            params[d(match[1])] = d(match[2]);
        window.params = params;
    })();
    var connection = new RTCMultiConnection();
    connection.session = {
        screen: true,
        data: true,
        oneway: true
    };
    connection.onmessage = function(event) {
        CROP_X = event.data.CROP_X;
        CROP_Y = event.data.CROP_Y;
        CROP_W = event.data.CROP_W;
        CROP_H = event.data.CROP_H;
        if (!_canvas) return;
        _canvas.width = CROP_W;
        _canvas.height = CROP_H;
    };
    connection.onstream = function(event) {
        var inited = false;
        event.mediaElement.addEventListener('timeupdate', function(ev) {
            if (!inited) {
                VIDEO_WIDTH = event.mediaElement.offsetWidth;
                VIDEO_HEIGHT = event.mediaElement.offsetHeight;
                event.mediaElement.style.display = 'none';
                event.mediaElement.style.visibility = 'hidden';
                inited = true;
            }
            CropFrame(ev, event.stream, event.mediaElement);
        });
    };
    if (params.sessionid) {
        // for participants
        connection.channel = connection.sessionid = params.sessionid;
        connection.join({
            sessionid: params.sessionid,
            userid: params.sessionid,
            extra: {},
            session: connection.session
        });
        document.getElementById('edit-panel').style.display = 'none';
    } else {
        // for initiator
        connection.channel = connection.sessionid = connection.userid;
        connection.open({
            dontTransmit: true,
            onMediaCaptured: function() {
                var domain = '';
                var resultingURL = domain + '?sessionid=' + connection.sessionid;
                document.getElementById('private_url').innerHTML = 'Share this private room URL: <p style="color:blue">' + resultingURL +'</p>';
                console.log('resultingURL:'+resultingURL);
            }
        });
    }
    </script>
</body>

</html>
</apex:page>

Page preview

Screen-sharing app with WebRTC and Salesforce

Screen Sharing

Screen sharing

Comment below with your queries if you are facing any challenges or are not able to see the demo. In the next post we will see a more advanced use case of Salesforce and WebRTC integration - Video Conferencing.


You’ve successfully subscribed to Inteygrate
Welcome back! You’ve successfully signed in.
Great! You’ve successfully signed up.
Your link has expired
Success! Check your email for magic link to sign-in.