zhuker/lamejs

Save buffer to mp3 file

316xu opened this issue · 2 comments

316xu commented

I just write some code like this.

How can I save buffer to a mp3 file with nodejs?

var lamejs = require('lamejs');
var fs = require('fs');

function encodeMono(channels, sampleRate, samples) {
    var buffer = [];
    var mp3enc = new lamejs.Mp3Encoder(channels, sampleRate, 128);
    var remaining = samples.length;
    var maxSamples = 1152;
    for (var i = 0; remaining >= maxSamples; i += maxSamples) {
        var mono = samples.subarray(i, i + maxSamples);
        var mp3buf = mp3enc.encodeBuffer(mono);
        if (mp3buf.length > 0) {
            buffer.push(new Int8Array(mp3buf));
        }
        remaining -= maxSamples;
    }
    var d = mp3enc.flush();
    if(d.length > 0){
        buffer.push(new Int8Array(d));
    }
    
    console.log('done encoding, size=', buffer.length);
//    fs.open('test.mp3', 'w', (err, fd) => {
//        if (err) {
//            console.log(err);
//            return;
//        }
//        fs.write(fd, buffer, (err, written, buffer) => {
//            if (err) {
//                console.log(err);
//                return;
//            }
//            console.log('written:', written);
//        });   
//
//    });
}

function toArrayBuffer(buf) {
    var ab = new ArrayBuffer(buf.length);
    var view = new Uint8Array(ab);
    for (var i = 0; i < buf.length; ++i) {
        view[i] = buf[i];
    }
    return ab;
}

var wavFile = "./Left44100.wav";
//var request = new XMLHttpRequest();
//var request = XMLHttpRequest;
fs.readFile(wavFile, (err, data) => {
    let audioData = toArrayBuffer(data);
    console.log(audioData);
    
    var wav = lamejs.WavHeader.readHeader(new DataView(audioData));
    console.log('wav:', wav);
    var samples = new Int16Array(audioData, wav.dataOffset, wav.dataLen / 2);
    encodeMono(wav.channels, wav.sampleRate, samples);
});
316xu commented

I have solved it.

var lamejs = require('lamejs');
var fs = require('fs');

function encodeMono(channels, sampleRate, samples) {
    var buffers = [];
    var mp3enc = new lamejs.Mp3Encoder(channels, sampleRate, 128);
    var remaining = samples.length;
    var maxSamples = 1152;
    var length = 0;
    for (var i = 0; remaining >= maxSamples; i += maxSamples) {
        var mono = samples.subarray(i, i + maxSamples);
        var mp3buf = mp3enc.encodeBuffer(mono);
        if (mp3buf.length > 0) {
            length += mp3buf.length;
            buffers.push(Buffer.from(mp3buf));
        }
        remaining -= maxSamples;
    }
    var d = mp3enc.flush();
    if(d.length > 0){
        length += d.length;
        buffers.push(Buffer.from(d));
    }

    var mp3data = Buffer.concat(buffers, length);
    
    fs.writeFile('test.mp3', mp3data);
}

function toArrayBuffer(buf) {
    var ab = new ArrayBuffer(buf.length);
    var view = new Uint8Array(ab);
    for (var i = 0; i < buf.length; ++i) {
        view[i] = buf[i];
    }
    return ab;
}

var wavFile = "./Left.wav";

fs.readFile(wavFile, (err, data) => {
    let audioData = toArrayBuffer(data);
    var wav = lamejs.WavHeader.readHeader(new DataView(audioData));
    var samples = new Int16Array(audioData, wav.dataOffset, wav.dataLen / 2);
    encodeMono(wav.channels, wav.sampleRate, samples);
});

function toArrayBuffer(buf) {
var ab = new ArrayBuffer(buf.length);
var view = new Uint8Array(ab);
for (var i = 0; i < buf.length; ++i) {
view[i] = buf[i];
}
return ab;
}

Why do you need a wav file here? What's the purpose of this file?