2015-10-09 3 views
2

Моя цель: читать HTTP-аудиопоток HTTP из браузера и иметь доступ к необработанным аудиоданным.XMLHttpRequest и http streaming

  • HTML5 < аудио> позволяет мне легко играть поток, но, насколько я знаю, не предоставляет доступ к необработанным аудиоданных. Он просто играет.

  • JS XMLHTTPRequest может загружать файлы через HTTP и обрабатывать необработанные аудиоданные. Он кажется хорошим кандидатом, но он имеет ограничение: он не предоставляет доступ к двоичным данным до завершения загрузки (readystate = 4). В моем случае поток неограничен, поэтому readistate постоянно остается в 3, а XHR-ответ равен null (это поведение подробно описано в документации mozilla). Обратите внимание, что поперечное происхождение политикой сервера я подключаюсь является Access-Control-Allow-Origin: *

образца кода, который работает для местных регулярных файлов, но не для потоков. Я получаю исключения нулевого указателя на request.response.length

request = new XMLHttpRequest(); 
//request.open('GET', 'test.mp3', true); 
request.open('GET', 'http://domain.com/stream.mp3', true); 
request.responseType = 'arraybuffer'; 
request.onload = function() { 
    console.log("request onload"); 
    var audioData = request.response; 
    audioCtx.decodeAudioData(audioData, 
    function(buffer) { myBuffer = buffer; source.buffer = myBuffer; }, 
    function(e){"Error with decoding audio data" + e.err} 
); 
} 
request.onreadystatechange = function() { 
    console.log("ready state = " + request.readyState); 
    console.log(request.response.length); 
} 
request.send(); 

Кто-нибудь знает альтернативы или обходные пути для тех вариантов, так, что сырые бинарные пакеты могут быть считаны при загрузке потока?

Обратите внимание, что у меня нет контроля на сервере. Это поток icecast http. Кроме того, в браузере я бы хотел избежать использования Flash. Спасибо

Редактировать: для выяснения возможных вопросов, связанных с кросс-началом, JS запускается на странице, размещенной на сервере localhost.

+0

Чтобы быть ясным, вы хотите, чтобы необработанные декодированные аудио данные PCM, а не битовый поток с сервера, да? Если это так, Web Audio API - это то, что вам нужно. – Brad

+0

@Brad действительно я использую API веб-аудио (в качестве подсказки см., Например, метод decodeAudioData выше, в моем частичном коде). Мне просто не удалось получить буфер из потока и поместить его в API. Я думаю, что нашел решение, см. Мое решение ниже. – astooooooo

ответ

4

Следующие обходной путь работал:

Как указано в MDN https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest/Sending_and_Receiving_Binary_Data, можно переопределить тип MIME запроса HTTP , установив его в обычном режиме и вызовите responseText.

function load_binary_resource(url) { 
    var req = new XMLHttpRequest(); 
    req.open('GET', url, false); 
    //XHR binary charset opt by Marcus Granado 2006 [http://mgran.blogspot.com] 
    req.overrideMimeType('text\/plain; charset=x-user-defined'); 
    req.send(null); 
    if (req.status != 200) return ''; 
    return req.responseText; 
} 

Дело в том, что req.responseText не страдает от того же ограничения req.response. Он не равен нулю в состоянии readistate = 3. Затем двоичный responseText доступен с

var filestream = load_binary_resource(url); 
var abyte = filestream.charCodeAt(x) & 0xff; // throw away high-order byte (f7) 

Существенным недостатком является то, что req.responseText продолжает расти, как поток загружается. Время от времени запрос должен быть сброшен во избежание чрезмерного потребления ОЗУ.

+1

Есть ли какие-либо обновления до сегодняшнего дня? –

-2

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

+1

Спасибо за ваш вклад.Обратите внимание, что политика перекрестного происхождения подключаемого сервера - это Access-Control-Allow-Origin: * – astooooooo

+0

да, но если вы используете только локальный файл, с какого-то сервера, браузер автоматически отменяет все запросы из localhost – Sebastian

+0

Я дважды проверял случайный mp3-файл на внешнем сервере. Я получаю ошибку перекрестного происхождения. В потоке, который я пытаюсь загрузить, есть политика открытого креста. При попытке подключиться к нему я не получаю ошибку CORS. Проблема в другом месте. – astooooooo