2015-10-09 29 views
2

我的目标是从浏览器中读取HTTP MP3音频流并可以访问原始音频数据XMLHttpRequest和http流

  • HTML5 <音频>让我轻松地播放流,但据我所知,不授予访问原始音频数据。它只是玩它。

  • JS XMLHTTPRequest可以通过HTTP下载文件并处理原始音频数据。它似乎是一个很好的候选者,但它有一个限制:它不会授予对二进制数据的访问权限,直到下载完成(readystate = 4)。在我的情况下,这个流是无限的,所以readystate永远保持在3,XHR响应为null(这个行为在mozilla文档中有详细描述)。请注意,我连接到服务器的跨域策略是访问控制允许来源:*

代码示例,对于本地普通文件的工作,而不是流。我会在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运行在托管在本地主机服务器上的页面上。

+0

要清楚,您需要原始解码的PCM音频数据,而不是来自服务器的比特流,是的?如果是这样,那么Web Audio API就是您需要的。 – Brad

+0

@Brad事实上,我使用Web Audio 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的相同限制。它在状态readystate = 3中不为null。 然后,二进制的responseText与

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

一个显著的缺点是随着流下载的req.responseText保持增长访问。该请求应该不时重置以避免RAM消耗过多。

+1

有没有更新到今天? –

-2

您必须在主机上有本地主机服务器或脚本。 Becouse当您运行脚本文件,你会得到跨起源错误,当您尝试其他服务器上请求

+1

感谢您的输入。请注意,我连接到的服务器的跨源策略是Access-Control-Allow-Origin:* – astooooooo

+0

是,但是,如果您仅使用本地文件,则从某种服务器,浏览器会自动取消本地主机的所有请求 – Sebastian

+0

我再次检查外部服务器上的随机mp3文件。我得到了交叉原点错误。我试图下载的流有一个开放的跨源策略。尝试连接到它时,我没有收到任何CORS错误。问题在别处。 – astooooooo