node.js - 将捕获的视频保存到Electron中的文件

标签 node.js video webrtc electron recordrtc

我要将从网络摄像头捕获的视频保存到本地文件。到目前为止,我已经能够:

  • 使用getUserMedia创建一个流
  • RecordRTC封装流。
  • RecordRTC获取blob

  • 我无法弄清楚如何将视频保存到文件中。在save()上调用RecordRTC可以下载视频文件,但是我希望一切都发生在nodejs中以进行进一步处理。该文件是可播放的,无论如何。我试图将Blob和dataURL写入文件,但是该文件不可播放。

    最佳答案

    在Chromium中实现的MediaRecorder类以及因此在Electron中实现的类可以支持您的用例。将媒体另存为文件不仅是可行的,而且可以说是微不足道的:

    const recorder = new MediaRecorder(await navigator.mediaDevices.getUserMedia());
    const blob_reader = new FileReader();
    const storage_stream = require("fs").createWriteStream(path);
    const blobs = [];
    blob_reader.addEventListener("load", ev => {
        storage_stream.write(Buffer.from(ev.currentTarget.result));
        if(blobs.length) ev.currentTarget.readAsArrayBuffer(blobs.shift());
    });
    recorder.addEventListener("dataavailable", ev => {
        if(blob_reader.readyState != 1) blob_reader.readAsArrayBuffer(ev.data);
        else blobs.push(ev.data);
    });
    
    缺少我认为将Blob对象转换为ArrayBuffer等效项的技术上可消耗且不希望(但必不可少)的步骤,这与API实现本身一样高效-JavaScript机器本身在此并不繁重。
    上面的摘录中的注释和解释:
  • 在您通过发出对 MediaRecorder.start 方法的调用来实际启动媒体记录器之前,将没有任何 Action 。请注意,如果需要,该代码段可与多个生成的Blob配合使用-视情况而定,使用1秒的时间片(start的第一个参数)可能是个好主意。这样的时间片允许您进行适当的数据流传输,而不是将潜在的巨大单值的已编码视频流存储在进程内存中(如果您将timeslice参数省略为start,则会得到此值)。
  • 一旦发出对start的调用(带有时间片),生成的文件将开始“在磁盘上”增长,具体取决于时间片的值和中间缓冲区的长度。
  • 作为编码媒体的一部分,MediaRecorder对象会生成blobs,由于某种原因,它不被许多其他API所“消耗”,因此我们必须将它们转换为可消耗的东西,在这种情况下为对我们来说 ArrayBuffer 类更方便。
  • 由于将blob转换为数组缓冲区是异步的,因此我们有一个blob队列,这些队列将根据FIFO进行适当转换。
  • require("fs")为我们提供了一个Node.js模块,“fs”不是您的Web浏览器中其他可用的模块,至少不是根据我所知道的Web标准草案。但是,这就是该模块,它使我们可以将所得的数组缓冲区转储到文件中。
  • 也许不起眼的表达式Buffer.from(...)在这里不仅仅令人眼前一亮-Web API空间中没有Buffer类,它是一个Node.js类,能够将ArrayBuffer包装为 View (不复制数据)。这是必要的,因为您不能直接将ArrayBuffer写入文件流。
  • 媒体记录器对象生成的数据的串联是有效的媒体容器(相对于记录器对象的MIME类型),因此,只要按照正确的顺序完成操作,将这些数据交给流就足够了我们有效的媒体容器文件(例如.webm.mp4)。
  • 但是,生成的文件是所谓的传输流-一些视频播放器可能会或可能无法可靠或有效地搜索数据。但是,ffmpeg可以通过对这些文件建立索引并进行相应的修补来对这些文件进行简单的后处理。我认为这样的步骤是可选的-传输流没有天生就错,就像上面的代码片段生成的一样。
  • 上面传递给pathcreateWriteStream变量表示要将视频保存到的文件的路径。变量未在代码段中声明或定义,但显然必须如此。

  • 我已经在Windows 10上使用3.0.4版本的Electron测试了该代码段。
    将媒体保存为文件的另一种方法(也可以与相当现代的Web浏览器一起使用)是将记录器提供的blob连接到一个blob中,然后让用户使用以下命令下载整个产品: URL.createObjectURL 方法。但是,我认为这种方法和上面说明的方法在功能或功能上并不相同-对于由不同的物理/虚拟RAM提供支持的Blob如何在不同的用户代理中实现,我不是100%的自信,例如-媒体文件可能会变得非常大,并且如果包含在blob中并用URL引用,则这些文件需要全部存储在RAM中,这可能是潜在的资源耗尽错误。相比之下,零散编写文件自然不会受到这种限制。无论如何,我将createObjectURL的应用程序留给读者练习,它应该相当简单,其他所有内容都已准备就绪。

    关于node.js - 将捕获的视频保存到Electron中的文件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41046709/

    相关文章:

    ios - Swift Play 视频无法显示

    video - 使用 ffmpeg 将图像序列转换为视频时颜色困惑

    javascript - 如何使用 webrtc 在 html5 页面中查看直播文件

    javascript - WebRTC - 在 web 应用程序中选择主摄像头(当设备有多个后置摄像头时)

    node.js - 将await/async 与Puppeteer 函数一起使用时出错

    node.js - 在 Heroku 上通过 https 运行 Keystone.js 应用程序

    javascript - 在bluemix中上传node.js应用程序

    Android VideoView 无法播放

    android - 我需要做什么才能为 Android (NDK) 构建(部分)WebRTC?它找不到 C++ header

    node.js - “NODE_OPTIONS”未被识别为内部或外部命令