Добавление свойства к ArrayBuffer, отправленному через DataChannel

В настоящее время я получаю фрагменты из потока видео, которое я отправляю по DataChannel партнеру, который затем реконструирует видео на другом конце.

У меня эта часть работает нормально, но я хотел бы добавить, какой кусок # был получен, чтобы не имело значения, если они поступят в другом порядке, чем предполагалось.

Первоначально я думал, что добавление параметра chunkId будет работать, но когда я делаю .data.chunkId на стороне получателя, он не определен.

Затем я попытался преобразовать ArrayBuffer в строку вместе с chunkId, используя JSON.stringify({ "chunkId": chunkId, "data": chunk }), но это вызывает проблемы, когда я анализирую его на другом конце (Unexpected end of JSON input и Unexpected token , in JSON at position #).

DataChannels также принимает большие двоичные объекты, поэтому я решил попробовать это, но отправитель использует node.js, который, по-видимому, не может этого сделать. Я так и не понял, как это обойти.

Последнее, что я пробовал, это просто добавить chunkId в начало/конец самого ArrayBuffer, но когда я пытаюсь создать новый массив, я получаю сообщение об ошибке source is too large при попытке добавить сам фрагмент.

Каков правильный способ достижения этого?


person Jabos    schedule 19.06.2017    source источник


Ответы (1)


Вы должны иметь возможность смешивать отправку текста и ArrayBuffers и проверять их при получении:

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>

Так почему бы не отправлять идентификатор чанка перед каждым ArrayBuffer?

person jib    schedule 19.06.2017
comment
Я полагал, что отправка его двумя частями будет более подвержена ошибкам, но я могу найти некоторые обходные пути, чтобы обойти/смягчить их. Жаль, что это нельзя сделать одновременно - person Jabos; 21.06.2017