2013-08-21 14 views
7

Ho fatto un registratore audio utilizzando getUserMedia(). E salvando il file utilizzando Recorder.jsHTML5 Registrazione audio con basso kbps

Ma il file di output è molto più pesante di quanto mi piacerebbe.

Un record audio di 4 minuti ha qualcosa come 40mb. E non posso inviarlo al mio server. Se è così, si bloccherà.

Così, ho cercato come ridurre la registrazione kbps. Ma non ho trovato nulla. Solo alcune soluzioni Flash. Ma questi non si adattano al mio progetto.

Quindi, la mia domanda è, è possibile ridurre il kbps di un record audio utilizzando getUserMedia()?

risposta

1

Hai un paio di opzioni.

Innanzitutto, per riduzioni di dimensioni ridotte, è sempre possibile modificare il file recorderWorker.js in RecorderJS per utilizzare una frequenza di campionamento e una profondità di bit inferiori. Ciò richiederebbe un po 'di conoscenza di come funziona l'audio digitale e un certo livello di comfort con gli array digitati, ma non dovrebbe essere troppo difficile. Se si scende su quella strada, this page ha una spiegazione decente del formato WAVE. La riduzione della profondità di bit dovrebbe essere abbastanza semplice. Il downsampling può essere un po 'più complesso, ma dovrebbe comunque essere abbastanza fattibile con un po' di ricerca. Una volta che hai ottenuto la profondità di bit e la frequenza di campionamento che desideri, la modifica dell'intestazione nella funzione encodeWAV di RecorderJS dovrebbe essere piuttosto semplice.

L'altra opzione sarebbe quella di convertire in un formato con perdita (ad esempio MP3). This è l'unica libreria che conosco adesso che lo farà, anche se potrebbe essercene di più. Non ho effettivamente usato questo, e ho sentito che è un po 'lento - ma probabilmente lo puoi eseguire in un web worker se è un problema.

10

Nel mio caso, Chrome registra audio a 96kHz e Firefox a 44.1kHz, che rende enormi i file WAV. Ho implementato una funzione downsampling all'interno recorderWorker.js in cui è possibile selezionare il rapporto di campione desiderata, come 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; 
} 

e mi chiamo quando si esporta il file wav:

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

Nizza! Lo proverò il prima possibile! –

+0

un'altra strategia potrebbe non essere quella di calcolare il bitrate medio e considerare solo un campione per passo: 'risultato [offsetResult] = buffer [offsetBuffer];' –

+0

Questo sembra funzionare bene. – Knelis