darksigma
darksigma

Reputation: 313

Receive wav file and write it to disk on Node/Express Server

I'm sending a audio file to my Node/Express server using the following:

curl -X POST -H "Content-Type: audio/wav" --data-binary @"hello.wav" http://127.0.0.1:3000/extract_indicators/audio/darksigma

And I'm using the following code:

 ...

app.use(bodyParser.raw({ type: 'audio/wav', limit: '50mb' }));

 ...

app.post('/extract_indicators/audio/:user_id', function (req, res) {
  console.log("RECIEVED AUDIO TO EXTRACT INDICATORS: ", req.body);
  var writeStream = fs.createWriteStream('sample.wav');
  req.pipe(writeStream);
  res.sendStatus(200);
});

But the sample.wav file ends up being empty. Any ideas?

Upvotes: 2

Views: 4955

Answers (1)

robertklep
robertklep

Reputation: 203554

The problem is your use of the body-parser middleware. This will read the entire file into memory, and as a result, the req stream will be exhausted (completely read). This means you cannot subsequently pipe it to a file (because all the data has already been read).

You have two options:

  • Don't use body-parser at all, and pipe the request stream to the file (remove app.use(bodyParser.raw(...)) and the rest of your code would work as expected);
  • Leave the body-parser in and write req.body to a file:

    app.post('/extract_indicators/audio/:user_id', function (req, res) {
      fs.writeFile('sample.wav', req.body, function(err) {
        res.sendStatus(err ? 500 : 200);
      });
    });
    

Both have pro's and con's: not using body-parser means you have to check for the right content-type yourself, and limit the amount of data allowed to be uploaded (perhaps stream-meter can be useful there).

But using body-parser means that all uploaded files are completely read into memory first, which—especially for larger numbers of requests—can exhaust your server's memory.

Alternatively, you could consider allowing the files to be uploaded as multipart/form-data, so you could use something like multer, which is pretty configurable.

cURL can handle this too:

curl -XPOST -F file@hello.wav http://127.0.0.1:3000/extract_indicators/audio/darksigma

Upvotes: 4

Related Questions