问题
I am currently receiving chunks from a stream of a video that I send over the DataChannel to a peer who will then reconstruct the video on the other end.
I have this part working just fine but I would like to add which chunk # it was that was received so that it doesn't matter if they happen to arrive in a different order than intended.
Initially I thought that adding a parameter chunkId
would work but when I do .data.chunkId
on the receiver side, it is undefined.
Then I tried to stringify the ArrayBuffer along with the chunkId
using JSON.stringify({ "chunkId": chunkId, "data": chunk })
but it causes problems when I parse it on the other end (Unexpected end of JSON input
and Unexpected token , in JSON at position #
)
DataChannels also accept blobs so I thought I would try that but the sender is using node.js which apparently can't do that. I wasn't quite able to figure out how to get around that.
The last thing I tried was to simply append the chunkId
to the beginning/end of the ArrayBuffer itself but when I try to create a new array I get the error source is too large
when trying to add the chunk itself.
What is the correct way of achieving this?
回答1:
You should be able to intermingle sending text and ArrayBuffers, and check for them on reception:
var pc1 = new RTCPeerConnection(), pc2 = new RTCPeerConnection();
pc1.onicecandidate = e => pc2.addIceCandidate(e.candidate);
pc2.onicecandidate = e => pc1.addIceCandidate(e.candidate);
pc1.oniceconnectionstatechange = e => log(pc1.iceConnectionState);
pc1.onnegotiationneeded = e =>
pc1.createOffer().then(d => pc1.setLocalDescription(d))
.then(() => pc2.setRemoteDescription(pc1.localDescription))
.then(() => pc2.createAnswer()).then(d => pc2.setLocalDescription(d))
.then(() => pc1.setRemoteDescription(pc2.localDescription))
.catch(e => log(e));
var dc1 = pc1.createDataChannel("chat", {negotiated: true, id: 0});
var dc2 = pc2.createDataChannel("chat", {negotiated: true, id: 0});
dc2.binaryType = "arraybuffer";
dc2.onmessage = e => {
if (e.data instanceof ArrayBuffer) {
log("Got ArrayBuffer!");
} else if (e.data instanceof Blob) {
log("Got Blob!");
} else {
log("> " + e.data);
}
}
button.onclick = e => dc1.send(new ArrayBuffer(8));
chat.onkeypress = e => {
if (e.keyCode != 13) return;
dc1.send(chat.value);
chat.value = "";
};
var log = msg => div.innerHTML += "<br>" + msg;
Chat: <input id="chat"><button id="button">Send ArrayBuffer</button><br>
<div id="div"></div>
<script src="https://webrtc.github.io/adapter/adapter-latest.js"></script>
So why not send the chunk id ahead of each ArrayBuffer?
来源:https://stackoverflow.com/questions/44629478/appending-property-to-arraybuffer-sent-over-datachannel