Я пытаюсь отправить данные изображения по Data Channel
, но он не работает. Когда вы просто получаете данные от ctx.getImageData
, я получаю строку "[Object ImageData]"
с другой стороны. Преобразование части данных только в blob приводит к ошибке: Uncaught NetworkError: Failed to execute 'send' on 'RTCDataChannel': Could not send data
. Я получаю ту же ошибку при попытке конвертировать ее в ArrayBuffer
. Как мне это сделать?Отправить данные изображения по каналу данных RTC
ответ
Вот демо я написал только сейчас: http://richard.to/projects/datachannel-demo/
Обратите внимание, что я использую местные каналы, и я просто отображение изображения и не оказывающее на холст. Это должно быть легко сделать. Вы можете столкнуться с проблемами при фактическом общении с удаленным устройством. Я еще не проверял его. Также он работает только в Chrome. Но должно быть просто сделать работу в Firefox.
Это было немного сложно понять, поскольку материал WebRTC постоянно меняется. Не говоря уже о том, что Firefox и Chrome работают несколько иначе.
Я собираюсь сосредоточиться на Chrome, поскольку сообщения об ошибках, которые вы получаете, относятся к Chrome, в частности Uncaught NetworkError: Failed to execute 'send' on 'RTCDataChannel': Could not send data
. Эта проблема была описана здесь: https://groups.google.com/forum/#!topic/discuss-webrtc/U927CZaCdKU
Это связано с ограничением скорости передачи данных RTP data channel
. Ссылка, которую я дал вам, упоминал 3 KB/sec
и в моем тестировании, который звучит правильно.
Хорошей новостью является то, что после Chrome 31 вы можете использовать каналы передачи данных на основе SCTP. См. Здесь: https://groups.google.com/forum/#!topic/discuss-webrtc/y2A97iCByTU.
Это означает, что вместо этого:
window.localPeerConnection = new webkitRTCPeerConnection(servers,
{optional: [{RtpDataChannels: true}]});
Вы можете сделать что-то вроде этого (вероятно, можно удалить второй параметр):
window.localPeerConnection = new webkitRTCPeerConnection(servers,
{optional: []});
Я считаю, вы по-прежнему будет скорость ограничена, но теперь это 64kbps
. Возможно, я ошибаюсь в этом номере. Не могу найти ссылку, с которой я ее прочитал.
Одна хорошая вещь в канале SCTP заключается в том, что вместо ненадежного (UDP) вы можете использовать надежное соединение для передачи данных (TCP), и данные отправляются по порядку. Я не уверен в этом. Еще раз, не могу найти ссылку.
Теперь, из-за этого, похоже, вам все равно придется вырезать данные. Вы не можете отправить все это одновременно в Chrome. Однако вы можете сделать это в Firefox.
Второе, что вам нужно знать, это то, что в настоящее время данные не поддерживаются данным устройством blob
. По крайней мере, в обычном Chrome 32. Это означает, что мы должны отправлять данные в виде текста, если мы хотим использовать Chrome.
Так что мы можем сделать, это преобразовать наши данные изображения в base64 с canvas.toDataURL()
.Вот пример того, как это будет работать:
var canvas = document.createElement('canvas');
canvas.width = startimage.width;
canvas.height = startimage.height;
var ctx = canvas.getContext('2d');
ctx.drawImage(startimage, 0, 0, startimage.width, startimage.height);
var data = canvas.toDataURL("image/jpeg");
Теперь, когда у нас есть данные, нам просто нужно разбить bas64 строку:
Вот реализация комков данных, которые я использую в моя демка выше:
function sendData() {
trace("Sending data");
sendButton.disabled = true;
var canvas = document.createElement('canvas');
canvas.width = startimage.width;
canvas.height = startimage.height;
var ctx = canvas.getContext('2d');
ctx.drawImage(startimage, 0, 0, startimage.width, startimage.height);
var delay = 10;
var charSlice = 10000;
var terminator = "\n";
var data = canvas.toDataURL("image/jpeg");
var dataSent = 0;
var intervalID = 0;
intervalID = setInterval(function(){
var slideEndIndex = dataSent + charSlice;
if (slideEndIndex > data.length) {
slideEndIndex = data.length;
}
sendChannel.send(data.slice(dataSent, slideEndIndex));
dataSent = slideEndIndex;
if (dataSent + 1 >= data.length) {
trace("All data chunks sent.");
sendChannel.send("\n");
clearInterval(intervalID);
}
}, delay);
}
реализация довольно проста, в основном только с помощью setInterval
. Вы можете возиться с параметрами размера и задержки фрагмента. Также нам нужно установить символ терминатора, чтобы узнать, когда сообщение завершено. Я просто использовал символ \n
.
И вот как будет реализован приемник. В основном отслеживает данные до тех пор, пока не получит символ терминатора, который я использовал только символ новой строки.
function handleMessage(event) {
if (event.data == "\n") {
endimage.src = imageData;
trace("Received all data. Setting image.");
} else {
imageData += event.data;
//trace("Data chunk received");
}
}
Надеюсь, это поможет. Было интересно исследовать его. Не совсем уверен, что это будет идеальное решение для отправки изображения через WebRTC. Есть некоторые демонстрации, которые делают передачу файлов P2P и прочее. Думаю, это зависит от вашей цели.
Это исключение вызвано превышением предела пропускной способности, согласованного в сеансе.
При создании ответа на предложение, вы должны изменить объект sessionDescription, который является частью PeerConnection, чтобы изменить параметр b=AS:
, который содержит максимальную пропускную способность в кбит/с:
var Bandwidth = 5000;
sessionDescription.sdp = sessionDescription.sdp.replace(/b=AS:([0-9]+)/g, 'b=AS:'+Bandwidth+'\r\n');
alert(JSON.stringify(sessionDescription));
По умолчанию в значение 30 кбит/с.
Похоже, у меня нет этой части текста в моем sdp. Может быть, когда его нет, он просто принимает значение по умолчанию 30, и нам просто нужно добавить его вручную в sdp? И я предпочел бы иметь регулярное выражение примерно так: '/ b = AS: ([0-9] +)/g', так как я [не мог заставить вас работать] (http://regexr.com/ 398og). Но если бы это сработало, это было бы здорово, хотя было бы еще лучше, если бы сам браузер обрабатывал bandwith (точно так же, как веб-порты (я не уверен, но похоже, что они есть), поскольку я могу просто выбросить (массивные) количества строк через него без сбоев). – MarijnS95
Не работает для меня, протестирован на Chrome M40. – Imskull
Предлагаемое регулярное выражение для замены 30 на 1000 (если это сработало ...): var new_offer = offer.replace (/ (\ Sb = AS:) ([0-9] +) (\ S) /, "$ 11000 $ 3 «); –
Это на самом деле комментарий bornSwift, но у меня недостаточно репутации для комментариев. Итак: когда вы используете канал данных RTP, вы увидите пропускную способность приложения (AS) в пределах sdp (т. Е. B = AS: 30). 30 - значение по умолчанию. Вы можете заменить это на произвольное значение (1638400 работает, но если вы хотите нажать его дальше, вам придется проб и ошибок).
Однако при инициализации канала данных SCTP вы не увидите полосы пропускания AS в вашем sdp. Это просто отлично. Вам не о чем беспокоиться.
- 1. Как отправить текстовые данные по каналу agi
- 2. Карта изображения по альфа-каналу
- 3. WebRTC: не удалось отправить ArrayBuffer по каналу данных в хроме
- 4. Как безопасно отправлять данные по общедоступному каналу?
- 5. Отправка структурированных данных по именованному каналу (Linux)
- 6. Как отправить несколько наборов данных по каналу связи multipeer
- 7. Golang: не удается отправить по каналу
- 8. Надежная передача данных по отказоустойчивому каналу
- 9. Надежная передача данных по каналу с потерями
- 10. Репликация базы данных транзакций по ненадежному каналу
- 11. Отправить Загрузить данные изображения в базу данных
- 12. Отправка блоков данных по именованному каналу в linux
- 13. kwargs, отправленный по каналу pyAMF
- 14. Неустойчивое поведение RTC datachannel
- 15. В неуправляемом Python вы можете отправить канал по каналу?
- 16. Учебник по виртуальному каналу IOS
- 17. Отправить данные по конфигурации
- 18. В неуправляемом python данные передаются по каналу неизменяемым?
- 19. Чтение и запись данных по именованному каналу с демонизацией
- 20. Отправить данные по ajax
- 21. Как отправить сообщение определенному каналу в irssi?
- 22. Приложите текстовый файл и отправить BlueTooth каналу
- 23. Загрузка содержимого по незащищенному каналу
- 24. SIGCONT не обнаружен по каналу
- 25. Можно ли фильтровать по каналу
- 26. Создание размещенного репозитория по каналу
- 27. Go Неблокирующий множественный прием по каналу
- 28. C++ Возможно ли шифровать данные, отправленные по именованному каналу?
- 29. отправлять push-уведомления по определенному каналу
- 30. Медленная репликация по каналу WAN - только загрузки
Привет, спасибо за ваш ответ. В настоящее время я делаю что-то совершенно другое (и именно поэтому я забыл об этом вопросе). В настоящее время я работаю с веб-сайтами и отправляет координаты рисованной линии, например, вместо изображения. Я могу по-прежнему взглянуть на это, чтобы уменьшить нагрузку на сервер, теперь я знаю, что данные должны быть разделены. – MarijnS95
FYI, я могу отправить строку в Chrome M40, но всегда не удалось при попытке отправить arraybuffer, я получил: «Не удалось выполнить« отправить »на« RTCDataChannel »: не удалось отправить данные« – Imskull