基于electron api和 this question我正在尝试将录制的用户屏幕保存到根应用程序文件夹中视频文件夹中的 .webm 文件。
实际上它几乎可以正常工作,因为它保存了 .webm 文件,但保存的文件是空的,它的重量为 0B..我不知道我在这里遗漏了什么。
所以它看起来好像没有正确记录,因为文件是空的..
编辑 调试时我发现记录可能正常工作,因为我控制日志的 blob 内部有值,在 toArrayBuffer
之后我的 blob 不再有内部值。
代码是:
(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()
函数立即执行,它也在 console.log
命中此 Controller 后按预期启动。
stopRecording()
函数在 7 秒后正确执行,它 console.log('Saved video: ' + file);
就好了。
然后我转到我刚刚创建的视频文件夹我打开我保存的 example.webm 文件,它是空的。
它不会在控制台中打印任何错误。
- 在
stopRecording()
函数中停止记录器后,我consoled.log(blobs)
看它是否真的是 Blob。 - 我
console.log(ab)
在toArrayBuffer(new Blob(blobs, {type: 'video/webm'}), function(ab) {})
回调。
我的行为是 blob
包含值而 ab
不包含值。
我自己真的解决不了,寻找我创建的答案demo repository使用最少的复制示例,只需克隆它即可查看您自己的行为
最佳答案
您的 recorder.stop()
将按如下方式运行:( from MediaRecorder docs )
When the stop() method is invoked, the UA queues a task that runs the following steps:
- If
MediaRecorder.state
is "inactive", raise a DOMInvalidState
error and terminate these steps. If theMediaRecorder.state
is not "inactive", continue on to the next step.- Set the
MediaRecorder.state
to "inactive" and stop capturing media.- Raise a
dataavailable
event containing the Blob of data that has been gathered.- Raise a
stop
event.
在您的情况下,您不会等待 stop
事件,因此 dataavailable
将仅在您启动文件保存方法后填充 blob
.
您必须重构stopRecording
以确保录制的数据可用。例如:
function stopRecording () {
const save = () => {
...
}
recorder.onstop = save
recorder.stop()
}
关于javascript - 从 Electron 应用程序将 desktopCapturer 保存到视频文件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49208343/