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() 方法支持的数据类型,然后再将其传入。

  1. 将您的事件处理程序变成 async 函数
  2. 使用 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," 听起来很奇怪。

我还没有解决这个新错误。如果您找到解决方案,我很乐意提供帮助。

相关阅读