編集:発生し続けるエラーを説明するために、発生している問題のCodePenを作成しました。コンソールを開くと、エラーが表示されます。 [ https://codepen.io/FifthCloud/pen/eYpqJLN ]
React/Nodeを使用して自宅で独自のストリーミングカメラサービスを設計したかったのです。これまでのところ、私はクライアント/サーバーアプローチで長い道のりを歩んできました。サーバーは、カメラが取り付けられたRaspberry Piです。 FFMpegを使用すると、そこからすべてのビデオを表示でき、websocketを使用すると、データを正常に送信できます(つまり、クライアントに送信されているデータが表示されない理由がわかります)。
私が直面している問題は、データをバッファに追加できない理由です。手始めに、私はメディアソースに関するこのデモをガイドと例として使用し、私がやるべきことについて説明します。 http://nickdesaulniers.github.io/netfix/demo/bufferAll.html Media Sourceに関する私の研究からこのリンクを取得しました: https://developer.mozilla.org/ en-US/docs/Web/API/MediaSource/readyState また、この投稿から多くのインスピレーションを得て、この回答のために本当に遠ざかったことにも言及したいと思います HTML5 Video:Streaming Video with Blob URL
それを念頭に置いて、MediaSource
を正常に作成してバッファを開くことができますが、理解できないのは、なぜバッファに追加できないのですか?私が受け取っているエラーはこれです:
TypeError: 'SourceBuffer'で 'appendBuffer'を実行できませんでした:提供された署名に一致する関数が見つかりませんでした。
クライアント側のコードは次のとおりです
_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
イベントから発生します。
例と私が投稿したリンクからのガイドについて述べたように、私は彼らのコードを見て、それをステップスルーしました。彼らによると、バッファの追加は正常に機能するはずですが、コード内でもappendbuffer()
はprotoセクションにのみリストされています。ここを参照してください: https:/ /drive.google.com/open?id=1vOU4oM-XoKe71DofQuLU2THxMdgiown_ であるにもかかわらず、コードはappendbuffer()について文句を言っていません。コンソールでログを記録すると、バッファは https://drive.google.com/open?id=1T4Ix-y124NgQJ9xu97xv4U2yFTn2k7vF のようになります。何が欠けていますか?
私は答えが非常に明白であるように感じますが、それは私が間違っていることに関して私を逃れています。
いくつかのハイエンドのRTSP対応IPカメラを使用して、同様のプロジェクトを自分で構築していますが、今日同じエラーが発生しました。まず、Mozilla Developer Network(MDN)のドキュメント(以下のリンク)によると、このAPIは実験的なものであることを覚えておいてください。
そうは言っても、私はJavaScriptの専門家ではありませんが、問題の根本的な原因を発見したようです。 「Blob」オブジェクトをhandleData()
の_data.data
_から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);
}
_
問題は、これを実行すると、SourceBuffer
のMediaSource
オブジェクトに渡されるデータが多すぎるため、新しいエラーが発生し始めることです。入力ストリームに対応できないため、次のようなエラーが表示されます。
「SourceBuffer」で「appendBuffer」を実行できませんでした:このSourceBufferはまだ「appendBuffer」または「remove」操作を処理しています
「バッファをバッファリングする」必要があるようですが、それは奇妙に聞こえます。
この新しいエラーはまだ解決していません。あなたが解決策を見つけたら、私はいくつかの助けが欲しいです。