Hardiksinh Gohil
Hardiksinh Gohil

Reputation: 160

Screen recording using RecordRTC - Unable to record video sounds playing on screen or through speaker

I am trying to record screen with videos playing on screen + microphone of user.

See demo: https://jsfiddle.net/4z447wpn/5/

Code below:

<!DOCTYPE html>
<html>
<head>
<title>Screen recording using RecordRTC</title>
<style>
    html, body{
        margin: 0!important;
        padding: 0!important;
        width: 100%;
        height: 100%;
    }
</style>
</head>
<body>

<video controls autoplay height="600" width="800" style="float: left; margin-top: 20px"></video>

<iframe width="420" height="315"  style="float: right; margin-top: 20px"
src="https://www.youtube.com/embed/9Zr2jjg1X-U">
</iframe> 

<script src="https://cdn.webrtc-experiment.com/RecordRTC.js"></script>
<script src="https://webrtc.github.io/adapter/adapter-latest.js"></script>
<script src="https://cdn.WebRTC-Experiment.com/getScreenId.js"></script>
<script>
function captureScreen(cb) {
    getScreenId(function (error, sourceId, screen_constraints) {
        navigator.mediaDevices.getUserMedia(screen_constraints).then(cb).catch(function(error) {
          console.error('getScreenId error', error);
          alert('Failed to capture your screen. Please check browser console logs for further information.');
        });
    });
}
function captureAudio(cb) {
    navigator.mediaDevices.getUserMedia({audio: true, video: false}).then(cb);
}
function keepStreamActive(stream) {
    var video = document.createElement('video');
    video.muted = true;
    setSrcObject(stream, video);
    video.style.display = 'none';
    (document.body || document.documentElement).appendChild(video);
}

captureScreen(function(screen) {
    keepStreamActive(screen);

    captureAudio(function(mic) {
        keepStreamActive(mic);

        screen.width = window.screen.width;
        screen.height = window.screen.height;
        screen.fullcanvas = true;

        var recorder = RecordRTC([screen, mic], {
            type: 'video',
            mimeType: 'video/webm',
            previewStream: function(s) {
                document.querySelector('video').muted = true;
                setSrcObject(s, document.querySelector('video'));
            }
        });

        //Start recording
        recorder.startRecording();

        //Stop recording after specific seconds
        setTimeout(function() {
            recorder.stopRecording(function() {
                var blob = recorder.getBlob();
                document.querySelector('video').src = URL.createObjectURL(blob);
                document.querySelector('video').muted = false;
                screen.getVideoTracks().forEach(function(track) {
                    track.stop();
                });
                screen.getAudioTracks().forEach(function(track) {
                    track.stop();
                });
                mic.getVideoTracks().forEach(function(track) {
                    track.stop();
                });
                mic.getAudioTracks().forEach(function(track) {
                    track.stop();
                });
            });
        }, 20 * 1000);

    });
});
</script>
</body>
</html>

Notes:

(1) Play iframe video(loaded on right-side) quickly after you allow access of browser screen and microphone, so it will start recording everything and it will auto stop after 20 seconds and will play recorded video. Pause right-side video to listen recorded sound.

(2) Chrome user needs to install extension: https://chrome.google.com/webstore/detail/screen-capturing/ajhifddimkapgcifgcodmmfdlknahffk

Problems I face:

(1) It is not recording sounds playing in videos on screen. Though it captures full screen with microphone of user.

(2) If I select current screen as screen capture window, it shows same screen in loop.

See problems in image : recordRTC-screenshot

Upvotes: 1

Views: 4695

Answers (1)

Muaz Khan
Muaz Khan

Reputation: 7236

Your demo works on localhost or on a non-iframe based HTTPs website after passing "second" parameter over getScreenId e.g.

getScreenId(callback, true);

Where second argument i.e. boolean true enabled the speakers.

Note: If still doesn't works then test on incognito to ignore/bypass cache.

