I have a public IP to which I want my clients to send their WebRTC RTP stream to.
The client will know the codecs and to which ports to send the stream to.
I am trying to do as barebones of an implementation as possible, but so much details seem to be missing.
All Google searches points be to using some kind of server for this, such as Janus gateway, which is acceptable if required, but I don't see why would I need this, as the only requirement for me is to make the browser send RTP stream to predefined IP and port.
I have created an working setup using Janus gateway, then copied the SDPs used so I could use them withing a setup without 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]);
}
});
Here I initialize the webcam feed, create an RTCPeerConnection without ICE servers as documented here and add all tracks.
I setup a listener to onnegotiationneeded callback where when negotiation is needed I create an offer with offerToReceiveAudio and offerToReceiveVideo set to false on the RTCPeerConnection, and after it has been created I set the created offer as RTCPeerConnections local description.
After this I set predefined SDP as remoteDescription.
The SDP has been copied from Janus session, it contains ICE attribute such as ice-ufrag, ice-pwd and ice-options, and if I delete them, I get error regarding Invalid description.
The SDP also contains STUN(?) candidates and removing them makes no difference.
After running this the browser connects to the STUN candidate, but as this is not necessary as the server is run on public IP, the request fails..
Which steps should be taken to make a minimal setup where the browser sends RTP to predefined host/port on predefined codec?
I might be misunderstanding the question, but I don't believe this is possible Pasi.
The browser will only send video when
You could easily build this with existing building blocks though! If you don't want to run a full WebRTC implementation, you could stitch existing libraries together like pion/ice pion/dtls and pion/srtp
In the long run you will probably be better served by running something like Janus. There are lots of hidden details you will end up hitting that WebRTC solves for you :)