BVSKanth
BVSKanth

Reputation: 111

Download a file from S3 to Local machine

I am trying to download an audio(mp3) file from AWS S3 to local computer. It works fine when I execute on local host, but after after deploying same code onto AWS. It's downloading files to server machine instead of User's local machine.

Tried these two versions. Both are doing in same way

Version 1:

    const key = track.audio_transcode_filename.substring(20);

    var s3Client = knox.createClient(envConfig.S3_BUCKET_TRACKS);
    const os = require('os');
    const downloadPath = os.homedir().toString();
    const config =require('../../config/environment');
    const fs = require('fs');
    var filePath=downloadPath + "\\Downloads\\" + track.formatted_title + ".mp3";
    if (fs.existsSync(filePath)) {
        var date = new Date();
        var timestamp = date.getTime();
        filePath=downloadPath + "\\Downloads\\" + track.formatted_title + "_" + timestamp + ".mp3";
     }
    const file = fs.createWriteStream(filePath);

    s3Client.getFile(key, function(err, res) {
      res.on('data', function(data) { file.write(data); });
      res.on('end', function(chunk) { file.end(); });
    });

version 2:

  var audioStream = '';

    s3Client.getFile(key, function(err, res) {
      res.on('data', function(chunk) { audioStream += chunk });
      res.on('end', function() { fs.writeFile(filePath + track.formatted_title + ".mp3", audioStream, 'binary')})
    }); 

Thanks, Kanth

Upvotes: 0

Views: 1701

Answers (3)

BVSKanth
BVSKanth

Reputation: 111

Thank you both @Rashomon and @Martin do santos. I'had to add client side script to read response stream and download file in the following way

downloadTrack(track).then((result) =>{
      //var convertedBuffer = new Uint8Array(result.data);
      const url = window.URL.createObjectURL(new Blob([result.data],{type: 'audio/mpeg'}));
      const link = document.createElement('a');
      link.href = url;
      link.setAttribute('download', track.formatted_title + '.mp3');
      document.body.appendChild(link);
      link.click();
  }, (error) =>{

  console.error(error);
})

Upvotes: 0

Martin Do Santos
Martin Do Santos

Reputation: 137

You'll need to send it to the user. So, I think you have an expressJS and the user can get the element using your API endpoint.

After all you have done in your question, you will need to send it to the user.

res.sendFile('/path/to/downloaded/s3/object')

Upvotes: 0

Rashomon
Rashomon

Reputation: 6762

Instead of getting the file and sending to client again, how about getting the url of the file and redirecting the client?

Something like:

s3Client.getResourceUrl(key, function(err, resourceUrl) {
  res.redirect(resourceUrl); 
)};

Upvotes: 1

Related Questions