Saving desktopCapturer to video file in Electron

℡╲_俬逩灬. 提交于 2019-12-03 03:26:58

I answered my own question with the help of Demian's link to MediaRecorder as well as other related questions.

Below is an excerpt from magnemite with some minor simplifications and converted from TypeScript to JavaScript ES5 for better understanding to most readers.

var fs = require('fs');
var electron = require('electron');

var SECRET_KEY = 'Magnemite';

var recorder;
var blobs = [];

function startRecording() {
    var title = document.title;
    document.title = SECRET_KEY;

    electron.desktopCapturer.getSources({ types: ['window', 'screen'] }, function(error, sources) {
        if (error) throw error;
        for (let i = 0; i < sources.length; i++) {
            let src = sources[i];
            if (src.name === SECRET_KEY) {
                document.title = title;

                navigator.webkitGetUserMedia({
                    audio: false,
                    video: {
                        mandatory: {
                            chromeMediaSource: 'desktop',
                            chromeMediaSourceId: src.id,
                            minWidth: 800,
                            maxWidth: 1280,
                            minHeight: 600,
                            maxHeight: 720
                        }
                    }
                }, handleStream, handleUserMediaError);
                return;
            }
        }
    });
}

function handleStream(stream) {
    recorder = new MediaRecorder(stream);
    blobs = [];
    recorder.ondataavailable = function(event) {
        blobs.push(event.data);
    };
    recorder.start();
}

function stopRecording() {
    recorder.stop();
    toArrayBuffer(new Blob(blobs, {type: 'video/webm'}), function(ab) {
        var buffer = toBuffer(ab);
        var file = `./videos/example.webm`;
        fs.writeFile(file, buffer, function(err) {
            if (err) {
                console.error('Failed to save video ' + err);
            } else {
                console.log('Saved video: ' + file);
            }
        });
    });
}

function handleUserMediaError(e) {
    console.error('handleUserMediaError', e);
}

function toArrayBuffer(blob, cb) {
    let fileReader = new FileReader();
    fileReader.onload = function() {
        let arrayBuffer = this.result;
        cb(arrayBuffer);
    };
    fileReader.readAsArrayBuffer(blob);
}

function toBuffer(ab) {
    let buffer = new Buffer(ab.byteLength);
    let arr = new Uint8Array(ab);
    for (let i = 0; i < arr.byteLength; i++) {
        buffer[i] = arr[i];
    }
    return buffer;
}

// Record for 7 seconds and save to disk
startRecording();
setTimeout(function() { stopRecording() }, 7000);

This will record the current electron window for 7 seconds and save to disk.

Take a look at the MediaRecorder API

You should convert that stream to binary chunks.

Thanks for the example, saved me tons of time.

The only thing when you do: recorder.stop();

you should put toArrayBuffer inside recorder.onstop = function(event) {

}

    function stopRecording() {
        recorder.stop();
        recorder.onstop = function (event) {
            toArrayBuffer(new Blob(blobs, { type: 'video/webm' }), function (ab) {
                var buffer = toBuffer(ab);
                var file = `./videos/example.webm`;
                fs.writeFile(file, buffer, function (err) {
                    if (err) {
                        console.error('Failed to save video ' + err);
                    } else {
                        console.log('Saved video: ' + file);
                    }
                });
            });
        }
    }
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!