Search code examples
javascriptnode.jselectron

Write file to disk from blob in electron application


I am creating an Electron Application in which I am recording data from webcam and desktop, at the end of the recording session, I want to save the data to a file in the background. I do not know how to write the data from a blob to a file directly. Any suggestions? Below is my current handling for MediaRecord Stop event.

this.mediaRecorder.onstop = (e) => {                                      
       var blob = new Blob(this.chunks,                                      
                           { 'type' : 'video/mp4; codecs=H.264' });                                                       
       var fs = require('fs');                                               
       var fr = new FileReader();                                            
       var data = null;                                                      
       fr.onload = () => {                                                   
           data = fr.result;                                                 
           fs.writeFile("test.mp4", data, err => {                           
               if(err) {                                                     
                   return console.log(err);                                  
               }                                                             
               console.log("The file was saved!");                           
           });                                                               
       };                                                                    
       fr.readAsArrayBuffer(blob);                                           
   }                          

Solution

  • You can do it using FileReader and Buffer.

    In the renderer process, send the event to the main process to save the file with the buffer:

    function saveBlob(blob) {
        let reader = new FileReader()
        reader.onload = function() {
            if (reader.readyState == 2) {
                var buffer = new Buffer(reader.result)
                ipcRenderer.send(SAVE_FILE, fileName, buffer)
                console.log(`Saving ${JSON.stringify({ fileName, size: blob.size })}`)
            }
        }
        reader.readAsArrayBuffer(blob)
    }
    

    Get back the confirmation:

    ipcRenderer.on(SAVED_FILE, (event, path) => {
        console.log("Saved file " + path)
    })
    

    (SAVE_FILE and SAVED_FILE are static strings containing event name)

    and in the main process:

    ipcMain.on(SAVE_FILE, (event, path, buffer) => {
        outputFile(path, buffer, err => {
            if (err) {
                event.sender.send(ERROR, err.message)
            } else {
                event.sender.send(SAVED_FILE, path)
            }
        })
    })
    

    outputFile is from 'fs-extra'

    Handling node operations in main process is preferred. See Electron Security suggestions.

    If you do want to not use main process, you can use 'electron-remote' to create background processes to write the file. Additionally, you can invoke ffmpeg in the background process to compress/encode the file into different format.