Воспроизведение звука из буфера

Я пытаюсь создать приложение для голосового вызова в реальном времени. Моя цель - использовать родной JS-микрофон api и отправлять данные через websocket другим клиентам. Я понял следующий код:

<script>
// Globals
var aCtx;
var analyser;
var microphone;

navigator.getUserMedia_ = (   navigator.getUserMedia
                           || navigator.webkitGetUserMedia 
                           || navigator.mozGetUserMedia 
                           || navigator.msGetUserMedia);

if (navigator.getUserMedia_) {
    navigator.getUserMedia_({audio: true}, function(stream) {
        aCtx = new webkitAudioContext();
        analyser = aCtx.createAnalyser();
        microphone = aCtx.createMediaStreamSource(stream);
        microphone.connect(analyser);
        process();
    });
};
function process(){
    console.log(analyser);
    setInterval(function(){
        FFTData = new Float32Array(analyser.frequencyBinCount);
        analyser.getFloatFrequencyData(FFTData);

        console.log(FFTData); // display
    },10);
}

</script>

поэтому каждые 10 мс я собираюсь получить буфер и отправить его через node. Проблема в том, что я не мог понять, как играть в буфер, и я даже не уверен, правильно ли получаю буфер. Я пробовал:

var source = audioContext.createBufferSource();
var buffer; // the result printed in the code below
var audioBuffer = audioContext.createBuffer(1, buffer.length, 44100);
audioBuffer.getChannelData(0).set(buffer);
source.buffer = audioBuffer;
source.connect(audioContext.destination);

Правильно ли я получаю буфер? Как я могу играть?

Ответ 1

Чтобы выполнить воспроизведение буфера, вы должны вызвать метод start на вашем экземпляре AudioBufferSourceNode. Проблема здесь заключается в том, что вы хотите воспроизвести аудиопоток, а AudioBuffer не предназначен для этого. Если вы продолжаете создавать объекты AudioBuffer, заполняя их данными и предоставляя их вашему экземпляру AudioBufferSourceNode, наверняка будут заметные паузы в звуке.

Вместо этого вы должны сохранить буфер кеша, заполнить его, как только данные поступят, и выпустить его с нормальной скоростью (не сразу, вам нужно подождать, чтобы в нем было достаточно миллисекунд аудио).

Лучший способ сделать это - использовать надлежащие API-интерфейсы: посмотрите http://www.w3.org/TR/webaudio/#MediaStreamAudioDestinationNode-section и http://www.w3.org/TR/webaudio/#MediaStreamAudioSourceNode-section.