Skip to content

Instantly share code, notes, and snippets.

@TooTallNate
Last active April 6, 2024 14:03
Show Gist options
  • Select an option

  • Save TooTallNate/4170656 to your computer and use it in GitHub Desktop.

Select an option

Save TooTallNate/4170656 to your computer and use it in GitHub Desktop.

Revisions

  1. TooTallNate revised this gist Feb 13, 2013. 1 changed file with 7 additions and 1 deletion.
    8 changes: 7 additions & 1 deletion transcode.js
    Original file line number Diff line number Diff line change
    @@ -1,4 +1,8 @@

    /**
    * Module dependencies.
    */

    var fs = require('fs');
    var ogg = require('ogg');
    var lame = require('lame');
    @@ -7,7 +11,7 @@ var vorbis = require('vorbis');
    var od = new ogg.Decoder();

    od.on('stream', function (stream) {
    var vd = new vorbis.Decoder(stream);
    var vd = new vorbis.Decoder();

    // the "format" event contains the raw PCM format
    vd.on('format', function (format) {
    @@ -66,6 +70,8 @@ od.on('stream', function (stream) {
    console.log(err);
    // maybe try another decoder...
    });

    stream.pipe(vd);
    });

    fs.createReadStream(process.argv[2]).pipe(od);
  2. TooTallNate created this gist Nov 29, 2012.
    71 changes: 71 additions & 0 deletions transcode.js
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,71 @@

    var fs = require('fs');
    var ogg = require('ogg');
    var lame = require('lame');
    var vorbis = require('vorbis');

    var od = new ogg.Decoder();

    od.on('stream', function (stream) {
    var vd = new vorbis.Decoder(stream);

    // the "format" event contains the raw PCM format
    vd.on('format', function (format) {
    var bytesPerSample = format.bitDepth / 8;
    var encoder = new lame.Encoder();
    var out = fs.createWriteStream(new Date().getTime() + '.mp3');
    encoder.pipe(out);

    var leftover;
    vd.on('data', function (b) {

    // first we have to make sure that the Buffer we got is a multiple of
    // "float" sized, so that it will fit nicely into a Float32Array
    if (leftover) {
    b = Buffer.concat([ leftover, b ]);
    }
    var len = (b.length / bytesPerSample | 0) * bytesPerSample;
    if (len != b.length) {
    console.error('resizing Buffer from %d to %d', b.length, len);
    leftover = b.slice(len);
    b = b.slice(0, len);
    }

    // now that we know "b" is aligned to "float" sized, create a TypedArray
    // from it, and create an output Buffer where the "int" samples will go
    var floatSamples = new Float32Array(b);
    var o = new Buffer(floatSamples.length * 2);
    var intSamples = new Int16Array(o);

    // we need to convert all the float samples into short int samples
    // and populate the "intSamples" array
    for (var i = 0; i < floatSamples.length; i++) {
    var f = floatSamples[i];
    var val = Math.floor(f * 32767.0 + 0.5);

    // might as well guard against clipping
    if (val > 32767) {
    console.error('clipping detected: %d -> %d', val, 32767);
    val = 32767;
    }
    if (val < -32768) {
    console.error('clipping detected: %d -> %d', val, -32768);
    val = -32768;
    }
    intSamples[i] = val;
    }

    // write the populated "intSamples" Buffer to the lame encoder
    encoder.write(o);
    });
    });

    // an "error" event will get emitted if the stream is not a Vorbis stream
    // (i.e. it could be a Theora video stream instead)
    vd.on('error', function (err) {
    console.log(err);
    // maybe try another decoder...
    });
    });

    fs.createReadStream(process.argv[2]).pipe(od);