Search code examples
javascriptnode.jslamenode-lame

Why doesn't node-lame encode properly (nodeJS library)?


I've been trying to use the node-lame library to encode a file from the uploaded bitrate to 32 kbps to save space the same way I do it with sharp to compress my images.

My code first checks if the file is an audio file. If it is it then makes the encoder and it should encode it:

if (aud.test(user_file)){

        const encoder = new Lame({
            "output": req.file.path,
            "bitrate": 32,
        }).setFile(req.file.path);
        
        await encoder
            .encode()
            .then(() => {})
            .catch((error) => {
                // Something went wrong
            });
    }

The problem is that it doesn't actually get encoded. I have also tried this in my .then but it doesn't help.

.then(data => {
    fs.writeFileSync(req.file.path + '.mp3', data);
    user_file = user_file + '.mp3';
    fs.unlinkSync(req.file.path)
})

This is supposed to be a fairly simple library so I don't know what I'm doing wrong. I am trying to encode from file to file.

Also tried this:

const encoder = new Lame({
            "output": user_file + '.mp3',
            "bitrate": 32,
        }).setFile(req.file.path);

Solution

  • I went ahead and wrote a demo for this. You can find the full repo here. I have verified this does work but keep in mind this is only a proof of concept.

    This is what my Express server looks like:

    
    const express = require('express');
    const fs = require('fs');
    const path = require('path');
    const fileUpload = require('express-fileupload');
    const Lame = require('node-lame').Lame;
    
    const app = express();
    
    app.use(express.json());
    app.use(express.urlencoded({ extended: false }));
    app.use(fileUpload());
    
    // File upload path
    app.post('/upload', async (req, res) => {
      const fileToEncode = req.files.uploadedFile;
      if (!fileToEncode) {
        res.status(500).end();
        return;
      }
    
      const filePath = path.resolve('./uploads', fileToEncode.name);
      const outputPath = path.resolve('./uploads', fileToEncode.name + '-encoded.mp3');
    
      // Save uploaded file to disk
      await fileToEncode.mv(filePath);
    
      try {
        const encoder = new Lame({ 
          output: outputPath,
          bitrate: 8,
        }).setFile(filePath);
        await encoder.encode();
        res.download(outputPath);
      } catch (encodingError) {
        console.error(encodingError);
        res.status(500).send(encodingError);
      }
    
      // Removed files we saved on disk
      res.on('finish', async () => {
        await fs.unlinkSync(filePath);
        await fs.unlinkSync(outputPath);
      })
    });
    
    // Home page
    app.get('*', (req, res) => {
        res.status(200).send(`
        <!DOCTYPE html>
        <html>
        <body>
    
        <p id="status"></p>
    
        <form method="post" enctype="multipart/form-data" action="/upload" onsubmit="handleOnSubmit(event, this)">
          <input name="uploadedFile" type="file" />
          <button id="submit">Submit Query</button>
        </form>
    
        <script>
        async function handleOnSubmit(e,form) {
          const statusEl = document.getElementById("status");
          statusEl.innerHTML = "Uploading ...";
          e.preventDefault();
          const resp = await fetch(form.action, { method:'post', body: new FormData(form) });
          const blob = await resp.blob();
          const href = await URL.createObjectURL(blob);
          Object.assign(document.createElement('a'), {
            href,
            download: 'encoded.mp3',
          }).click();
          statusEl.innerHTML = "Done. Check your console.";
        }
        </script>
    
        </body>
        </html>    
        `);
    });
    
    process.env.PORT = process.env.PORT || 3003;
    
    app.listen(process.env.PORT, () => { 
        console.log(`Server listening on port ${process.env.PORT}`);
    });