2

At my endpoint in my NodeJS server, after retrieving an audio file stored as a Buffer in MongoDB, I want to represent it with a URL (much like how you do with URL.createObjectURL(blob) in the frontend on the browser). I then plan to res.render() the URL in HTML through Handlebars on the client, so that the user can click on it to download it:

<a href={{url}}>Click me to download the file!</a>

In the NodeJs server, I have converted the MongoDB Buffer into a JavaScript ArrayBuffer through:

var buffer = Buffer.from(recordingFiles[0].blobFile);
var arrayBuffer = Uint8Array.from(buffer).buffer;

I am unsure where to proceed from here. I seen solutions using fs or res.download(), but they don't seem applicable to my situation. Thanks in advance for any help!

2 Answers2

1

Do you always need to preload the audio file onto the page?

If not, then I would advise you to add a separate endpoint to download the file on demand. The frontend link can send a get request to the endpoint and download the file only if the user clicked it.
Otherwise you'd always be downloading the buffer behind the scenes, even if the user didn't intend to download it. This is especially problematic on slow connections.

Frontend:

<a href={{`${baseUrl}/download/${audioId}`}}>Click me to download the file!</a>

Backend:

const stream = require('stream');

app.get('/download/:audioId', function (request, response) {
  // Retrieve the tag from our URL path
  const audioId = request.params.audioId;
  
  const fileData; // TODO: Get file buffer from mongo.
  const fileContents = Buffer.from(fileData, 'base64');

  const readStream = new stream.PassThrough();
  readStream.end(fileContents);

  response.set('Content-disposition', 'attachment; filename=' + fileName);
  response.set('Content-Type', '<your MIME type here>');

  readStream.pipe(response);
});

A list of relevant MIME types can be found here.

EcksDy
  • 1,289
  • 9
  • 25
  • Solved my problem entirely! I was planning to fix the preloading thing after getting the data stream working but this has solved two things at once! Thank you!!! – Jack Walters Jun 15 '21 at 18:44
  • I had a feeling you'd run into that later. Also take a look at community guidelines(https://stackoverflow.com/help/someone-answers), it's ok to skip thank you's in the comments :) – EcksDy Jun 16 '21 at 07:51
0

Hopefully this can help.

var blob = new Blob(BUFFER, {type: "audio mime type"});
var link = document.createElement('a');
link.href = window.URL.createObjectURL(blob);
var fileName = reportName;
link.download = fileName;
link.click();
WoopWoop193
  • 13
  • 1
  • 5
  • Hi WoopWoop193 thank you for your answer. These seem like commands that would work in the frontend, while I need to create this href (URL) in the backend. As such I can't access 'Blob', 'document' or 'window'. – Jack Walters Jun 15 '21 at 10:14