В документах я вижу следующий пример отправки строки по каналу данных WebRTC:
var message = messageInputBox.value;
sendChannel.send(message);
Я пытаюсь отправить изображения и видео, поэтому я создаю ArrayBuffer
:
var reader = new FileReader();
reader.addEventListener("loadend", function () {
// reader.result contains the contents of blob as a typed array
data.media = reader.result; // ArrayBuffer
outboundMediaQueue.push(data);
});
reader.readAsArrayBuffer(data.media);
Я могу передать этот ArrayBuffer, но я также пытаюсь отправить вместе с ним некоторые метаданные (идентификатор носителя). Учитывая, что я не могу JSON.serialize
создать ArrayBuffer, как я могу передать эти данные с соответствующими метаданными?
Обновление:
Это работает:
sendChannel.send(data.media); // sending `ArrayBuffer` only
Но это не работает:
sendChannel.send(data); // arbitrary object with desired metadata
И это тоже не работает:
sendChannel.send(JSON.stringify(data));
Обновление 2
Я составил следующий модуль, который, кажется, обрабатывает кодирование и декодирование. Он не полностью протестирован и не тестировался на больших файлах; Я буду держать это в курсе, когда выясню, что работает:
define([], function () {
// https://developer.mozilla.org/en-US/docs/Web/API/WindowBase64/Base64_encoding_and_decoding#Solution_2_–_rewrite_the_DOMs_atob()_and_btoa()_using_JavaScript's_TypedArrays_and_UTF-8
// https://developers.google.com/web/updates/2012/06/How-to-convert-ArrayBuffer-to-and-from-String
const arrayBufferConverter = {};
arrayBufferConverter.bufferToString = function (outboundBuffer) {
const dataView = new DataView(outboundBuffer);
const decoder = new TextDecoder('utf-8'); // base64?
const decodedString = decoder.decode(dataView);
return decodedString;
}
arrayBufferConverter.stringToBuffer = function (inboundString) {
var encoded = new TextEncoderLite('utf-8').encode(inboundString);
var b64Encoded = base64js.fromByteArray(encoded);
return b64Encoded;
}
return arrayBufferConverter;
});
Обновление 3
Поскольку моя единственная реальная потребность здесь — соединить метаданные с ArrayBuffer
, я собираюсь забыть о бессмыслице кодирования/декодирования и просто сгенерировать дайджест на обоих концах транзакции:
arrayBufferConverter.getDigestFromBuffer = function (buffer) {
const view = new DataView(buffer);
const numBytes = view.byteLength;
const interval = Math.floor(numBytes / 32);
var currentIndex = 0;
var digest = "";
while (currentIndex < numBytes) {
digest += view.getInt8(currentIndex);
currentIndex += interval;
}
return digest;
}
Таким образом, я буду отправлять ArrayBuffers
и соответствующие метаданные в двух отдельных запросах и управлять сопряжением с помощью некоторой базовой логики очереди. Это полностью устраняет текущие затраты на обработку и риски, связанные с кодированием/декодированием больших медиафайлов, в пользу небольшой фиксированной стоимости логики сопряжения. Я оставлю это открытым, если у кого-то есть другие рекомендации.
data
, не так ли? Или я ошибаюсь? - person Patrick Roberts   schedule 30.06.2017