szokrika
szokrika

Reputation: 41

save mp3 as ajax post data with node js

Not sure what am I doing wrong...

I have a node js webserver that should save a mp3 file to disk from an ajax post. The post contains an mp3 file constructed from a wav file created by recorder.js in the browser.

In my requestHandler I have the following code:

var
formidable = require('formidable'),
http = require('http'),
path = require('path'),
fs = require('fs');

function requestHandler(req, res) {

 var requestPath = path.basename(req.url) || 'index.html',
     ext = path.extname(requestPath),
     localFolder = __dirname + '/public/',
     uploadFolder = __dirname + '/uploads/';

if(requestPath === 'uploadmp3' && req.method === 'POST') {

    var form = new formidable.IncomingForm();

    form.parse(req, function(err, fields, files) {
        if(err) {
            console.error(err.message);
            return;
        }
        var mp3File = uploadFolder + fields.fname;
        var base64File = new Buffer(fields.data, 'binary').toString('base64');
        var decodedFile = new Buffer(base64File, 'base64').toString('binary');

        fs.writeFileSync(mp3File, decodedFile, 'base64', function(err){
            if(err) {
                return console.log(err);
            }
            console.log('written to disk: ' + mp3File);
        });

        res.writeHead(200, {'Content-Type:' : 'text/plain'});
        res.write(mp3File+ ' \n\n');
        res.end('\n');
    });

    return;
  }
}

The result is that I save the file to disk, but although it has the correct size, the time is not set properly and the playback last for one second.

I can save it with php with no problem... mp3 file plays perfectly, but I really need this to work on node js.

Upvotes: 0

Views: 2651

Answers (2)

Developer
Developer

Reputation: 1041

You need to use Stream to save contents to disk. As per your implementation:

var fs = require('fs');
if(requestPath === 'uploadmp3' && req.method === 'POST') {
    var mp3File = uploadFolder+'audio_feedback_' + new Date().getTime() + '.mp3';
    var mp3_file = fs.createWriteStream(mp3File);

    mp3_file.on('open', function (fd) {
        req.on('data', function(data){
            console.log("loading... \n");
            mp3_file.write(data);
        }); 

        req.on('end', function(){
            console.log("finalizing...");
            mp3_file.end();

            res.writeHead(200, {'Content-Type:' : 'text/plain'});
            res.write(mp3File+ ' is written to disk');
            res.end('\n');
        });
    });

}

Hope this helps.

Upvotes: 3

szokrika
szokrika

Reputation: 41

I have fixed it with:

if(requestPath === 'uploadmp3' && req.method === 'POST') {
    var mp3 = '';
    var mp3File = uploadFolder+'audio_feedback_' + new Date().getTime() + '.mp3';
    // req.setEcoding('base64');

    req.on('data', function(data){
        console.log("loading... \n");
        mp3 += data;
    });
    req.on('end', function(){
        console.log("request completed");

        fs.open(mp3File, 'w', function(err, fd) {
            if(err) {
                return console.log(err);
            }
            // console.log(mp3File + ' file was read...');
            fs.writeFile(mp3File, mp3, 'base64', function(err){
                if(err) {
                    return console.log(err);
                }
                console.log('written to disk: ' + mp3File);
            });
        });

        res.writeHead(200, {'Content-Type:' : 'text/plain'});
        res.write(mp3File+ ' is written to disk');
        res.end('\n');
    });

}

Upvotes: -1

Related Questions