Basing on electron api and this question I'm trying to save recorded user screen to .webm file in videos folder in root app folder.
Actually it's almost working because it save .webm file but the file which is saved is empty, it weigh 0B.. I don't know what I'm missing here.
So it looks like it's somehow not recording correctly because file is empty..
edit when debbuging I discovered that recording is probably working correctly because blobs which I console log has value inside, after toArrayBuffer
my blob no longer has value inside.
Code is:
(function () {
'use strict';
var fs = require('fs');
var { desktopCapturer } = require('electron');
var recorder, blobs = [];
angular
.module('app')
.controller('loggedScreen', Controller);
Controller.$inject = ['$scope'];
function Controller($scope) {
var startRecord = function () {
console.log('started');
desktopCapturer.getSources({types: ['window', 'screen']}, function(error) {
if (error) throw error;
navigator.webkitGetUserMedia({
audio: false,
video: {
mandatory: {
chromeMediaSource: 'desktop',
minWidth: 1280,
maxWidth: 1280,
minHeight: 720,
maxHeight: 720
}
}
}, handleStream, handleError);
return;
});
};
function handleError(err) {
console.log('something went wrong but it shouldnt');
}
function handleStream(stream) {
recorder = new MediaRecorder(stream);
blobs = [];
recorder.ondataavailable = function (event) {
blobs.push(event.data);
};
recorder.start();
}
function toArrayBuffer(blob, cb) {
var fileReader = new FileReader();
fileReader.onload = function() {
var arrayBuffer = this.result;
cb(arrayBuffer);
};
fileReader.readAsArrayBuffer(blob);
}
function toBuffer(ab) {
var buffer = new Buffer(ab.byteLength);
var arr = new Uint8Array(ab);
for (var i = 0; i < arr.byteLength; i++) {
buffer[i] = arr[i];
}
return buffer;
}
function stopRecording() {
recorder.stop();
console.log(blobs); // 300k bytes
toArrayBuffer(new Blob(blobs, {type: 'video/webm'}), function(ab) {
console.log(ab); // 0 bytes
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);
}
});
});
}
startRecord();
setTimeout(function() {
// stop recording after 7sec
stopRecording();
}, 7000);
}
})();
startRecord()
function is executed immediately, it also console.log
started as expected just after hitting this controller.
stopRecording()
function is executed after 7 second correctly, it console.log('Saved video: ' + file);
just fine.
Then I go to my just created videos folder I open my saved example.webm file and it's empty.
It doesn't print any error in console.
- I
consoled.log(blobs)
after stoping recorder instopRecording()
function to see if it's actually Blob. - I
console.log(ab)
insidetoArrayBuffer(new Blob(blobs, {type: 'video/webm'}), function(ab) {})
callback.
I've got behaviour as blobs
contains value when ab
not.
I really can't solve it myself, looking for answer I create demo repository with minimal reproduced example just clone it to see behaviour for your own
Your
recorder.stop()
will run as follows: (from MediaRecorder docs)In your case you don't wait up the
stop
event, sodataavailable
will fillblobs
only after you started the file saving method.You have to restructure
stopRecording
to ensure recorded data is available. For example: