Поток WebRTC RTP на публичный IP без ICE / STUN

У меня есть общедоступный IP-адрес, на который я хочу, чтобы мои клиенты отправляли свой поток WebRTC RTP.

Клиент будет знать кодеки и на какие порты отправлять поток.

Я пытаюсь сделать реализацию как можно более простой, но, похоже, не хватает многих деталей.

Все поиски Google указывают на использование для этого какого-то сервера, такого как шлюз Janus, который приемлем, если требуется, но я не понимаю, зачем мне это нужно, поскольку единственное требование для меня - заставить браузер отправлять RTP. поток на предопределенный IP и порт.

Я создал рабочую настройку с использованием шлюза Janus, затем скопировал используемые SDP, чтобы я мог использовать их с настройкой без Janus.

    navigator.mediaDevices.getUserMedia({audio: true, video: true}).then(function (stream) {
        let videoElement = document.getElementById("my-video");
        videoElement.srcObject = stream;


        var peerConnection = new RTCPeerConnection({iceServers: []});

        peerConnection.onnegotiationneeded = function() {
            console.log("onnegotiationneeded");


            peerConnection.createOffer({offerToReceiveAudio: false, offerToReceiveVideo: false}).then(function (offer) {
                peerConnection.setLocalDescription(offer);

                console.log("setRemoteDescription");


                peerConnection.setRemoteDescription({
                    type: 'answer',
                    sdp: `v=0
o=mozilla...THIS_IS_SDPARTA-74.0.1 1586270943313087 1 IN IP4 192.168.1.5
s=VideoRoom 1234
t=0 0
a=group:BUNDLE 0 1
a=msid-semantic: WMS janus
m=audio 9 UDP/TLS/RTP/SAVPF 109
c=IN IP4 192.168.1.5
a=recvonly
a=mid:0
a=rtcp-mux
a=ice-ufrag:uuIW
a=ice-pwd:bW5IdRMw2iMhH5wLiC+2u3
a=ice-options:trickle
a=fingerprint:sha-256 6E:5C:B0:6A:56:78:54:93:AB:6D:21:7E:B7:B3:F9:80:5C:0D:00:F0:D8:52:8E:BA:F1:87:C4:A7:37:38:CB:46
a=setup:active
a=rtpmap:109 opus/48000/2
a=extmap:1 urn:ietf:params:rtp-hdrext:ssrc-audio-level
a=extmap:3 urn:ietf:params:rtp-hdrext:sdes:mid
a=msid:janus janusa0
a=ssrc:849691919 cname:janus
a=ssrc:849691919 msid:janus janusa0
a=ssrc:849691919 mslabel:janus
a=ssrc:849691919 label:janusa0
a=candidate:1 1 udp 2013266431 192.168.1.5 60526 typ host
a=end-of-candidates
m=video 9 UDP/TLS/RTP/SAVPF 126
c=IN IP4 192.168.1.5
a=recvonly
a=mid:1
a=rtcp-mux
a=ice-ufrag:uuIW
a=ice-pwd:bW5IdRMw2iMhH5wLiC+2u3
a=ice-options:trickle
a=fingerprint:sha-256 6E:5C:B0:6A:56:78:54:93:AB:6D:21:7E:B7:B3:F9:80:5C:0D:00:F0:D8:52:8E:BA:F1:87:C4:A7:37:38:CB:46
a=setup:active
a=rtpmap:126 H264/90000
a=fmtp:126 profile-level-id=42e01f;packetization-mode=1
a=rtcp-fb:126 ccm fir
a=rtcp-fb:126 nack
a=rtcp-fb:126 nack pli
a=rtcp-fb:126 goog-remb
a=rtcp-fb:126 transport-cc
a=extmap:3 urn:ietf:params:rtp-hdrext:sdes:mid
a=extmap:6/inactive http://www.webrtc.org/experiments/rtp-hdrext/playout-delay
a=msid:janus janusv0
a=ssrc:3452602418 cname:janus
a=ssrc:3452602418 msid:janus janusv0
a=ssrc:3452602418 mslabel:janus
a=ssrc:3452602418 label:janusv0
a=candidate:1 1 udp 2013266431 192.168.1.5 60526 typ host
a=end-of-candidates`
                })
            });
        };

        let tracks = stream.getTracks();
        for(var i = 0; i < tracks.length; i++) {
            peerConnection.addTrack(tracks[i]);
        }

    });

Здесь я инициализирую канал веб-камеры, создаю RTCPeerConnection без серверов ICE как задокументировано здесь и добавьте все треки.

