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

881 views Asked by At

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);
1

There are 1 answers

0
Matt Oestreich On BEST ANSWER

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}`);
});