electron - MediaRecorder Blob 在 Electron 应用程序中归档

标签 electron mediarecorder getusermedia

我有一个具有非常简单的桌面捕获功能的 Electron 应用程序:

const {desktopCapturer} = require('electron')
const fs = require('fs');

var recorder;
var chunks = [];
var WINDOW_TITLE = "App Title";

function startRecording() {
    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 === WINDOW_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);
    chunks = [];
    recorder.ondataavailable = function(event) {
        chunks.push(event.data);
    };
    recorder.start();
}

function stopRecording() {
    recorder.stop();
    toArrayBuffer(new Blob(chunks, {type: 'video/webm'}), function(ab) {
        var buffer = toBuffer(ab);
        var file = `./test.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 3.5 seconds and save to disk
startRecording();
setTimeout(function() { stopRecording() }, 3500);

我知道要保存 MediaRecorder blob 源,我需要将其读入 ArrayBuffer,然后将其复制到普通 Buffer 中以保存文件。

然而,这对我来说似乎失败的地方是将大块 blob 组合成 blob。当 block 被添加到单个 Blob 中时 - 就像它们消失了一样。新的 Blob 是空的,之后复制到的所有其他数据结构也是完全空的。

在创建 Blob 之前,我知道我在 chunks 数组中有有效的 Blob。

以下是 block 的调试信息,在执行 new Blob(chunks, {.. 之前部分。
console.log(chunks)

console.log(chunks)

然后这里是 new Blob(chunks, {type: 'video/webm'}) 的调试信息目的。
console.log(ab)

console.log(ab)

我完全被难住了。我能找到的所有引用教程或其他 SO 答案基本上都遵循这个流程。我错过了什么?

Electron 版:1.6.2

最佳答案

那是不可能的。您没有等待值(value)进入 stopReocoring。您需要将 stopRecording 函数更改为以下内容:

function stopRecording() {
    var save = function() {
        console.log(blobs);
        toArrayBuffer(new Blob(blobs, {type: 'video/webm'}), function(ab) {
            console.log(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);
                }
            });
        });
    };
    recorder.onstop = save;
    recorder.stop();
}

关于electron - MediaRecorder Blob 在 Electron 应用程序中归档,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43383399/

相关文章:

android - 如何以编程方式在android中录制静音视频

android - 如何暂停/恢复视频录制

javascript - WebRTC Chrome 相机限制

javascript - getUserMedia 使用确切的 : deviceId 为错误的相机创建流

java - 创建由较小文件组成的声音文件

HTML5 & Web 音频 api : Streaming microphone data from browser to server. 理想的传输和数据压缩

javascript - jQuery 查找元素 :contains, 然后获取类

visual-studio - 如何在Visual Studio中使用Breakpad符号调试Electron Shell?

node.js - 将 webview View 设置为窗口大小

javascript - 渲染器中的 Electron 非上下文感知 native 模块