标题: sourceBuffer failed to execute appendBuffer on sourceBuffer this sourc [打印本页] 作者: 守听 时间: 2024-9-24 11:50 标题: sourceBuffer failed to execute appendBuffer on sourceBuffer this sourc sourceBuffer failed to execute appendBuffer on sourceBuffer this sourcebuffer is still processing an appendbugger or remove operation, 这个报错
这个错误通常是由于在 SourceBuffer 还在处理前一个 appendBuffer 或 remove 操作时,又尝试执行另一个 appendBuffer 操作。这意味着在 appendBuffer 调用之间没有正确处理并等候前一个操作完成。
要办理这个问题,可以利用一个队列来存储要追加的数据块,并在前一个操作完成后再执行下一个操作。这是通过监听 sourceBuffer 的 updateend 事件来实现的。
以下是一个更详细的示例,确保在一个操作完成后再举行下一个操作:
完备的前端代码示例
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Audio Stream with MediaSource</title>
</head>
<body>
<audio id="audioElement" controls></audio>
<script>
if ('MediaSource' in window) {
var audio = document.getElementById('audioElement');
var mediaSource = new MediaSource();
audio.src = URL.createObjectURL(mediaSource);
mediaSource.addEventListener('sourceopen', function () {
var sourceBuffer = mediaSource.addSourceBuffer('audio/mpeg');
// 处理数据块追加的竞争问题
let queue = [];
let isAppending = false;
function appendNextChunk() {
if (queue.length > 0 && !isAppending) {
isAppending = true;
sourceBuffer.appendBuffer(queue.shift());
}
}
sourceBuffer.addEventListener('updateend', function () {
isAppending = false;
appendNextChunk();
});
sourceBuffer.addEventListener('error', function (e) {
console.error('SourceBuffer error:', e);
});
fetchAudioData();
});
function fetchAudioData() {
fetch('/audio') // 替换为你的音频流URL
.then(response => response.body.getReader())
.then(reader => {
function read() {
reader.read().then(({ done, value }) => {
if (done) {
mediaSource.endOfStream();
return;
}
queue.push(value);
appendNextChunk();
read();
});
}
read();
}).catch(error => {
console.error('Fetching audio data failed:', error);
});
}
} else {
console.log('The MediaSource API is not supported in this browser.');
}
</script>
</body>
</html>
复制代码
后端模拟(Java Servlet)
保持与之前的示例雷同的后端代码,模拟每秒钟返回1KB数据:
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.OutputStream;
import java.util.concurrent.TimeUnit;
@WebServlet("/audio")
public class SlowAudioStreamServlet extends HttpServlet {
private static final int CHUNK_SIZE = 1024; // 1 KB
private static final int HEADER_SIZE = 128; // 假设头信息大小为128字节