将捕获的视频保存到Electron中的文件 [英] Save captured video to file in Electron

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

问题描述

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

I want to save a video that is captured from webcam to a local file. So far I have been able to:


  1. 使用 getUserMedia 创建流li>
  2. RecordRTC

  3. RecordRTC获取blob来封装流

  1. Create a stream with getUserMedia
  2. Encapsulate the stream with RecordRTC
  3. Get blob from RecordRTC

虽然我不知道如何将视频保存到文件中。在 RecordRTC 上调用 save()允许我下载视频文件,但是我希望一切都发生在nodejs中以作进一步处理处理。该文件可以播放,无论如何。我试图将Blob和dataURL写入文件,但该文件不可播放。

I cannot figure out how to save the video to a file though. Calling save() on RecordRTC allows me to download the video file, but I want everything to happen in nodejs for further processing. The file is playable, regardless. I tried to write the blob and dataURL to file, but that file is not playable.

推荐答案

MediaRecorder 类,因此Electron可以单独支持您的用例,只需要编写媒体即可到本地文件。据我所知,使用任何标准化的Web API都无法实现后者的功能(截至撰写本文时),但是由于Electron嵌入了Node.js,因此不仅可以实现,而且可以说是微不足道的:

The MediaRecorder class implemented in Chromium and thus Electron, can support your use case alone save for the part of writing the media to a local file. The latter functionality isn't, to my knowledge, possible to achieve using any standardized Web APIs (as of the time of writing this), but since Electron embeds Node.js, it's not only possible but is arguably trivial:

navigator.mediaDevices.getUserMedia().then(function(stream) {
    const recorder = new MediaRecorder(stream);
    const blob_reader = new FileReader();
    const storage_stream = require("fs").createWriteStream(path);
    const blobs = [];
    blob_reader.addEventListener("load", function(ev) {
        storage_stream.write(Buffer.from(ev.currentTarget.result));
        if(blobs.length) {
            ev.currentTarget.readAsArrayBuffer(blobs.shift());
        }
    });
    recorder.addEventListener("dataavailable", function(ev) {
        if(blob_reader.readyState != 1) {
            blob_reader.readAsArrayBuffer(ev.data);
        } else {
            blobs.push(ev.data);
        }
    });
});

我认为技术上易消耗且不需要(但必要)的转换<$ c $的步骤简短c> Blob 对象等效于 ArrayBuffer 对象,这与API实现本身一样有效-JavaScript机器本身在此并不繁重。

Short of what I consider a technically expendable and undesired (but necessary) step of converting Blob objects to ArrayBuffer equivalents, this is as efficient as the API implementation itself is -- the JavaScript machine itself does no heavy lifting here.


  • 直到您通过发出 MediaRecorder.start 方法。请注意,如果需要,可以使该代码段与多个生成的Blob配合使用-视情况而定,使用1秒的时间片( start 的第一个参数)可能是个好主意。这样的时间片允许您进行适当的数据流传输,而不是将潜在的巨大单值编码视频流存储在进程内存中(如果您省略了时间片参数开始 )。

  • 只要调用开始(带有时间片),结果文件将开始在磁盘上增长,具体取决于时间片的值和中间缓冲区的长度。

  • A MediaRecorder 对象作为编码媒体的一部分,生成斑点由于某种原因,很多其他API都不非常消耗它们,因此我们必须将它们转换为可消耗的东西,在这种情况下,对于我们来说更方便的对象 ArrayBuffer 类。

  • Sinc将blob转换为数组缓冲区是异步的,我们有一个blob队列已在 FIFO 基础。

  • require( fs)为我们提供了一个Node.js模块, fs 不是不是您的Web浏览器中可用的模块,至少不是根据我所知道的Web标准草案。但是,这就是该模块,它使我们可以将所得的数组缓冲区转储到文件中。

  • 可能不太显眼的表达式 Buffer.from(...)远远不止这些-Web API空间中没有 Buffer 类,它是一个Node.js类,能够包装 ArrayBuffer 作为视图(不复制数据)。这是必要的,因为您不能将 ArrayBuffer 直接写入文件流。

  • 由媒体记录器生成的数据的串联对象是 valid 媒体容器(相对于记录器对象的MIME类型),因此,只要按照正确的顺序完成操作,将这些数据交给流就足以获取有效的媒体容器文件(例如 .webm .mp4 )。

  • 但是,生成的文件是所谓的传输流-一些视频播放器可能会或可能无法可靠或有效地搜索数据。但是, ffmpeg 可以通过对这些文件建立索引并进行相应的修补来对这些文件进行简单的后处理。我认为这样的步骤是可选的-传输流没有像上面的代码片段生成的流那样固有的错误。

  • 路径传递给上述 createWriteStream 的变量表示要将视频保存到的文件的路径。该变量未在代码段中声明或定义,但显然必须是。

  • There won't be any action until you actually start the media recorder by issuing a call to the MediaRecorder.start method. Note that the snippet is made to work with multiple generated blobs, if needed -- using a timeslice (first argument to start) of 1 second may be a good idea, depending. Such timeslice allows you to do proper streaming of data, as opposed to getting a potentially gigantic single blob worth of encoded video stream stored in process memory (which is what you get if you omit the timeslice parameter to start).
  • As soon as a call to start is issued (with a timeslice), the resulting file will start growing "on disk", depending on the timeslice value and lengths of intermediate buffers.
  • A MediaRecorder object, as part of encoding media, generates blobs which, for one reason or another, aren't very "consumable" by many other APIs, so we have to convert them to something that is consumable, in this case objects of the more convenient for us ArrayBuffer class.
  • Since conversion of a blob into an array buffer is asynchronous, we have a queue of blobs that is duly converted on a FIFO basis.
  • require("fs") gets us a Node.js module, "fs" is not a module otherwise available in your Web browser, at least not according to a Web standard draft I know of. That's the module, however, that allows us to dump the resulting array buffers into a file.
  • The perhaps inconspicuous expression Buffer.from(...) is more than meets the eye here -- there is no Buffer class in the Web API space, it's a Node.js class that is able to wrap an ArrayBuffer as a view (no data copying). This is necessary because you can't write an ArrayBuffer into a file stream directly.
  • A concatenation of data generated by a media recorder object is a valid media container (with respect to the MIME type of the recorder object), so just handing these data to the stream, when done in proper order of course, is sufficient to get us valid media container file (e.g. a .webm or an .mp4).
  • The resulting file is, however, a so called transport stream -- some video players may or may not be able to reliably or efficiently seek on the data. ffmpeg, however, can trivially postprocess such files by indexing them and patching them accordingly. I consider such step optional -- there is nothing inherently wrong with a transport stream like the ones generated by the snippet above.
  • The path variable passed to createWriteStream above denotes the path to the file you want to save the video to. The variable isn't declared or defined in the snippet, but it obviously must be.

我已经用3.0测试了代码段。 Windows 10上有4个版本的Electron。

I have tested the snippet with the 3.0.4 version of Electron on Windows 10.

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

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