2013-08-21 17 views
7

Zrobiłem audio rejestrator za pomocą getUserMedia(). I zapisanie pliku przy użyciu pliku Recorder.jsHTML5 Nagrywanie dźwięku z niską kbps

Ale plik wyjściowy jest znacznie cięższy niż chciałbym.

4-minutowy rekord audio zawiera około 40 MB. I nie mogę wysłać go na mój serwer. Jeśli tak, ulegnie awarii.

Poszukałem więc, jak zmniejszyć kbps nagrywania. Ale niczego nie znalazłem. Tylko niektóre rozwiązania Flash. Ale te nie pasują do mojego projektu.

Moje pytanie brzmi, czy można zmniejszyć kbps rekordu audio za pomocą funkcji getUserMedia()?

Odpowiedz

1

Masz kilka opcji.

Po pierwsze, w przypadku mniejszych rozmiarów, zawsze można zmodyfikować plik recorderWorker.js w aplikacji RecorderJS, aby użyć niższej częstotliwości próbkowania i głębokości bitowej. Wymagałoby to nieco wiedzy na temat działania cyfrowego dźwięku i pewnego poziomu komfortu pracy z wpisanymi tablicami - ale nie powinno być zbyt trudne. Jeśli pójdziesz tą drogą, this page ma przyzwoite wytłumaczenie formatu WAVE. Zmniejszanie głębi bitów powinno być dość proste. Próbkowanie w dół może być nieco bardziej skomplikowane, ale powinno być całkiem wykonalne przy odrobinie badań. Po uzyskaniu żądanej głębi i częstotliwości próbkowania zmiana nagłówka w funkcji RecorderJS na encodeWAV powinna być dość banalna.

Inną opcją byłoby przekonwertowanie na format stratny (np. MP3). This jest teraz jedyną biblioteką, jaka mi się teraz podoba, chociaż może być ich więcej. Nie używałem tego, i słyszałem, że jest nieco powolny - ale prawdopodobnie możesz uruchomić go w usłudze WWW, jeśli jest to problem.

10

W moim przypadku Chrome nagrywa audio z częstotliwością 96 kHz, a Firefox z częstotliwością próbkowania 44,1 kHz, co powoduje, że ogromne pliki WAV. I wdrożone funkcję przeprowadzający downsampling wewnątrz recorderWorker.js którym można wybrać współczynnik próbkowania chcesz, jak 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; 
} 

i wzywam go podczas eksportowania do pliku 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

Nice! Testuję to tak szybko, jak to możliwe! –

+0

Inną strategią może być nie obliczenie średniej przepływności i rozważenie tylko jednej próbki na krok: 'result [offsetResult] = buffer [offsetBuffer];' –

+0

To wydaje się działać dobrze. – Knelis

Powiązane problemy