我想從我的服務器流到客戶端的MP3數據。我正在使用Ajax來做這件事。服務器每個請求發送50千字節。我寫了兩個函數:一個獲取mp3數據和一個播放它們。第一個函數需要50千字節,對它們進行解碼並將解碼數據存儲在一個數組中,然後遞歸地調用它自己。只要數組中的第一個元素填充數據,第二個函數就會開始播放。問題是,這隻適用於第一個50千字節,然後才失敗。我想要做的是保持我的get_buffer函數運行,直到服務器告訴它沒有更多的數據要發送,並保持我的play()函數播放數據,直到數組中沒有更多的元素。在javascript中的異步遞歸函數
這裏是我的兩個功能:
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();
}
}
「offset」變量告訴服務器開始服務器發送mp3音頻的哪個字節。因此,如果將偏移量發送到文件末尾或文件結束後,服務器會回覆「已完成」。我檢查一下arraybuffer的大小是否等於4,而不是必須「完成」。然後它返回false。對不起,這是我的不好,它應該是(buffer_seg()== false)。當它到達數組的末尾時,它調用buffer_seg()函數來查看buffer_seg是否將緩衝新數據或返回false來指示EOF。謝謝你的回覆 –
是的,我知道你打算抵消什麼。我不確定你爲什麼指出這一點;它不會改變您的代碼編寫過程中您的響應可能會失敗。另外,'(buffer_seg()== false)'不會更好,因爲調用'buffer_seg'永遠不會返回。無論如何,因爲你有'buffer_seg'自己調用,所以沒有'play'調用它的意思。 –
是的,我同意你的觀點,我可以看到這可能導致腳本無法正常運行,我甚至已經糾正了一些這些問題。但是,對於如何編寫一個函數來保存流式數據並將其存儲在數組中以及讀取該數組並存儲它的另一個函數中,您是否有任何建議?或者任何想法如何緩衝MP3二進制數據,並在整個緩衝完成之前播放它? –