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.