XMLHttpRequest 和 http 流
XMLHttpRequest and http streaming
我的目标是从浏览器读取 HTTP MP3 音频流并访问原始音频数据。
HTML5 让我轻松播放流,但据我所知,不授予访问原始文件的权限音频数据。它只是播放它。
JS XMLHTTPRequest 可以通过 HTTP 下载文件并处理原始音频数据。它似乎是一个不错的候选者,但它有一个局限性:它在下载完成之前不授予对二进制数据的访问权限(readystate = 4)。在我的例子中,流是无限的,所以就绪状态永久保持在 3 并且 XHR 响应为空(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 运行 在本地主机服务器托管的页面上。
以下解决方法有效:
如 MDN https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest/Sending_and_Receiving_Binary_Data 中所述,可以覆盖 http 请求的 MIME 类型,将其设置为自定义,然后调用 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 相同的限制。它在状态 readystate=3 中不为空。
然后,使用
访问二进制 responseText
var filestream = load_binary_resource(url);
var abyte = filestream.charCodeAt(x) & 0xff; // throw away high-order byte (f7)
一个显着的缺点是 req.responseText 随着流的下载而不断增长。应不时重置请求以避免过多的 RAM 消耗。
我的目标是从浏览器读取 HTTP MP3 音频流并访问原始音频数据。
HTML5 让我轻松播放流,但据我所知,不授予访问原始文件的权限音频数据。它只是播放它。
JS XMLHTTPRequest 可以通过 HTTP 下载文件并处理原始音频数据。它似乎是一个不错的候选者,但它有一个局限性:它在下载完成之前不授予对二进制数据的访问权限(readystate = 4)。在我的例子中,流是无限的,所以就绪状态永久保持在 3 并且 XHR 响应为空(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 运行 在本地主机服务器托管的页面上。
以下解决方法有效:
如 MDN https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest/Sending_and_Receiving_Binary_Data 中所述,可以覆盖 http 请求的 MIME 类型,将其设置为自定义,然后调用 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 相同的限制。它在状态 readystate=3 中不为空。 然后,使用
访问二进制 responseTextvar filestream = load_binary_resource(url);
var abyte = filestream.charCodeAt(x) & 0xff; // throw away high-order byte (f7)
一个显着的缺点是 req.responseText 随着流的下载而不断增长。应不时重置请求以避免过多的 RAM 消耗。