编程语言
首页 > 编程语言> > javascript – 将desktopCapturer保存到Electron app的视频文件中

javascript – 将desktopCapturer保存到Electron app的视频文件中

作者:互联网

基于electron apithis question我试图将录制的用户屏幕保存到根应用程序文件夹中的视频文件夹中的.webm文件.

实际上它几乎正常工作,因为它保存了.webm文件,但保存的文件是空的,它的重量为0B ..我不知道我在这里缺少什么.

example file is 0 bytes

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

在debbuging时编辑我发现录制可能正常工作,因为我控制台日志的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在点击此控制器后按预期启动的.

stopRecording()函数在7秒后正确执行,它是console.log(‘保存视频:’文件);正好.

然后我去我刚刚创建的视频文件夹,打开我保存的example.webm文件,它是空的.

它不会在控制台中打印任何错误.

>我在stopRecording()函数中停止录制器后,我在consoled.log(blobs)中查看它是否实际是Blob.
>我在console.log(ab)内部toArrayBuffer(新Blob(blobs,{type:’video / webm’}),函数(ab){})回调.

screenshot of consoled things

我有行为,因为当没有时,blob包含值.

我真的无法自己解决,寻找答案我用最小的再现示例创建demo repository只是克隆它看你自己的行为

解决方法:

您的recorder.stop()将按如下方式运行:(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.

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

您必须重新调整stopRecording以确保记录的数据可用.例如:

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

标签:javascript,blob,electron,getusermedia,mediastream
来源: https://codeday.me/bug/20191007/1867510.html