1. Janus插件交互流程
Janus中所有插件都遵循以下基本数据流程:
- 客户端发送create创建一个Janus会话;
- Janus回复success返回Janus会话句柄;
- 客户端发送attach命令在Janus会话上attach指定插件;
- Janus回复success返回插件的句柄;
- 客户端给指定的插件发送message进行信令控制;
- Janus上的插件发送event通知事件给客户端;
- 客户端收集candidate并通过trickle消息发送给插件绑定的ICE通道;
- Janus发送webrtcup通知ICE通道建立;
- 客户端发送媒体数据;
- Janus发送media消息通知媒体数据的第一次到达;
- Janus进行媒体数据转发。
2. Janus信令交互过程
2.1 客户端与Janus信令交互
Janus客户端Janus网关Janus客户端发送create请求创建会话Janus网关创建会话,并返回会话IDJanus客户端发送attach请求使用插件Janus网关查找插件,并返回插件IDJanus客户端给指定插件发送message(Join)Janus网关返回ack消息Janus网关处理message,并将结果通过event事件发送给客户端Janus客户端给指定插件发送message(Configure & offer)Janus客户端给指定插件发送trickle(Candidate)...【有多个trickle(Candidate)】...【有多个trickle(Candidate)】Janus客户端给指定插件发送trickle(Candidate)Janus网关返回message(Configure & offer)的ack消息Janus网关处理message(Configure & offer),并将answer通过event事件发送给客户端Janus网关返回ack消息...【有多个trickle(Candidate)的ack】)...【有多个trickle(Candidate)的ack】)Janus网关返回ack消息Janus客户端给指定插件发送trickle(Candidate Complete)Janus网关返回trickle(Candidate Complete)的ack消息Janus网关返回webrtcup消息Janus网关返回media(video)消息Janus网关返回media(audio)消息发送媒体数据(video、audio)Janus客户端
Janus网关
- Janus客户端->Janus网关: Janus客户端发送create请求创建会话
{
"janus": "create",
"transaction": "XoldN2OmUa3r
}
- Janus网关–>>Janus客户端: Janus网关创建会话,并返回会话ID
{
"janus": "success",
"transaction": "XoldN2OmUa3r,
"data": {
"id": 7147844471131709
}
}
- Janus客户端->Janus网关: Janus客户端发送attach请求使用插件
{
"janus": "attach",
"plugin": "janus.plugin.videoroom",
"session_id": 7147844471131709,
"transaction": "zZxl_ZT7tFwTU"
}
- Janus网关–>>Janus客户端: Janus网关返回插件加载成功
-
[ { "janus": "event", "session_id": 2203210992983819, "transaction": "6G0CWxnS0AIf", "sender": 5887795480428864, "plugindata": { "plugin": "janus.plugin.videoroom", "data": { "videoroom": "attached", "room": 8888, "id": 7999958966973344, "display": "yml" } }, "jsep": { "type": "offer", "sdp": "v=0\r\no=- 1596633570688053 1 IN IP4 120.92.210.247\r\ns=VideoRoom 8888\r\nt=0 0\r\na=group:BUNDLE audio video\r\na=msid-semantic: WMS janus\r\nm=audio 9 UDP/TLS/RTP/SAVPF 111\r\nc=IN IP4 221.92.210.247\r\na=sendonly\r\na=mid:audio\r\na=rtcp-mux\r\na=ice-ufrag:cUyJ\r\na=ice-pwd:7BnHt9f+FtnwyEhZI4OAUB\r\na=ice-options:trickle\r\na=fingerprint:sha-256 75:6B:DD:07:96:B9:3F:58:5D:85:A1:48:39:E7:3B:52:92:CE:95:BE:8D:A4:8C:02:6A:A6:C2:21:9D:A8:5E:C3\r\na=setup:actpass\r\na=rtpmap:111 opus/48000/2\r\na=extmap:1 urn:ietf:params:rtp-hdrext:ssrc-audio-level\r\na=extmap:2 urn:ietf:params:rtp-hdrext:sdes:mid\r\na=rtcp-fb:111 transport-cc\r\na=msid:janus janusa0\r\na=ssrc:1141520184 cname:janus\r\na=ssrc:1141520184 msid:janus janusa0\r\na=ssrc:1141520184 mslabel:janus\r\na=ssrc:1141520184 label:janusa0\r\na=candidate:1 1 udp 2013266431 120.92.210.247 62294 typ host\r\na=end-of-candidates\r\nm=video 9 UDP/TLS/RTP/SAVPF 96 97\r\nc=IN IP4 221.92.210.247\r\na=sendonly\r\na=mid:video\r\na=rtcp-mux\r\na=ice-ufrag:cUyJ\r\na=ice-pwd:7BnHt9f+FtnwyEhZI4OAUB\r\na=ice-options:trickle\r\na=fingerprint:sha-256 75:6B:DD:07:96:B9:3F:58:5D:85:A1:48:39:E7:3B:52:92:CE:95:BE:8D:A4:8C:02:6A:A6:C2:21:9D:A8:5E:C3\r\na=setup:actpass\r\na=rtpmap:96 VP8/90000\r\na=rtcp-fb:96 ccm fir\r\na=rtcp-fb:96 nack\r\na=rtcp-fb:96 nack pli\r\na=rtcp-fb:96 goog-remb\r\na=extmap:2 urn:ietf:params:rtp-hdrext:sdes:mid\r\na=extmap:3 http://www.ietf.org/id/draft-holmer-rmcat-transport-wide-cc-extensions-01\r\na=extmap:6 http://www.webrtc.org/experiments/rtp-hdrext/playout-delay\r\na=fmtp:96 max-fs=12288;max-fr=60\r\na=rtpmap:97 rtx/90000\r\na=fmtp:97 apt=96\r\na=ssrc-group:FID 2531919795 1677914875\r\na=msid:janus janusv0\r\na=ssrc:2531919795 cname:janus\r\na=ssrc:2531919795 msid:janus janusv0\r\na=ssrc:2531919795 mslabel:janus\r\na=ssrc:2531919795 label:janusv0\r\na=ssrc:1677914875 cname:janus\r\na=ssrc:1677914875 msid:janus janusv0\r\na=ssrc:1677914875 mslabel:janus\r\na=ssrc:1677914875 label:janusv0\r\na=candidate:1 1 udp 2013266431 221.92.210.247 62294 typ host\r\na=end-of-candidates\r\n" } } ]
{
"janus": "success",
"session_id": 7147844471131709,
"transaction": "zZxl_ZT7tFwTU",
"data": {
"id": 7668325947218508
}
}
Janus网关–>>Janus客户端: Janus网关查找插件,并返回插件ID
- Janus客户端->Janus网关: Janus客户端给指定插件发送message(Join)
{
"janus": "message",
"session_id": 7147844471131709,
"handle_id": 7668325947218508
"transaction": "AblncRsrMM3T",
"body": {
"request": "join",
"room": 1234,
"ptype": "publisher",
"display": "ban"
}
}
- Janus网关–>>Janus客户端: Janus网关返回ack消息
{
"janus": "ack",
"session_id": 7147844471131709,
"transaction": "AblncRsrMM3T"
}
- 1
- 2
- 3
- 4
- 5
- Janus网关–>>Janus客户端: Janus网关处理message,并将结果通过event事件发送给客户端
{
"janus": "event",
"session_id": 7147844471131709,
"transaction": "AblncRsrMM3T",
"sender": 7668325947218508,
"plugindata": {
"plugin": "janus.plugin.videoroom",
"data": {
"videoroom": "joined",
"room": 1234,
"description": "Demo Room",
"id": 8177683424697792,
"private_id": 1508384900,
"publishers":[]
}
}
}
- Janus客户端->Janus网关: Janus客户端给指定插件发送message(Configure & offer)
{
"janus": "message",
"session_id": 7147844471131709,
"handle_id": 7668325947218508,
"transaction": "QvOYptHlhVOl",
"body": {
"request": "configure",
"audio": true,
"video": true
},
"jsep": {
"sdp": "......",
"type": "offer"
}
}
- Janus客户端->Janus网关: Janus客户端给指定插件发送trickle(Candidate)
{
"candidate": {
"candidate": "candidate:2202484529 1 udp 2122262783 2409:8805:85e3:2dd9:l:l:al91:925c 55527 typ host generation 0",
"sdpMid": "audio",
"sdpMLinelndex": 0
},
"janus": "trickle",
"session_id": 7147844471131709,
"handle_id": 7668325947218508,
"transaction": "A39mtuEYv9cR"
}
{
"candidate": {
"candidate": "candidate:2530088836 1 udp 2122194687 192.168.1.106 33864 typ host generation 0",
"sdpMid": "audio",
"sdpMLinelndex": 0
}
"janus": "trickle",
"session_id": 7147844471131709,
"handle_id": 7668325947218508,
"transaction": "qFvztALbkXUG"
}
{
"candidate": {
"candidate": "candidate:2202484529 2 udp 2122262782 2409:8805:85e3:2dd9:l:l:al91:925c 42873 typ host generation 0",
"sdpMid": "audio",
"sdpMLinelndex": 0
},
"janus": "trickle",
"session_id": 7147844471131709,
"handle_id": 7668325947218508,
"transaction": "VOzahdOJx6pn"
}
{
"candidate": {
"candidate": "candidate:2530088836 2 udp 2122194686 192.168.1.106 44575 typ host generation 0",
"sdpMid": "audio",
"sdpMLinelndex": 0
},
"janus": "trickle",
"session_id": 7147844471131709,
"handle_id": 7668325947218508,
"transaction": "spupMHelabw8"
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- Janus网关–>>Janus客户端: Janus网关返回message(Configure & offer)的ack消息
{
"janus": "ack",
"session_id": 7147844471131709,
"transaction": "QvOYptHlhVOl"
}
- 1
- 2
- 3
- 4
- 5
- Janus网关–>>Janus客户端: Janus网关处理message(Configure & offer),并将answer通过event事件发送给客户端
{
"janus": "event",
"session_id": 7147844471131709,
"transaction": "Qv0YptHlhVOl"
"sender": 7668325947218508,
"plugindata": {
"plugin": "janus.plugin.videoroom",
"data": {
"videoroom": "event",
"room": 1234,
"configured": "ok"
"audio_codec": "opus",
"video_codec": "h264"
}
},
"jsep":{
"type": "answer",
"sdp": "......"
}
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- Janus网关–>>Janus客户端: Janus网关返回ack消息
{
"janus": "ack",
"session_id": 7147844471131709,
"transaction": "A39mtuEYv9cR"
}
- 1
- 2
- 3
- 4
- 5
{
"janus": "ack",
"session_id": 7147844471131709,
"transaction": "qFvztALbkXUG"
}
- 1
- 2
- 3
- 4
- 5
{
"janus": "ack",
"session_id": 7147844471131709,
"transaction": "VOzahdOJx6pn"
}
- 1
- 2
- 3
- 4
- 5
{
"janus": "ack",
"session_id": 7147844471131709,
"transaction": "spupMHelabw8"
}
- 1
- 2
- 3
- 4
- 5
- Janus客户端->Janus网关: Janus客户端给指定插件发送trickle(Candidate Complete)
{
"candidate": {
"completed": true
}
"janus": "trickle",
"session_id": 7147844471131709,
"handle_id": 7668325947218508,
"transaction": "43XefXDPTPMX"
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- Janus网关–>>Janus客户端: Janus网关返回trickle(Candidate Complete)的ack消息
{
"janus": "ack",
"session_id": 7147844471131709
"transaction": "43XefXDPTPMX"
}
- 1
- 2
- 3
- 4
- 5
- Janus网关–>>Janus客户端: Janus网关返回webrtcup消息
{
"janus": "webrtcup",
"session_id": 7147844471131709,
"sender": 7668325947218508
}
- 1
- 2
- 3
- 4
- 5
- Janus网关–>>Janus客户端: Janus网关返回media(video)消息
{
"janus": "media",
"session_id": 7147844471131709,
"sender": 7668325947218508,
"type": "video",
"receiving": true
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- Janus网关–>>Janus客户端: Janus网关返回media(audio)消息
{
"janus": "media",
"session_id": 7147844471131709,
"sender": 7668325947218508,
"type": "audio",
"receiving": true
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
2.2 客户端之间的交互
Janus客户端AJanus网关Janus客户端B建立连接过程参考【客户端与Janus信令交互】连接建立成功建立连接过程参考【客户端与Janus信令交互】连接建立成功发送媒体数据(video、audio)处理媒体数据分层(video、audio)转发媒体数据分层(video、audio)发送媒体数据(video、audio)处理媒体数据分层(video、audio)转发媒体数据分层(video、audio)Janus客户端AJanus网关
Janus客户端B
2.3 客户端keepalive
Janus客户端Janus网关Janus客户端发送keepaliveJanus网关返回ack消息Janus客户端
Janus网关
- Janus客户端->Janus网关: Janus客户端发送keepalive
{
"janus": "keepalive",
"session_id": 7147844471131709,
"transaction": "WZqW7GMauQpS"
}
- 1
- 2
- 3
- 4
- 5
- Janus网关–>>Janus客户端: Janus网关返回ack消息
{
"janus": "ack",
"session_id": 7147844471131709,
"transaction": "WZqW7GMauQpS"
}
- 1
- 2
- 3
- 4
- 5
3. 完整信令交互时序图
4. 参考资料
基于Webrtc和Janus的多人视频会议系统开发4 - 改造信令交互系统完成sdp交换过程
https://blog.csdn.net/u011382962/article/details/81708519