TypeError: Failed to execute 'appendBuffer' on 'SourceBuffer': No function was found that matched the signature provided
TypeError: Failed to execute 'appendBuffer' on 'SourceBuffer': No function was found that matched the signature provided
编辑: 为了帮助说明我不断收到的错误,我创建了一个我遇到的问题的 CodePen。打开控制台,您将看到错误。 [https://codepen.io/FifthCloud/pen/eYpqJLN]
我想使用 React/Node 在家里设计自己的流媒体摄像头服务。到目前为止,我已经使用 Client/Server 方法走了很长一段路。服务器是 raspberry pi 并附有摄像头。使用 FFMpeg 我可以看到它的所有视频并使用 websockets 我可以成功发送数据(我的意思是我看到发送到客户端的数据将进入为什么它不会呈现)。
我 运行 遇到的问题是为什么我不能将数据附加到缓冲区。对于初学者,我使用这个关于 Media Source 的演示作为我应该做什么的指南和示例。 http://nickdesaulniers.github.io/netfix/demo/bufferAll.html I got this link from my research about Media Source's here: https://developer.mozilla.org/en-US/docs/Web/API/MediaSource/readyState
还想提一下,我从这个 post 中得到了很多灵感,并且因为这个答案
而走得很远
考虑到这一点,我可以成功创建 MediaSource
并打开缓冲区,但我不明白的是为什么我无法附加到缓冲区?我收到的错误是:
TypeError: Failed to execute 'appendBuffer' on 'SourceBuffer': No function was found that matched the signature provided.
客户端代码如下
class ProductDetail extends React.Component {
constructor(props) {
super(props);
this.handleData = this.handleData.bind(this);
this.handleOpen = this.handleOpen.bind(this);
this.appendToSourceBuffer = this.appendToSourceBuffer.bind(this);
this.mediaStreaming = new MediaSource();
this.blobArr = [];
this.buffer = null;
this.myRef = React.createRef();
console.log("buffer initialized");
console.log("ReadyState [Initialized]: " + this.mediaStreaming.readyState);
this.state = {
msg: "",
stream: "",
streaming: URL.createObjectURL(this.mediaStreaming),
};
}
componentDidMount() {
this.mediaStreaming.addEventListener("sourceopen", () => {
console.log(
"ReadyState [Source Open]: " + this.mediaStreaming.readyState
);
this.buffer = this.mediaStreaming.addSourceBuffer(
'video/mp4;codecs="avc1.42E01E"'
);
this.buffer.addEventListener("updateend", () => {
this.mediaStreaming.endOfStream();
document.getElementById("streaming").play();
console.log(
"ReadyState [UpdateEnd]: " + this.mediaStreaming.readyState
);
});
});
}
handleData(data) {
const videoStream = JSON.parse(data);
if (videoStream.msg === "videoStream") {
this.blobArr.push(videoStream.chunk.data);
if (
this.mediaStreaming.readyState === "open" &&
this.buffer &&
this.buffer.updating === false &&
this.blobArr.length > 0
) {
console.log(
"ReadyState [AppendBuffer]: " + this.mediaStreaming.readyState
);
this.buffer.appendBuffer(this.blobArr.shift()); // Error message shows at this line!
document.getElementById("streaming").play();
console.log("Buffer Updating", this.buffer.updating);
}
}
}
handleOpen() {
console.log("Status: connected");
}
handleClose() {
console.log("Status: disconnected");
}
render() {
return (
<div>
<Websocket
url="ws://192.168.1.20:5000"
onMessage={this.handleData}
onOpen={this.handleOpen}
onClose={this.handleClose}
reconnect={true}
debug={true}
ref={(Websocket) => {
this.refWebSocket = Websocket;
}}
protocol="stream-protocol"
/>
<video width="640" height="480" id="streaming" controls autoPlay>
<source
ref={this.myRef}
src={this.state.streaming}
type="video/mp4"
/>
Your browser does not support the video tag.
</video>
</div>
);
}
}
当服务器发送下一个流式字节数组数据时,错误来自我的 WebSocket 的 handleData
事件。
正如我在 link 中提到的示例和指南,我已经 post 阅读了他们的代码并逐步完成了它。根据他们的说法,Append Buffer 应该可以正常工作,但是即使在他们的代码中,appendbuffer()
也仅列在 proto 部分中,请参见此处:https://drive.google.com/open?id=1vOU4oM-XoKe71DofQuLU2THxMdgiown_ and yet the code doesn't complain about their appendbuffer(). When I console log my buffer it looks like theirs https://drive.google.com/open?id=1T4Ix-y124NgQJ9xu97xv4U2yFTn2k7vF。我错过了什么?
我觉得答案很明显,但我不知道我做错了什么。
我自己正在构建一个类似的项目,使用多个支持 RTSP 的高端 IP 摄像头,今天 运行 遇到了同样的错误。首先,请记住,根据 Mozilla 开发者网络 (MDN) 文档(link,此 API 是实验性的。
话虽这么说,但我似乎找到了问题的根本原因,尽管我无论如何都不是 JavaScript 专家。事实证明,你不能直接将 data.data
中的 handleData()
中的 "Blob" 对象传递给 appendBuffer()
方法。相反,您需要先将 Blob 转换为 appendBuffer()
方法支持的数据类型,然后再将其传入。
- 将您的事件处理程序变成
async
函数
- 使用
Blob.arrayBuffer()
将数据 blob 转换为 JavaScript ArrayBuffer
改变这个:
handleData(data) {
const videoStream = JSON.parse(data);
if (videoStream.msg === "videoStream") {
this.blobArr.push(videoStream.chunk.data);
if (
this.mediaStreaming.readyState === "open" &&
this.buffer &&
this.buffer.updating === false &&
this.blobArr.length > 0
) {
console.log(
"ReadyState [AppendBuffer]: " + this.mediaStreaming.readyState
);
this.buffer.appendBuffer(this.blobArr.shift()); // Error message shows at this line!
document.getElementById("streaming").play();
console.log("Buffer Updating", this.buffer.updating);
}
}
}
进入这个:
async handleData(event) {
var buffer = await event.data.arrayBuffer(); // convert the message Blob into an ArrayBuffer
appendBuffer(buffer);
document.getElementById("streaming").play();
console.log("Buffer Updating", this.buffer.updating);
}
问题是,一旦执行此操作,您将开始收到新错误,因为有太多数据被传递到 MediaSource
上的 SourceBuffer
对象。由于它跟不上输入流,您会看到类似于以下错误的内容:
Failed to execute 'appendBuffer' on 'SourceBuffer': This SourceBuffer is still processing an 'appendBuffer' or 'remove' operation
看来我们需要 "buffer the buffers," 听起来很奇怪。
我还没有解决这个新错误。如果您找到解决方案,我很乐意提供帮助。
相关阅读
编辑: 为了帮助说明我不断收到的错误,我创建了一个我遇到的问题的 CodePen。打开控制台,您将看到错误。 [https://codepen.io/FifthCloud/pen/eYpqJLN]
我想使用 React/Node 在家里设计自己的流媒体摄像头服务。到目前为止,我已经使用 Client/Server 方法走了很长一段路。服务器是 raspberry pi 并附有摄像头。使用 FFMpeg 我可以看到它的所有视频并使用 websockets 我可以成功发送数据(我的意思是我看到发送到客户端的数据将进入为什么它不会呈现)。
我 运行 遇到的问题是为什么我不能将数据附加到缓冲区。对于初学者,我使用这个关于 Media Source 的演示作为我应该做什么的指南和示例。 http://nickdesaulniers.github.io/netfix/demo/bufferAll.html I got this link from my research about Media Source's here: https://developer.mozilla.org/en-US/docs/Web/API/MediaSource/readyState
还想提一下,我从这个 post 中得到了很多灵感,并且因为这个答案
考虑到这一点,我可以成功创建 MediaSource
并打开缓冲区,但我不明白的是为什么我无法附加到缓冲区?我收到的错误是:
TypeError: Failed to execute 'appendBuffer' on 'SourceBuffer': No function was found that matched the signature provided.
客户端代码如下
class ProductDetail extends React.Component {
constructor(props) {
super(props);
this.handleData = this.handleData.bind(this);
this.handleOpen = this.handleOpen.bind(this);
this.appendToSourceBuffer = this.appendToSourceBuffer.bind(this);
this.mediaStreaming = new MediaSource();
this.blobArr = [];
this.buffer = null;
this.myRef = React.createRef();
console.log("buffer initialized");
console.log("ReadyState [Initialized]: " + this.mediaStreaming.readyState);
this.state = {
msg: "",
stream: "",
streaming: URL.createObjectURL(this.mediaStreaming),
};
}
componentDidMount() {
this.mediaStreaming.addEventListener("sourceopen", () => {
console.log(
"ReadyState [Source Open]: " + this.mediaStreaming.readyState
);
this.buffer = this.mediaStreaming.addSourceBuffer(
'video/mp4;codecs="avc1.42E01E"'
);
this.buffer.addEventListener("updateend", () => {
this.mediaStreaming.endOfStream();
document.getElementById("streaming").play();
console.log(
"ReadyState [UpdateEnd]: " + this.mediaStreaming.readyState
);
});
});
}
handleData(data) {
const videoStream = JSON.parse(data);
if (videoStream.msg === "videoStream") {
this.blobArr.push(videoStream.chunk.data);
if (
this.mediaStreaming.readyState === "open" &&
this.buffer &&
this.buffer.updating === false &&
this.blobArr.length > 0
) {
console.log(
"ReadyState [AppendBuffer]: " + this.mediaStreaming.readyState
);
this.buffer.appendBuffer(this.blobArr.shift()); // Error message shows at this line!
document.getElementById("streaming").play();
console.log("Buffer Updating", this.buffer.updating);
}
}
}
handleOpen() {
console.log("Status: connected");
}
handleClose() {
console.log("Status: disconnected");
}
render() {
return (
<div>
<Websocket
url="ws://192.168.1.20:5000"
onMessage={this.handleData}
onOpen={this.handleOpen}
onClose={this.handleClose}
reconnect={true}
debug={true}
ref={(Websocket) => {
this.refWebSocket = Websocket;
}}
protocol="stream-protocol"
/>
<video width="640" height="480" id="streaming" controls autoPlay>
<source
ref={this.myRef}
src={this.state.streaming}
type="video/mp4"
/>
Your browser does not support the video tag.
</video>
</div>
);
}
}
当服务器发送下一个流式字节数组数据时,错误来自我的 WebSocket 的 handleData
事件。
正如我在 link 中提到的示例和指南,我已经 post 阅读了他们的代码并逐步完成了它。根据他们的说法,Append Buffer 应该可以正常工作,但是即使在他们的代码中,appendbuffer()
也仅列在 proto 部分中,请参见此处:https://drive.google.com/open?id=1vOU4oM-XoKe71DofQuLU2THxMdgiown_ and yet the code doesn't complain about their appendbuffer(). When I console log my buffer it looks like theirs https://drive.google.com/open?id=1T4Ix-y124NgQJ9xu97xv4U2yFTn2k7vF。我错过了什么?
我觉得答案很明显,但我不知道我做错了什么。
我自己正在构建一个类似的项目,使用多个支持 RTSP 的高端 IP 摄像头,今天 运行 遇到了同样的错误。首先,请记住,根据 Mozilla 开发者网络 (MDN) 文档(link,此 API 是实验性的。
话虽这么说,但我似乎找到了问题的根本原因,尽管我无论如何都不是 JavaScript 专家。事实证明,你不能直接将 data.data
中的 handleData()
中的 "Blob" 对象传递给 appendBuffer()
方法。相反,您需要先将 Blob 转换为 appendBuffer()
方法支持的数据类型,然后再将其传入。
- 将您的事件处理程序变成
async
函数 - 使用
Blob.arrayBuffer()
将数据 blob 转换为 JavaScriptArrayBuffer
改变这个:
handleData(data) {
const videoStream = JSON.parse(data);
if (videoStream.msg === "videoStream") {
this.blobArr.push(videoStream.chunk.data);
if (
this.mediaStreaming.readyState === "open" &&
this.buffer &&
this.buffer.updating === false &&
this.blobArr.length > 0
) {
console.log(
"ReadyState [AppendBuffer]: " + this.mediaStreaming.readyState
);
this.buffer.appendBuffer(this.blobArr.shift()); // Error message shows at this line!
document.getElementById("streaming").play();
console.log("Buffer Updating", this.buffer.updating);
}
}
}
进入这个:
async handleData(event) {
var buffer = await event.data.arrayBuffer(); // convert the message Blob into an ArrayBuffer
appendBuffer(buffer);
document.getElementById("streaming").play();
console.log("Buffer Updating", this.buffer.updating);
}
问题是,一旦执行此操作,您将开始收到新错误,因为有太多数据被传递到 MediaSource
上的 SourceBuffer
对象。由于它跟不上输入流,您会看到类似于以下错误的内容:
Failed to execute 'appendBuffer' on 'SourceBuffer': This SourceBuffer is still processing an 'appendBuffer' or 'remove' operation
看来我们需要 "buffer the buffers," 听起来很奇怪。
我还没有解决这个新错误。如果您找到解决方案,我很乐意提供帮助。