worker.js 2.76 KB
Newer Older
范雪寒's avatar
范雪寒 committed
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108
(function () {
  'use strict';
  if (!importScripts) {
    var importScripts = (function (globalEval) {
      var xhr = new XMLHttpRequest;
      return function importScripts() {
        var
          args = Array.prototype.slice.call(arguments)
          , len = args.length
          , i = 0
          , meta
          , data
          , content
        ;
        for (; i < len; i++) {
          if (args[i].substr(0, 5).toLowerCase() === "data:") {
            data = args[i];
            content = data.indexOf(",");
            meta = data.substr(5, content).toLowerCase();
            data = decodeURIComponent(data.substr(content + 1));
            if (/;\s*base64\s*[;,]/.test(meta)) {
              data = atob(data);
            }
            if (/;\s*charset=[uU][tT][fF]-?8\s*[;,]/.test(meta)) {
              data = decodeURIComponent(escape(data));
            }
          } else {
            xhr.open("GET", args[i], false);
            xhr.send(null);
            data = xhr.responseText;
          }
          globalEval(data);
        }
      };
    }(eval));
  }


  importScripts('assets/libs/audio-recorder/lame.min.js');

  var mp3Encoder, maxSamples = 1152, samplesMono, lame, config, dataBuffer;

  var clearBuffer = function () {
    dataBuffer = [];
  };

  var appendToBuffer = function (mp3Buf) {
    dataBuffer.push(new Int8Array(mp3Buf));
  };

  var init = function (prefConfig) {
    config = prefConfig || {};
    lame = new lamejs();
    mp3Encoder = new lame.Mp3Encoder(1, config.sampleRate || 44100, config.bitRate || 128);
    clearBuffer();
    self.postMessage({
      cmd: 'init'
    });
  };

  var floatTo16BitPCM = function (input, output) {
    for (var i = 0; i < input.length; i++) {
      var s = Math.max(-1, Math.min(1, input[i]));
      output[i] = (s < 0 ? s * 0x8000 : s * 0x7FFF);
    }
  };

  var convertBuffer = function (arrayBuffer) {
    var data = new Float32Array(arrayBuffer);
    var out = new Int16Array(arrayBuffer.length);
    floatTo16BitPCM(data, out);
    return out;
  };

  var encode = function (arrayBuffer) {
    samplesMono = convertBuffer(arrayBuffer);
    var remaining = samplesMono.length;
    for (var i = 0; remaining >= 0; i += maxSamples) {
      var left = samplesMono.subarray(i, i + maxSamples);
      var mp3buf = mp3Encoder.encodeBuffer(left);
      appendToBuffer(mp3buf);
      remaining -= maxSamples;
    }
  };

  var finish = function () {
    appendToBuffer(mp3Encoder.flush());
    self.postMessage({
      cmd: 'end',
      buf: dataBuffer
    });
    clearBuffer();
  };

  self.onmessage = function (e) {
    switch (e.data.cmd) {
      case 'init':
        init(e.data.config);
        break;
      case 'encode':
        encode(e.data.buf);
        break;
      case 'finish':
        finish();
        break;
    }
  };
})();