Note2: Test on localhost or non-iframe HTTPs website i.e. on your own domain instead of jsfiddle.


Updated the answer on Tuesday May 08 2018

Please try this code:

<!DOCTYPE html>
<html>
<head>
    <title>Screen recording using RecordRTC</title>
    <style>
        html, body{
            margin: 0!important;
            padding: 0!important;
            width: 100%;
            height: 100%;
        }
    </style>
</head>
<body>
    <button class="btn btn-primary" id="stoprecording">STOP RECORDING</button>

    <video id="preview-screen" controls autoplay height="600" width="800" style="float: left; margin-top: 20px"></video>

    <video width="420" height="315" controls="" autoplay="" loop="" style="float: right; margin-top: 20px" onloadedmetadata="typeof OnLoadedMetaData === 'function' ? OnLoadedMetaData() : setTimeout(function() {OnLoadedMetaData();}, 3000);">
        <source src="https://commondatastorage.googleapis.com/gtv-videos-bucket/sample/BigBuckBunny.mp4" type="video/mp4">
    </video>

    <script src="https://cdn.webrtc-experiment.com/RecordRTC.js"></script>
    <script src="https://webrtc.github.io/adapter/adapter-latest.js"></script>
    <script src="https://cdn.WebRTC-Experiment.com/getScreenId.js"></script>
    <script>
    function captureScreen(cb) {
        getScreenId(function (error, sourceId, screen_constraints) {
            navigator.mediaDevices.getUserMedia(screen_constraints).then(cb).catch(function(error) {
              console.error('getScreenId error', error);
              alert('Failed to capture your screen. Please check browser console logs for further information.');
            });
        }, true);
    }
    function captureAudio(cb) {
        navigator.mediaDevices.getUserMedia({audio: true, video: false}).then(cb);
    }
    function keepStreamActive(stream) {
        var video = document.createElement('video');
        video.muted = true;
        setSrcObject(stream, video);
        video.style.display = 'none';
        (document.body || document.documentElement).appendChild(video);
    }

    var recorder = '';
    var screenRec = '';
    var micRec = '';

    function OnLoadedMetaData (){
        captureScreen(function(screen) {
            keepStreamActive(screen);

            captureAudio(function(mic) {
                keepStreamActive(mic);

                screen.width = window.screen.width;
                screen.height = window.screen.height;
                screen.fullcanvas = true;

                recorder = RecordRTC([screen, mic], {
                    type: 'video',
                    mimeType: 'video/webm',
                    previewStream: function(s) {
                        document.querySelector('#preview-screen').muted = true;
                        setSrcObject(s, document.querySelector('#preview-screen'));
                    }
                });

                screenRec = screen;
                micRec = mic;

                //Start recording
                recorder.startRecording();

            });

            addStreamStopListener(screen, function() {
                btnStopRecording.click();
            });
        });
    }

    var btnStopRecording = document.getElementById('stoprecording');
    btnStopRecording.onclick = function() {
        this.disabled = true;

        recorder.stopRecording(function() {
            var blob = recorder.getBlob();

            document.querySelector('#preview-screen').src = URL.createObjectURL(blob);
            document.querySelector('#preview-screen').muted = false;

            screenRec.getTracks().concat(micRec.getTracks()).forEach(function(track) {
                track.stop();
            });
        });
    };

    function addStreamStopListener(stream, callback) {
        var streamEndedEvent = 'ended';
        if ('oninactive' in stream) {
            streamEndedEvent = 'inactive';
        }
        stream.addEventListener(streamEndedEvent, function() {
            callback();
            callback = function() {};
        }, false);
        stream.getAudioTracks().forEach(function(track) {
            track.addEventListener(streamEndedEvent, function() {
                callback();
                callback = function() {};
            }, false);
        });
        stream.getVideoTracks().forEach(function(track) {
            track.addEventListener(streamEndedEvent, function() {
                callback();
                callback = function() {};
            }, false);
        });
    }
    </script>
</body>
</html>

Upvotes: 0

Related Questions