node.jsnode-streams

In node, how does one concatenate mp3 files using streams


I'm trying to concatenate a series of mp3 files into one mp3 file and failing miserably.

As far as I can tell, the code I'm using is correct but it's creating a file that contains only the string 'Done'.

const dhh = fs.createWriteStream("./dhh-interview.mp3");

clips.forEach((clip) => {
    currentfile = `${dirPath}\\${clip}`;
    stream = fs.createReadStream(currentfile);
    stream.pipe(dhh, { end: false });
    stream.on("end", function () {
      console.log(currentfile + " appended");
    });
  });

clips is an array containing the filenames of the files I want concatenating. I've done a console.log on currentfile so I know it's pointing to where it should.


Solution

  • It looks like the issue you're facing is related to how you're using the stream.pipe method and the way you're handling the end event for each stream. The code you provided is trying to concatenate multiple MP3 files, but it's not handling the MP3 file format correctly, which is why you're getting "Done" in the output file.

    To concatenate MP3 files properly, you should use a library that understands the MP3 format and can concatenate the audio streams correctly. One such library is ffmpeg, which is a powerful multimedia framework. You can use the ffmpeg command-line tool or a Node.js wrapper like fluent-ffmpeg to achieve this.

    Here's how you can concatenate MP3 files using fluent-ffmpeg:

    First, install the fluent-ffmpeg library if you haven't already:

    npm install fluent-ffmpeg
    

    Then, use the following code to concatenate your MP3 files:

    const ffmpeg = require('fluent-ffmpeg');
    const fs = require('fs');
    
    const clips = ['file1.mp3', 'file2.mp3', 'file3.mp3']; // Replace with your file names
    const outputFilePath = './concatenated.mp3'; // Replace with your desired output file path
    
    const concat = ffmpeg();
    
    clips.forEach((clip) => {
      concat.input(clip);
    });
    
    concat
      .on('end', function () {
        console.log('Concatenation finished.');
      })
      .on('error', function (err) {
        console.error('Error:', err);
      })
      .mergeToFile(outputFilePath, './tmp')
      .run();
    

    Make sure to replace 'file1.mp3', 'file2.mp3', etc., with the actual file paths of your MP3 files and './concatenated.mp3' with your desired output file path.

    This code uses fluent-ffmpeg to concatenate the MP3 files correctly, and it should produce the expected output without the "Done" issue you mentioned.