Воспроизведение живого аудиопотока — html5

У меня есть настольное приложение, которое передает необработанные данные PCM в мой браузер через соединение через веб-сокет. Поток выглядит так ...\\x00\\x00\\x02\\x00\\x01\\x00\\x00\\x00\\x01\\x00\\xff\\xff\\xff\\xff\\....

Вопрос простой: можно ли воспроизвести такой поток в HTML с Web Audio API/WebRTC/...?

Любые предложения очень приветствуются!

редактирование кода

Этот код воспроизводит шум, сгенерированный случайным образом:

function myPCMSource() { 
    return Math.random() * 2 - 3;
}

var audioContext;

try {
    window.AudioContext = window.AudioContext || window.webkitAudioContext;
    audioContext = new AudioContext();
} catch(e) {
    alert('Web Audio API is not supported in this browser');
}

var bufferSize = 4096;
var myPCMProcessingNode = audioContext.createScriptProcessor(bufferSize, 1, 1);
myPCMProcessingNode.onaudioprocess = function(e) {
    var output = e.outputBuffer.getChannelData(0);
    for (var i = 0; i < bufferSize; i++) {
     output[i] = myPCMSource(); 
 }
}

Таким образом, изменение myPCMSource() на вход потока веб-сокета должно заставить его как-то работать. Но это не так. Я не получаю никаких ошибок, но API не воспроизводит ни звука, ни шума.


person boortmans    schedule 01.06.2014    source источник
comment
Не уверен, что для этого есть готовое решение. Но это должно быть возможно с использованием WebAudioAPI и его ScriptNode. Может быть, я должен сесть и написать один. Используете ли вы какую-либо конкретную структуру для передачи потока веб-сокетов?   -  person notthetup    schedule 02.06.2014
comment
Мое приложение написано на Python, где я использую библиотеку websocket-client. Я также нашел эту статью, где кто-то пытается добиться того же (code.google.com/p/chromium/issues/detail?id=250989), но так и не удалось заставить его работать   -  person boortmans    schedule 02.06.2014


Ответы (1)


Используйте ScriptProcessorNode, но имейте в виду, что если нагрузка на основной поток (поток, который запускает ваш javascript, отрисовывает экран и т. д.) слишком велика, он может дать сбой.

Кроме того, ваш поток PCM, вероятно, находится в формате int16, а API веб-аудио работает в терминах float32. Преобразуйте его так:

output_float[i] = (input_int16[i] / 32767);

то есть перейти от [0; 65535] диапазон до [-1,0; 1,0] диапазон.

ИЗМЕНИТЬ Я использовал output_float[i] = (input_int16[i] / 32767 - 1);, эту статью показывает, что вы должны использовать output_float[i] = (input_int16[i] / 32767);. Теперь он работает нормально!

person padenot    schedule 03.06.2014
comment
Хорошо, поэтому я пытаюсь преобразовать свой поток в массив байтов, но это еще не правильно. Мои преобразованные значения находятся между 1:0 и -1:0 , но все еще есть NaN. Я конвертирую с (parseInt(str.substring(0, 8)), 16) / 32767) - 1;. Любые идеи? - person boortmans; 05.06.2014
comment
Получите ArrayBuffer из своего веб-сокета, а затем получите из него Uint16Array: var input_int16 = new Uint16Array(event.data);, где событие — это событие, которое вы получаете от своего веб-сокета. Тогда используйте мой код преобразования выше. - person padenot; 06.06.2014