Доклад о WebRTC на фестивале 404
View Slide
WebRTC: Скоростнаядоставка данных
WebRTC больше 10 лет, что изменилось изачем об этом говорить?Изоляция бустит технологиюRTC и WebRTC активноразвиваются• WebRTC теперь IETF стандарт 🎉• Появляются новые APIХочется чтобы все понимали какэто работает
Пересылаемвидео, аудио, файлики,скриншаруChallengeВ условияхЛагающего интернетаЗлых админов,настроившихfirewallМеждуБольшим количествомучастниковС разнымиприоритетами🧟🧟🧟
Транспорт: медленно инадежно или быстро иопасно?• Следит за состоянием• Гарантирует правильныйпорядок доставки• Ничего не теряет• Ограничивает количествопакетов• Огромный header (до 60 байт)Просто посылает пакеты по адресу :)
WebRTCpeer-to-peer over UDP
Простой случай: 2 участникаnew RTCPeerConnection(…)new RTCPeerConnection(…)🦄
Простой случай: 2 участникаnew RTCPeerConnection(…)new RTCPeerConnection(…)
new RTCPeerConnection(…)new RTCPeerConnection(…)
ICE Agent:1. Собирает кандидатов.2. Для каждой парыкандидатов поверяетвозможность соединения.trickle ICE: Постепеннособирает кандидатов.Сигналим о том кого нашли.
Media: SRTP + SRTCPData: SCTPШифрованиеРаботает поверх UDP→быстрееМожно терять пакеты, еслинужноНе гарантирует порядокBundlingDTLS: TLS для UDP
Итого:Нам нужно придумать signalingНам нужен STUN и TURNDTLS, SCTP, SRTP, ICE gatheringсделает за нас browser
Optimal encoding: latency vs quality
20
Compression: intra & inter
Intraframe compression (AV1)
Какие кодеки поддерживает ваш браузер?
Simulcast – несколькопотоков разногокачества
26SVC: как Simulcast, только лучше
27SVC
28Экзотические кодеки и всякий MLLyraSatin
Несколько участников
Fully connected
MCU – Multipoint Control Unit
SFU – Selective Forwarding Unit
То же самое + 1000 зрителей
На клиенте
Меняется layout
Добавляем скрытого участника
То же самое + 1000 зрителей …и франкенштейн!
Создаем
Готовые решения
А что там под капотом?libwebrtclibyuvlibopuslibvpx…libwebrtclibyuvlibopuslibvpx…libyuvlibopuslibvpx…webrtc-rs
Отладка
Отладка костылем
chrome://webrtc-internals
about:webrtc (Firefox)
Чего-то не хватает….
WebCodecsconst decoder = new VideoDecoder({output: (frame) => {/* do something */},error: console.log});await videoDecoder.configure({codec: 'vp8'});decoder.decode(chunk);
WebTransportconst transport = new WebTransport('https://example.com');await transport.ready;const stream = await transport.createSendStream();const writer = sender.getWriter();writer.write(new Uint8Array([68, 69, 70]));
Insertable-streamsconst stream = await getUserMedia({ video: true });const track = stream.getVideoTracks()[0];const processor = new MediaStreamTrackProcessor({ track });const generator = new MediaStreamTrackGenerator({ kind: 'video' });const transformer = new TransformStream({async transform(frame, controller) {const newFrame = processFrameSomehow(frame);videoFrame.close();controller.enqueue(newFrame);},});trackProcessor.readable.pipeThrough(transformer).pipeTo(trackGenerator.writable);trackGenerator.readableControl.pipeTo(trackProcessor.writableControl);
Если вам не нравитсябраузерная реализация, вывсегда можете использоватьсвою ;)
Примеры:
Фронтенду на заметкуНе забывайте обрабатывать случайотсутствия разрешений дляgetUserMedia / getDisplayMediaКамер и микрофонов может бытьнесколько. Выбор камер требуетразрешенияПридется писать очень многоасинхронной логики.Нужно использовать https дажелокальноawait navigator.mediaDevices.enumerateDevices()https://github.com/jfromaniello/selfsigned/pull/43
@polina_gurtovaya@pgurtovaya@evilmartians@evilmartians_ruevilmartians.comСпасибо![email protected]https://bit.ly/3eKfTZa