将desktopCapturer保存到Electron应用程序的视频文件中 [英] Saving desktopCapturer to video file from Electron app

查看:429
本文介绍了将desktopCapturer保存到Electron应用程序的视频文件中的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

基于



所以它看起来好像没有正确录制,因为文件是空的..



编辑在重新布局时我发现录制可能正常正确,因为我控制台日志的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'];

函数Controller($ scope){

var startRecord = function(){
console.log('started');
desktopCapturer.getSources({types:['window','screen']},function(error){
if(error)throw error;
navigator.webkitGetUserMedia({
audio:false,
视频:{
强制:{
chromeMediaSource:'桌面',
minWidth:1280,
maxWidth:1280,
minHeight:720,
maxHeight:720
}
}
},handleStream,handleError);
返回;
});
};

函数handleError(错误){
console.log('出错了但它不应该');
}

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

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

函数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];
}
返回缓冲区;
}

函数stopRecording(){
recorder.stop();
console.log(blobs); // 300k字节
toArrayBuffer(新Blob(blobs,{type:'video / webm'}),函数(ab){
console.log(ab); // 0字节
var buffer = toBuffer(ab);
var file =`./ videos / example.webm`;
fs.writeFile(file,buffer,function(err){
if(err) {
console.error('无法保存视频'+错误);
}其他{
console.log('保存的视频:'+文件);
}
});
});
}

startRecord();
setTimeout(function(){
// 7秒后停止录制
stopRecording();
},7000);
}
})();

startRecord()函数立即执行,它也 console.log 在点击此控制器后按预期启动。



stopRecording()函数在正确的7秒后执行,它是 console.log( '已保存的视频:'+文件); 就好了。



然后我转到刚刚创建的视频文件夹中,打开已保存的 example.webm 文件,该文件为空。



它不会在控制台中输出任何错误。







  • consoled.log(blobs) stopRecording()中停止记录后看看它是否实际上是Blob。

  • console.log(ab)内到theArrayBuffer(新Blob(blob) ,{type:'video / webm'}),function(ab){}) callback。





我的行为为 blobs 包含值当 ab 没有。






我真的无法解决它我自己,寻找答案我创建了演示存储库,只需要复制一些示例,只需将其克隆到看你自己的行为

解决案例

您的 recorder.stop()将按如下方式运行:(来自MediaRecorder docs


调用stop()方法后,UA会按以下步骤对运行
的任务进行排队:


  1. 如果 MediaRecorder.state 处于非活动状态,引发DOM InvalidState 错误并终止这些步骤。如果 MediaRecorder.state 不是非活动,请继续执行下一步。

  2. MediaRecorder.state 设置为非活动并停止捕获媒体。

  3. 提升一个 dataavailable 事件,其中包含已收集的Blob数据。

  4. 提高停止事件。


在您的情况下,您不等待停止事件,因此 dataavailable 只有在您启动文件保存方法后才会填写 blobs



您必须重组 stopRecording 以确保记录的数据可用。例如:

  function stopRecording(){
const save =()=> {
...
}
recorder.onstop = save
recorder.stop()
}


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 in stopRecording() function to see if it's actually Blob.
  • I console.log(ab) inside toArrayBuffer(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)

When the stop() method is invoked, the UA queues a task that runs the following steps:

  1. If MediaRecorder.state is "inactive", raise a DOM InvalidState error and terminate these steps. If the MediaRecorder.state is not "inactive", continue on to the next step.
  2. Set the MediaRecorder.state to "inactive" and stop capturing media.
  3. Raise a dataavailable event containing the Blob of data that has been gathered.
  4. Raise a stop event.

In your case you don't wait up the stop event, so dataavailable will fill blobs only after you started the file saving method.

You have to restructure stopRecording to ensure recorded data is available. For example:

function stopRecording () {
  const save = () => {
    ...
  }
  recorder.onstop = save
  recorder.stop()
}

这篇关于将desktopCapturer保存到Electron应用程序的视频文件中的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