9

In my electron application, users can record video from their webcam using the MediaRecorder API.

When the user hit the "stop record" button, I get a blob of the recorded video.

What i would like to do is to convert this blob to a real webm video and write it into the user's filesystem with for example :

fs.writeFile(localdir + '\\video.webm', videoBlob); // does not work

The example below works pretty well with base64 image snapshot that I get from the webcam, but i can't make it work with the video blob that I get.

Thanks for enlighten me !

Nuzzob
  • 371
  • 1
  • 4
  • 23

3 Answers3

18

An alternative to FileReader is a promise-based approach via Blob's arrayBuffer method:

async function saveFile() {

    const blob = new Blob(chunks, {
        type: 'video/webm'
    })


    const buffer = Buffer.from( await blob.arrayBuffer() );

    fs.writeFile('video.webm', buffer, () => console.log('video saved!') );

}
JeffD23
  • 8,318
  • 2
  • 32
  • 41
  • How can one do this with puppeteer's expose function ? Seems like sending blob or array buffer to the exposed function doesn't work because argument is JSON.strigified. blob.text() works to send it to the expose function but I'm not sure how to save it as a video file later. All my efforts end up with a corrupted video file :/ – ihor.eth Oct 02 '21 at 00:25
6

Create a video blob. chunks is an array of event.data from a MediaRecorder instance's ondataavailable

var blob = new Blob(chunks, {
    type: 'video/webm'
})

Read the blob as an ArrayBuffer, and use that to create a Buffer. Save the buffer as a file.

var reader = new FileReader()
reader.onload = function(){
    var buffer = new Buffer(reader.result)
    fs.writeFile(path, buffer, {}, (err, res) => {
        if(err){
            console.error(err)
            return
        }
        console.log('video saved')
    })
}
reader.readAsArrayBuffer(blob)
posit labs
  • 8,951
  • 4
  • 36
  • 66
  • 2
    I also have to contribute with a downvote here, because while this is indeed the obvious solution, it forces the Blob data to be read into memory, which may not exactly be gentle when you have a few hours of video (the Blob may or may not reside in memory by itself depending on how the browser decides, and if it doesn't, doing this will nuke it into the RAM). – John Weisz Feb 18 '19 at 19:38
  • 1
    @JohnWeisz IMO that's an edge case. I'd be happy to see your solution for that, regardless – posit labs Feb 19 '19 at 01:17
0

You need to use FileReader to read blob contents as an array and then create a Buffer instance.

I cannot get the audio to work though :(

demian85
  • 2,394
  • 3
  • 20
  • 20