내 서버에서 클라이언트 측으로 mp3 데이터를 스트리밍하려고합니다. 나는 Ajax를 사용하여 이것을하고있다. 서버는 요청 당 50KB를 보냅니다. 필자는 두 가지 기능을 썼습니다. 하나는 mp3 데이터를 가져오고 하나는 mp3 데이터를 재생합니다. 첫 번째 함수는 50 킬로바이트를 사용하여 디코드 한 다음 디코드 된 데이터를 배열에 저장 한 다음 재귀 적으로 호출합니다. 두 번째 함수는 배열의 첫 번째 요소가 데이터로 채워지 자마자 재생을 시작합니다. 문제는 처음 50 킬로바이트에서만 작동한다는 것입니다. 내가하고 싶은 일은 서버가 보낼 데이터가 더 이상 없다고 알리고 배열에 더 이상 요소가 없을 때까지 데이터를 재생하는 내 play() 함수를 유지할 때까지 get_buffer 함수를 계속 실행하는 것입니다.자바 스크립트의 비동기식 재귀 함수
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의 크기가 "done"보다 4보다 큰지 확인합니다. false를 반환합니다. 미안 해요, 내 버퍼가 있어야합니다 (buffer_seg() == false). buffer_seg() 함수가 배열의 끝에 도달하면 buffer_seg가 새 데이터를 버퍼링하는지 확인하거나 EOF를 나타내는 false를 반환합니다. 답장을 보내 주셔서 감사합니다. –
네, 오프셋하려는 의도를 알고 있습니다. 왜 당신이 이것을 지적하고 있는지 나는 확신 할 수 없다. 코드를 작성한 것처럼 응답이 순서대로 되돌아 올 수있는 것은 변하지 않습니다. 또한'(buffer_seg() == false)'는'buffer_seg'에 대한 호출이 절대로 돌아 오지 않기 때문에 더 잘 작동하지 않을 것입니다. 'buffer_seg' 자체를 호출했기 때문에 어떤 경우에도'play'라고하는 점이 없다. –
그래, 나는 당신의 요점에 동의, 어떻게 스크립트가 올바르게 실행되지 않을 수 있습니다 나는 심지어이 문제의 일부를 이미 수정 볼 수 있습니다. 그러나 스트리밍 데이터를 백그라운드로 유지하고 배열에 저장하는 함수와 배열을 읽고 저장하는 함수를 작성하는 방법에 대한 제안이 있습니까? 아니면 전체 버퍼링이 끝나기 전에 mp3 바이너리 데이터를 어떻게 버퍼링하고 재생할 수 있습니까? –