Node.js Backend: Obtaining Audio Duration through Reading

You have two options to obtain audio duration. The first one is by using HTML5 audio API. Alternatively, you can utilize a client-side library, such as JavaScript-ID3-Reader, which can fetch just enough of the MP3 to read the ID3 tags. If you are using server-side JavaScript, you can easily read files from the server and perform any desired tasks.

Question:

I am attempting to determine the duration or length of an
audio file
through backend calculations. After uploading the audio file to S3, it is read in lambda. Despite utilizing a library, I have yet to find an effective solution. It should be noted that the solutions I have come across so far have only been for frontend calculations. In order to read the mp3 duration, I am storing the file in the temporary lambda folder. However, I encounter two different results depending on whether I use the direct S3 URL or s3.getobject. When using the former, the result is 0:00, whereas the latter results in the file being unable to be located.

s3.getObject({ Bucket: bucketName, Key: `audio/filename` }, function(err, data){   
                if (err) {
                    console.error(err.code, "-", err.message);
                }
                fs.writeFile(`/tmp/filename`, data.Body, function(err){
                    if(err)
                        console.log(err.code, "-", err.message);           
                    }); 
            });
            mp3Duration(`/tmp/filename`, function (err, duration) {
                if (err) return console.log(err.message);
                console.log('Your file is ' + duration + ' seconds long');
            });    



Solution:


The issue is that you are attempting to access the file prior to it being saved in the temporary directory.

s3.getObject({ Bucket: bucketName, Key: `audio/filename` }, function (err, data) {
    if (err) { console.error(err.code, "-", err.message); return; }
    fs.writeFile(`/tmp/filename`, data.Body, function (err) {
        if (err) { console.error(err.code, "-", err.message); return;}
        mp3Duration(`/tmp/filename`, function (err, duration) {
            if (err) { console.error(err.message); return;}
            console.log('Your file is ' + duration + ' seconds long');
        });
    });
});

The

mp3Duration

function has been relocated to the callback of

writeFile

.

To verify its functionality, I employed the mp3Duration function and observed that it operates smoothly on Node v15.12.0.

const mp3Duration = (fileName, callback) => {
  // do your work to find the duration and finally call the callback
  callback(null, duration)
};

This can be expressed using promises with async/await syntax.

const mp3Duration = (fileName) => {
  // do your work to find the duration and return a promise. In case of error return Promise.reject();
  return Promise.resolve(duration);
};
try {
    const object = await s3.getObject({ Bucket: bucketName, Key: `audio/filename` }).promise();
    await fs.promises.writeFile(`/tmp/filename`, object.Body);
    const duration = await mp3Duration(`/tmp/app.js`);
    console.log('Your file is ' + duration + ' seconds long');
} catch (err) {
    console.error(err);
}

Frequently Asked Questions