我正在尝试将mp3数据从我的服务器传输到客户端。我正在使用Ajax这样做。服务器每个请求发送50千字节。我写了两个函数:一个获取mp3数据,另一个播放它们。第一个函数占用50千字节,对它们进行解码并将解码后的数据存储在一个数组中,然后递归调用。只要数组中的第一个元素填充了数据,第二个函数就会开始播放。问题是,这适用于前50千字节,然后失败。我想要做的是保持我的get_buffer函数运行,直到服务器告诉它不再发送数据,并保持我的play()函数播放数据,直到数组中没有更多的元素。
这是我的两个功能:
function buffer_seg() {
// starts a new request
buff_req = new XMLHttpRequest();
// Request attributes
var method = 'GET';
var url = '/buffer.php?request=buffer&offset=' + offset;
var async = true;
// set attributes
buff_req.open(method, url, async);
buff_req.responseType = 'arraybuffer';
// keeps loading until something is recieved
if (!loaded) {
change_icon();
buffering = true;
}
buff_req.onload = function() {
segment = buff_req.response;
// if the whole file was already buffered
if (segment.byteLength == 4) {
return true;
} else if (segment.byteLength == 3) {
return false;
}
// sets the new offset
if (offset == -1) {
offset = BUFFER_SIZE;
} else {
offset += BUFFER_SIZE;
}
//decodes mp3 data and adds it to the array
audioContext.decodeAudioData(segment, function(decoded) {
buffer.push(decoded);
debugger;
if (index == 0) {
play();
}
});
}
buff_req.send();
buff_seg();
}
第二功能:
function play() {
// checks if the end of buffer has been reached
if (index == buffer.length) {
loaded = false;
change_icon();
if (buffer_seg == false) {
stop();
change_icon();
return false;
}
}
loaded = true;
change_icon();
// new buffer source
var src = audioContext.createBufferSource();
src.buffer = buffer[index++];
// connects
src.connect(audioContext.destination);
src.start(time);
time += src.buffer.duration;
src.onended = function() {
src.disconnect(audioContext.destination);
play();
}
}
答案 0 :(得分:0)
对buffer_seg
的递归调用位于buffer_seg
的主体中,而不是在回调中,因此它会立即发生 - 而不是像您似乎想要的那样,在收到响应之后。其次,这也意味着递归调用是无条件的,它应该基于先前的响应是否指示更多数据可用。如果这不只是崩溃您的浏览器,我不知道为什么。这也意味着流式音频块可能无序地推入缓冲区。
首先,在检查流结束后,我会考虑将递归调用移动到onload
处理程序的末尾。
在第二个功能中,您打算if (buffer_seg == false)
做什么?永远不会满足这种情况。您是否认为这是查看buffer_seg
的最后返回值的方法?这不是它的工作原理。也许你应该有一个两个函数都可以看到的变量,buffer_seg
可以设置play
可以测试的变量,或类似的东西。