1

I'm trying to build an Electron React App that captures short videos of the screen but am unable to store videos (as part of a larger "Payload" object:
{video_buffer: xxx, time_stamp: 3456345 ...}

The videos are created in the renderer process via MediaStream and MediaRecorder API's then converted to Blob. Here is some sample code:-

let mediaRecorder = new MediaRecorder(videoStream);
    mediaRecorder.start()
    let chunks = []
              
    mediaRecorder.ondataavailable = (event) => {chunks.push(event.data)}

    mediaRecorder.onstop = async (event) => {
            let blob = new Blob(chunks, {type: 'video/mp4'})    
            chunks = []
            const buffer = await blob.arrayBuffer()

The buffer works when I convert to a URL and set it to the Video element src

let videoURL = URL.createObjectURL(blob)

The videos are short and occupy about 2.5MB max.

I can only send the buffer (or the URL) via IPC (not the Blob).

In the main process, I'm using Mongoose with the schema:

new payloadSchema = {video_buffer: {type: Buffer}}

but this doesn't work, presumably because buffer is an ArrayBuffer and not a Data View or TypedArray.

So I tried converting it to a Uint8Array TypedArray object:

const new_buffer = new Uint8Array(buffer)

but i get this error on saving:

video_buffer: CastError: Cast to Buffer failed for value "Uint8Array(2041510) [
[electron]        26,  69, 223, 163, 159,  66, 134, 129,   1,  66, 247, 129,
[electron]         1,  66, 242, 129,   4,  66, 243, 129,   8,  66, 130, 132,
[electron]       119, 101,  98, 109,  66, 135, 129,   4,  66, 133, 129,   2,
[electron]        24,  83, 128, 103,   1, 255, 255, 255, 255, 255, 255, 255,
[electron]        21,  73, 169, 102, 153,  42, 215, 177, 131,  15,  66,  64,
[electron]        77, 128, 134,  67, 104, 114, 111, 109, 101,  87,  65, 134,
[electron]        67, 104, 114, 111, 109, 101,  22,  84, 174, 107, 171, 174,
[electron]       169, 215, 129,   1, 115, 197, 135, 155, 112,  30, 237,  62,
[electron]       162, 245, 131, 129,
[electron]       ... 2041410 more items
[electron]     ]" at path "video_buffer"

I then tried to convert the Uint8Array into a hex encoded string then storing that as a buffer .

On querying MongoDB in Terminal it has stored the string:

const buff_to_hex_string = new_buffer.toString('hex')

Then save it via Mongoose as before : (Schema {type: Buffer})

This seemed to work with following output from MongoDB:

The output of the saved Payload Schema is:

video_buffer: Binary {
[electron]     _bsontype: 'Binary',
[electron]     sub_type: 0,
[electron]     position: 9514868,
[electron]     buffer: <Buffer 32 36 2c 36 39 2c 32 32 33 2c 31 36 33 2c 31 35 39 2c 36 36 2c 31 33 34 2c 31 32 39 2c 31 2c 36 36 2c 32 34 37 2c 31 32 39 2c 31 2c 36 36 2c 32 34 32 ... 9514818 more bytes>

Question: On retrieving the stored buffer object, what is the easiest way to convert it back into an ArrayBuffer so that I can play it in a video element ?

Do I need to convert backwards --> hex string --> Uint8Array --> ArrayBuffer ---> Blob ---> URL ?

I've tried lots of methods provided but none work.

Any help would be much appreciated.

Thanks.

Radespy
  • 336
  • 2
  • 11
  • For media data of about 2.5 MB size, you can store as a document with field type `Binary Data` (alias `binData`). See [BSON Types](https://docs.mongodb.com/manual/reference/bson-types/index.html). You may want to search for storing (and retrieving) binary data within MongoDB document. – prasad_ Mar 02 '21 at 08:27
  • Thanks. Do you mean that I can use ‘Binary Data’ in the type field instead of Buffer ? – Radespy Mar 03 '21 at 00:12

1 Answers1

0

if you are using the mongodb driver you can directly store uint8array. it uses the bin type inside mongodb.

to convert it back just use the code below.

let buffer = uint8_obj.buffer;

then you can do whatever you like with the raw buffer.

desertnaut
  • 57,590
  • 26
  • 140
  • 166