Reputation: 1652
I am currently working on testing Jitsi as an SFU. I am trying to create a simple test using the COLIBRI REST API. The current test is a JavaScript client, opened in two tabs, with each tab connecting to Jitsi Videobridge (JVB) through the REST API and displaying the video sent via the other client, through JVB.
First, the good news. I have successfully configured our clients to connect to JVB through the REST API and display the other peer's video feed. However, chrome://webrtc-internals only shows two ssrc_send entries and no ssrc_recv entries. I am very curious why we are seeing video and not seeing any ssrc_recv entries in webrtc-internals.
We have discovered that by adding the following ssrc lines to our SDP offer, we can get webrtc-internals to display src_recv entries. However, the stats show no media flowing through these ssrc_recvs and we lose the video streams we were seeing without the ssrc lines.
a=ssrc:${info.contents[0].channels[0].sources[0]} cname:mixed
a=ssrc:${info.contents[0].channels[0].sources[0]} label:mixedlabelaudio0${sessionId}
a=ssrc:${info.contents[0].channels[0].sources[0]} msid:mixedmslabel${sessionId} mixedlabelaudio0${sessionId}
a=ssrc:${info.contents[0].channels[0].sources[0]} mslabel:mixedmslabel${sessionId}
a=ssrc:${info.contents[1].channels[0].sources[0]} cname:mixed
a=ssrc:${info.contents[1].channels[0].sources[0]} label:mixedlabelvideo0${sessionId}
a=ssrc:${info.contents[1].channels[0].sources[0]} msid:mixedmslabel mixedlabelvideo0${sessionId}
a=ssrc:${info.contents[1].channels[0].sources[0]} mslabel:mixedmslabel${sessionId}
Our main question is why we are not seeing any ssrc_recv entries - even though we can see video streams flowing - and how we can modify/fix our code to display those ssrc_recv entries in webrtc-internals. We are worried that not seeing these entries is a sign of something larger that we are missing with our implementation. However, is it possible we are simply running into a Chrome bug?
Any help on this issue is greatly appreciated.
I have included the relevant code snippets below:
Initial conference creation call
POST {} to /colibri/conferences
Channel allocation call
PATCH below to /colibri/conferences/9ad7d1fe11a85c1a
{
"id": "9ad7d1fe11a85c1a",
"contents": [
{
"name": "audio",
"channels": [
{
"expire": 60,
"initiator": true,
"endpoint": 1490294249498,
"direction": "sendrecv",
"channel-bundle-id": 1490294249498,
"rtp-level-relay-type": "mixer"
}
]
},
{
"name": "video",
"channels": [
{
"expire": 60,
"initiator": true,
"endpoint": 1490294249498,
"direction": "sendrecv",
"channel-bundle-id": 1490294249498,
"last-n": 2
}
]
}
],
"channel-bundles": [
{
"id": 1490294249498,
"transport": {
"xmlns": "urn:xmpp:jingle:transports:ice-udp:1",
"rtcp-mux": true,
"fingerprint": {
"xmlns": "urn:xmpp:jingle:apps:dtls:0",
"required": false
}
}
}
]
}
SDP Offer
v=0
o=- 1490294249719 2 IN IP4 0.0.0.0
s=-
t=0 0
a=group:BUNDLE audio video
m=audio 1 RTP/SAVPF 111 103 104 126
c=IN IP4 0.0.0.0
a=rtpmap:111 opus/48000/2
a=rtpmap:103 ISAC/16000
a=rtpmap:104 ISAC/32000
a=rtpmap:126 telephone-event/8000
a=fmtp:111 minptime=10; useinbandfec=1
a=rtcp:1 IN IP4 0.0.0.0
a=extmap:1 urn:ietf:params:rtp-hdrext:ssrc-audio-level
a=extmap:3 http://www.webrtc.org/experiments/rtp-hdrext/abs-send-time
a=setup:actpass
a=mid:audio
a=sendrecv
a=ice-ufrag:ere4l1bbu7bbf8
a=ice-pwd:79r5i3snbhbrca0735vs3v30q4
a=fingerprint:sha-1 C2:FF:06:CD:0D:6C:EF:6E:CC:54:CE:2D:F1:68:34:DB:06:B8:79:6A
a=candidate:9ad7d1fe11a85c1a70d346f625a464501524626b 1 tcp 2130706431 172.31.54.51 4443 typ host generation 0
a=candidate:9ad7d1fe11a85c1a70d346f625a4645015247820 1 udp 2130706431 172.31.54.51 10000 typ host generation 0
a=candidate:9ad7d1fe11a85c1a70d346f625a46450ffffffff9d5ff4a9 1 tcp 1694498815 52.90.200.113 4443 typ srflx raddr 172.31.54.51 rport 4443 generation 0
a=candidate:9ad7d1fe11a85c1a70d346f625a46450ffffffff9d600a5e 1 udp 1677724415 52.90.200.113 10000 typ srflx raddr 172.31.54.51 rport 10000 generation 0
a=rtcp-mux
m=video 1 RTP/SAVPF 100
c=IN IP4 0.0.0.0
a=rtpmap:100 VP8/90000
a=fmtp:100 x-google-start-bitrate=800
a=rtcp:1 IN IP4 0.0.0.0
a=rtcp-fb:100 ccm fir
a=rtcp-fb:100 nack
a=rtcp-fb:100 nack pli
a=rtcp-fb:100 goog-remb
a=extmap:3 http://www.webrtc.org/experiments/rtp-hdrext/abs-send-time
a=setup:actpass
a=mid:video
a=sendrecv
a=ice-ufrag:ere4l1bbu7bbf8
a=ice-pwd:79r5i3snbhbrca0735vs3v30q4
a=fingerprint:sha-1 C2:FF:06:CD:0D:6C:EF:6E:CC:54:CE:2D:F1:68:34:DB:06:B8:79:6A
a=candidate:9ad7d1fe11a85c1a70d346f625a464501524626b 1 tcp 2130706431 172.31.54.51 4443 typ host generation 0
a=candidate:9ad7d1fe11a85c1a70d346f625a4645015247820 1 udp 2130706431 172.31.54.51 10000 typ host generation 0
a=candidate:9ad7d1fe11a85c1a70d346f625a46450ffffffff9d5ff4a9 1 tcp 1694498815 52.90.200.113 4443 typ srflx raddr 172.31.54.51 rport 4443 generation 0
a=candidate:9ad7d1fe11a85c1a70d346f625a46450ffffffff9d600a5e 1 udp 1677724415 52.90.200.113 10000 typ srflx raddr 172.31.54.51 rport 10000 generation 0
a=rtcp-mux
JSON/COLIBRI answer
PATCH below to /colibri/conferences/9ad7d1fe11a85c1a
{
"id": "9ad7d1fe11a85c1a",
"contents": [
{
"name": "audio",
"channels": [
{
"id": "b2c29ad1f4555d04",
"expire": 30,
"initiator": true,
"endpoint": "1490294249498",
"direction": "sendrecv",
"channel-bundle-id": "1490294249498",
"sources": [
1274366703
],
"ssrc-groups": [
{
"semantics": "SIM",
"sources": [
1274366703
]
}
],
"rtp-level-relay-type": "translator",
"payload-types": [
{
"id": 111,
"name": "opus",
"clockrate": 48000,
"channels": 2,
"parameters": {
"fmtp": [
"minptime=10;useinbandfec=1"
]
}
},
{
"id": 103,
"name": "ISAC",
"clockrate": 16000,
"channels": 1
},
{
"id": 104,
"name": "ISAC",
"clockrate": 32000,
"channels": 1
},
{
"id": 126,
"name": "telephone-event",
"clockrate": 8000,
"channels": 1
}
],
"rtp-hdrexts": [
{
"id": 1,
"uri": "urn:ietf:params:rtp-hdrext:ssrc-audio-level"
},
{
"id": 3,
"uri": "http://www.webrtc.org/experiments/rtp-hdrext/abs-send-time"
}
],
"transport": {
"xmlns": "urn:xmpp:jingle:transports:ice-udp:1",
"rtcp-mux": true,
"pwd": "2u1eHOiv1Sc3dF4bEeVM0CP4",
"ufrag": "NJe9",
"fingerprints": [
{
"fingerprint": "71:05:78:40:20:F0:F7:AD:DA:89:D6:F6:22:17:AC:FC:97:2B:1C:25:9A:D1:B6:E7:80:91:C7:72:A6:DE:2C:D3",
"hash": "sha-256",
"setup": "active"
}
],
"candidates": [
{
"foundation": 3031090232,
"component": 1,
"transport": "udp",
"priority": 2122260223,
"ip": "192.168.1.20",
"port": 53868,
"type": "host",
"generation": 0,
"network-id": 1,
"network-cost": 10,
"id": 3031090232,
"network": 1,
"protocol": "udp"
},
{
"foundation": 1119534572,
"component": 1,
"transport": "udp",
"priority": 1686052607,
"ip": "71.229.240.22",
"port": 53868,
"type": "srflx",
"raddr": "192.168.1.20",
"rport": 53868,
"generation": 0,
"network-id": 1,
"network-cost": 10,
"id": 1119534572,
"network": 1,
"protocol": "udp"
},
{
"foundation": 4197005512,
"component": 1,
"transport": "tcp",
"priority": 1518280447,
"ip": "192.168.1.20",
"port": 9,
"type": "host",
"tcptype": "active",
"generation": 0,
"network-id": 1,
"network-cost": 10,
"id": 4197005512,
"network": 1,
"protocol": "tcp"
}
]
}
}
],
"sctpconnections": []
},
{
"name": "video",
"channels": [
{
"id": "d4782a7f74565a42",
"expire": 30,
"initiator": true,
"endpoint": "1490294249498",
"direction": "sendrecv",
"channel-bundle-id": "1490294249498",
"sources": [
1305961943
],
"rtp-level-relay-type": "translator",
"ssrc-groups": [
{
"semantics": "SIM",
"sources": [
1305961943
]
}
],
"last-n": 2,
"payload-types": [
{
"id": 100,
"name": "VP8",
"clockrate": 90000,
"channels": 2,
"parameters": {
"rtcp-fb": [
"ccm fir",
"nack",
"nack pli",
"goog-remb"
]
}
}
],
"rtp-hdrexts": [
{
"id": 3,
"uri": "http://www.webrtc.org/experiments/rtp-hdrext/abs-send-time"
}
],
"transport": {
"xmlns": "urn:xmpp:jingle:transports:ice-udp:1",
"rtcp-mux": true,
"pwd": "2u1eHOiv1Sc3dF4bEeVM0CP4",
"ufrag": "NJe9",
"fingerprints": [
{
"fingerprint": "71:05:78:40:20:F0:F7:AD:DA:89:D6:F6:22:17:AC:FC:97:2B:1C:25:9A:D1:B6:E7:80:91:C7:72:A6:DE:2C:D3",
"hash": "sha-256",
"setup": "active"
}
],
"candidates": [
{
"foundation": 3031090232,
"component": 1,
"transport": "udp",
"priority": 2122260223,
"ip": "192.168.1.20",
"port": 53868,
"type": "host",
"generation": 0,
"network-id": 1,
"network-cost": 10,
"id": 3031090232,
"network": 1,
"protocol": "udp"
},
{
"foundation": 1119534572,
"component": 1,
"transport": "udp",
"priority": 1686052607,
"ip": "71.229.240.22",
"port": 53868,
"type": "srflx",
"raddr": "192.168.1.20",
"rport": 53868,
"generation": 0,
"network-id": 1,
"network-cost": 10,
"id": 1119534572,
"network": 1,
"protocol": "udp"
},
{
"foundation": 4197005512,
"component": 1,
"transport": "tcp",
"priority": 1518280447,
"ip": "192.168.1.20",
"port": 9,
"type": "host",
"tcptype": "active",
"generation": 0,
"network-id": 1,
"network-cost": 10,
"id": 4197005512,
"network": 1,
"protocol": "tcp"
}
]
}
}
],
"sctpconnections": []
}
],
"channel-bundles": [
{
"id": "1490294224066",
"transport": {
"candidates": [
{
"generation": 0,
"component": 1,
"protocol": "tcp",
"port": 4443,
"ip": "172.31.54.51",
"tcptype": "passive",
"foundation": "1",
"id": "9ad7d1fe11a85c1a5ec5e04d36669ed805534db8",
"priority": 2130706431,
"type": "host",
"network": 0
},
{
"generation": 0,
"component": 1,
"protocol": "udp",
"port": 10000,
"ip": "172.31.54.51",
"foundation": "3",
"id": "9ad7d1fe11a85c1a5ec5e04d36669ed80553636d",
"priority": 2130706431,
"type": "host",
"network": 0
},
{
"generation": 0,
"rel-port": 4443,
"ip": "52.90.200.113",
"foundation": "2",
"rel-addr": "172.31.54.51",
"priority": 1694498815,
"type": "srflx",
"network": 0,
"component": 1,
"protocol": "tcp",
"port": 4443,
"tcptype": "passive",
"id": "9ad7d1fe11a85c1a5ec5e04d36669ed80ffffffff8d8edff6"
},
{
"generation": 0,
"rel-port": 10000,
"component": 1,
"protocol": "udp",
"port": 10000,
"ip": "52.90.200.113",
"foundation": "4",
"id": "9ad7d1fe11a85c1a5ec5e04d36669ed80ffffffff8d8ef5ab",
"rel-addr": "172.31.54.51",
"priority": 1677724415,
"type": "srflx",
"network": 0
}
],
"xmlns": "urn:xmpp:jingle:transports:ice-udp:1",
"ufrag": "8hvaa1bbu7airb",
"rtcp-mux": true,
"pwd": "187sh2bf3dl0lfola6goifb988",
"fingerprints": [
{
"fingerprint": "C2:FF:06:CD:0D:6C:EF:6E:CC:54:CE:2D:F1:68:34:DB:06:B8:79:6A",
"setup": "actpass",
"hash": "sha-1"
}
]
}
},
{
"id": "1490294249498",
"transport": {
"candidates": [
{
"generation": 0,
"component": 1,
"protocol": "tcp",
"port": 4443,
"ip": "172.31.54.51",
"tcptype": "passive",
"foundation": "1",
"id": "9ad7d1fe11a85c1a70d346f625a464501524626b",
"priority": 2130706431,
"type": "host",
"network": 0
},
{
"generation": 0,
"component": 1,
"protocol": "udp",
"port": 10000,
"ip": "172.31.54.51",
"foundation": "3",
"id": "9ad7d1fe11a85c1a70d346f625a4645015247820",
"priority": 2130706431,
"type": "host",
"network": 0
},
{
"generation": 0,
"rel-port": 4443,
"ip": "52.90.200.113",
"foundation": "2",
"rel-addr": "172.31.54.51",
"priority": 1694498815,
"type": "srflx",
"network": 0,
"component": 1,
"protocol": "tcp",
"port": 4443,
"tcptype": "passive",
"id": "9ad7d1fe11a85c1a70d346f625a46450ffffffff9d5ff4a9"
},
{
"generation": 0,
"rel-port": 10000,
"component": 1,
"protocol": "udp",
"port": 10000,
"ip": "52.90.200.113",
"foundation": "4",
"id": "9ad7d1fe11a85c1a70d346f625a46450ffffffff9d600a5e",
"rel-addr": "172.31.54.51",
"priority": 1677724415,
"type": "srflx",
"network": 0
}
],
"xmlns": "urn:xmpp:jingle:transports:ice-udp:1",
"ufrag": "ere4l1bbu7bbf8",
"rtcp-mux": true,
"pwd": "79r5i3snbhbrca0735vs3v30q4",
"fingerprints": [
{
"fingerprint": "C2:FF:06:CD:0D:6C:EF:6E:CC:54:CE:2D:F1:68:34:DB:06:B8:79:6A",
"setup": "actpass",
"hash": "sha-1"
}
]
}
}
],
"channel-bundlesFOO": [
{
"id": 1490294249498,
"transport": {
"xmlns": "urn:xmpp:jingle:transports:ice-udp:1",
"rtcp-mux": true,
"pwd": "2u1eHOiv1Sc3dF4bEeVM0CP4",
"ufrag": "NJe9",
"fingerprints": [
{
"fingerprint": "71:05:78:40:20:F0:F7:AD:DA:89:D6:F6:22:17:AC:FC:97:2B:1C:25:9A:D1:B6:E7:80:91:C7:72:A6:DE:2C:D3",
"hash": "sha-256",
"setup": "actpass"
}
],
"candidates": [
{
"foundation": 3031090232,
"component": 1,
"transport": "udp",
"priority": 2122260223,
"ip": "192.168.1.20",
"port": 53868,
"type": "host",
"generation": 0,
"network-id": 1,
"network-cost": 10,
"id": 3031090232,
"network": 1,
"protocol": "udp"
},
{
"foundation": 1119534572,
"component": 1,
"transport": "udp",
"priority": 1686052607,
"ip": "71.229.240.22",
"port": 53868,
"type": "srflx",
"raddr": "192.168.1.20",
"rport": 53868,
"generation": 0,
"network-id": 1,
"network-cost": 10,
"id": 1119534572,
"network": 1,
"protocol": "udp"
},
{
"foundation": 4197005512,
"component": 1,
"transport": "tcp",
"priority": 1518280447,
"ip": "192.168.1.20",
"port": 9,
"type": "host",
"tcptype": "active",
"generation": 0,
"network-id": 1,
"network-cost": 10,
"id": 4197005512,
"network": 1,
"protocol": "tcp"
}
]
}
}
]
}
Chrome WebRTC Internals
Test browser tabs
Upvotes: 1
Views: 2681
Reputation: 404
Adding on a bit to @Harish's answer: if you're using the bridge rest API, I assume you're not using Jicofo and you're using your own signaling entity. If so, then you'll need to do all the application signaling on your own. Presumably you're already doing some of this (to send the offer to the client). So when the first client joins it'll get the base offer that is built from the bridge's channel allocate response. Once other clients join, some component (likely the signaling server) will need to accumulate their ssrcs and add them to the outgoing offers.
Upvotes: 0
Reputation: 782
The reason you are not able to see the ssrc_recv because when we get the offer from Jitsi videobridge, it comes with some default/no ssrc. In your offer SDP, you can see that there is no ssrc for the incoming stream. Basically, Jitsi send another message (source-add) which contain the correct ssrc information. So, you need to do setRemoteDescription with those ssrc values to let webrtc stack know the actual ssrc corresponding to the receiving stream , So that it can generate the stats for incoming stream and appear in webrtc-internal as well.
Upvotes: 1