2013-08-21 6 views
7

Ich habe einen Audio-Recorder mit getUserMedia(). Und speichern Sie die Datei mit dem Recorder.jsHTML5 Aufnahme von Audio mit niedrigen kbps

Aber die Ausgabedatei ist viel schwerer als ich es gerne hätte.

Ein 4 Minuten Audio-Datensatz haben so etwas wie 40 MB. Und ich kann es nicht an meinen Server senden. Wenn ja, wird es abstürzen.

Also habe ich gesucht, wie die Aufnahme kbps zu reduzieren. Aber ich habe nichts gefunden. Nur einige Flash-Lösungen. Aber diese passen nicht zu meinem Projekt.

Also, meine Frage ist, ist es möglich, die kbps eines Audio-Datensatzes mit dem getUserMedia() zu reduzieren?

Antwort

1

Sie haben ein paar Optionen.

Zunächst können Sie für kleinere Verkleinerungen die recorderWorker.js-Datei in RecorderJS immer ändern, um eine niedrigere Abtastrate und Bittiefe zu verwenden. Dies würde ein wenig Wissen darüber erfordern, wie digitales Audio funktioniert und ein gewisses Maß an Komfort beim Arbeiten mit typisierten Arrays - sollte aber nicht zu schwer sein. Wenn Sie diese Straße hinunter gehen, this page hat eine anständige Erklärung des WAVE-Formats. Die Verringerung der Bittiefe sollte ziemlich einfach sein. Downsampling kann ein wenig komplexer sein, sollte aber mit ein wenig Nachforschung noch machbar sein. Sobald Sie die gewünschte Bittiefe und Abtastrate erreicht haben, sollte die Änderung der Kopfzeile in der Funktion encodeWAV von RecorderJS ziemlich trivial sein.

Die andere Option wäre die Konvertierung in ein verlustbehaftetes Format (z. B. MP3). This ist die einzige Bibliothek, die ich im Moment kenne, die das tun wird, obwohl es vielleicht mehr gibt. Ich habe das nicht wirklich benutzt und gehört, dass es ein bisschen langsam ist - aber Sie können es wahrscheinlich in einem Web-Arbeiter ausführen, wenn es ein Problem ist.

10

In meinem Fall nimmt Chrome Audio bei 96kHz und Firefox bei 44,1kHz auf, das macht riesige WAV Dateien. Ich implementierte eine Downsampling-Funktion innerhalb recorderWorker.js, wo Sie die Probe Verhältnis auswählen können Sie wollen, wie 16000.

function downsampleBuffer(buffer, rate) { 
    if (rate == sampleRate) { 
     return buffer; 
    } 
    if (rate > sampleRate) { 
     throw "downsampling rate show be smaller than original sample rate"; 
    } 
    var sampleRateRatio = sampleRate/rate; 
    var newLength = Math.round(buffer.length/sampleRateRatio); 
    var result = new Float32Array(newLength); 
    var offsetResult = 0; 
    var offsetBuffer = 0; 
    while (offsetResult < result.length) { 
     var nextOffsetBuffer = Math.round((offsetResult + 1) * sampleRateRatio); 
     var accum = 0, count = 0; 
     for (var i = offsetBuffer; i < nextOffsetBuffer && i < buffer.length; i++) { 
      accum += buffer[i]; 
      count++; 
     } 
     result[offsetResult] = accum/count; 
     offsetResult++; 
     offsetBuffer = nextOffsetBuffer; 
    } 
    return result; 
} 

und ich es nennen, wenn die WAV-Datei exportieren:

function exportWAV(rate, type) { 
    var bufferL = mergeBuffers(recBuffersL, recLength); 
    var bufferR = mergeBuffers(recBuffersR, recLength); 
    var interleaved = interleave(bufferL, bufferR); 
    var downsampledBuffer = downsampleBuffer(interleaved, rate); 
    var dataview = encodeWAV(rate, downsampledBuffer, false); 
    var audioBlob = new Blob([ dataview ], { 
     type : type 
    }); 

    this.postMessage(audioBlob); 
} 
+0

Nice! Ich werde es so schnell wie möglich testen! –

+0

eine andere Strategie könnte nicht sein, die durchschnittliche Bitrate zu berechnen und nur eine Probe pro Schritt zu betrachten: 'result [offsetResult] = buffer [offsetBuffer];' –

+0

Dies scheint gut zu funktionieren. – Knelis