Я настраиваю прослушиватель для обратного вызова onnegotiationneeded, где, когда требуется согласование, я создаю предложение с помощью offerToReceiveAudio и offerToReceiveVideo, для которых установлено значение false в RTCPeerConnection, и после его создания я устанавливаю созданное предложение как локальное описание RTCPeerConnections.

После этого я установил предопределенный SDP как remoteDescription.

SDP был скопирован из сеанса Janus, он содержит атрибут ICE, такой как ice-ufrag, ice-pwd и ice-options, и если я их удалю, я получаю сообщение об ошибке в недопустимом описании.

SDP также содержит кандидатов STUN (?), И их удаление не имеет значения.

После этого браузер подключается к кандидату STUN, но, поскольку в этом нет необходимости, поскольку сервер работает на общедоступном IP-адресе, запрос не выполняется.

Какие шаги необходимо предпринять, чтобы выполнить минимальную настройку, при которой браузер отправляет RTP на предопределенный хост / порт на предопределенном кодеке?


person Pasi Matalamäki    schedule 07.04.2020    source источник
comment
Вам нужно будет создать своих собственных ледяных кандидатов в зависимости от того, где подключаться, и игнорировать ледяных кандидатов, сгенерированных одноранговым соединением. Подробнее о ледовой проверке, шаг 2 - temasys.io/webrtc-ice-sorcery   -  person Karthik    schedule 07.04.2020
comment
Я бегло просмотрел эту статью, но она слишком расплывчата, чтобы понять ее. Я проверил ресурсы Mozillas относительно SDP и узнал об использовании «кандидата на хост», что уже было сделано, только IP был неправильным. Теперь я обновил его до localhost, но ледяное соединение по-прежнему не работает с ошибкой `` ICE failed, добавьте STUN-сервер и посмотрите about: webrtc для более подробной информации '' Я обновил вопрос, чтобы отразить этот обновленный SDP   -  person Pasi Matalamäki    schedule 07.04.2020


Ответы (1)


Я могу неправильно понять вопрос, но я не верю, что это возможно, Паси.

Браузер будет отправлять видео только тогда, когда

  • ДВС переходит в подключенный. Вам нужно ответить на эти сообщения
  • Рукопожатие DTLS, которое затем экспортирует ключевой материал и инициализирует SRTP
  • Затем все отправляется по SRTP.

Однако вы можете легко построить это из существующих строительных блоков! Если вы не хотите запускать полную реализацию WebRTC, вы можете объединить существующие библиотеки, например pion / ice pion / dtls и pion / srtp

В конечном итоге вам, вероятно, будет лучше, если вы запустите что-то вроде Януса. Есть много скрытых деталей, которые вы в конечном итоге решите, которые WebRTC решает за вас :)

person Sean DuBois    schedule 08.04.2020
comment
Я думаю, что большая часть этого происходит из-за неправильного понимания всего. После опробования решений для шлюзов janus / kurento они кажутся мне тяжеловесными. Я пытаюсь опубликовать веб-клиент на сервере RTMP, поэтому я использую ffmpeg для кодирования потока RTP на сервер RTMP. Эти детали действительно помогли мне понять, что потребуется для отказа от шлюза. Является ли ICE и использование безопасного соединения необходимостью? Некоторые источники, такие как связанный пост SO, говорят, что ICE не является обязательным требованием. Хм .. Мне действительно нужно копнуть глубже. Спасибо. - person Pasi Matalamäki; 08.04.2020
comment
Я провел несколько поисков, и это правда, что SRTP - единственный транспорт, доступный на webrtc, что разумно, поскольку безопасность является ключевым моментом при общении. ffmpeg, похоже, может понять поток SRTP, если бы я мог выполнить рукопожатие DTLS из первых рук - person Pasi Matalamäki; 08.04.2020
comment
Вы можете сделать что-то вроде github.com/pion/example-webrtc-applications / tree / master / twitch Я также рад ответить на дополнительные вопросы в pion.ly/slack ! Я буду немного медленнее возвращаться к ним, я отвечаю на SO как на последнюю вещь дня :) - person Sean DuBois; 09.04.2020
comment
Спасибо за эти замечательные ресурсы, они действительно помогли мне восполнить пробелы между моими знаниями Webrtc! Требования к проекту немного изменились после того, как появилось больше проблем из-за шлюза RTMP. - person Pasi Matalamäki; 12.04.2020
comment
@SeanDuBois Не могли бы вы поделиться каким-либо быстрым примером или начальным местом в pion webrtc, которое нужно искать при использовании, сшивая pion / ice pion / dtls и pion / srtp или даже pion / srtp, если ключи предварительно установлены - person Chakri; 17.12.2020