janus videoroom之媒体发布

janus是一款开源的webrtc服务器,里面的videoroom是其中一个插件,我称之为房间管理或者会议管理。

如下图所示,入会者1首先加入房间1,然后向此房间发布了自身的音频和视频,然后入会者2加入此房间,并且订阅了入会者1的视频,于是入会者2可以看到入会者1发布的视频。

在这里插入图片描述

在代码编写上的重要节点如下所示:
在这里插入图片描述

现在简要说明下入会者1向房间1发布视频的过程:
首先,入会者1通过CreateOffer构建本地媒体sdp信息,如下所示,然后发往janus服务端:

v=0
o=- 3472291487455110701 2 IN IP4 127.0.0.1
s=-
t=0 0
a=group:BUNDLE video
a=extmap-allow-mixed
a=msid-semantic: WMS stream_id
m=video 9 UDP/TLS/RTP/SAVPF 96 97 98 99 100 101 127 120 125 119 124 107 108 109 35 36 123 118 122
c=IN IP4 0.0.0.0
a=rtcp:9 IN IP4 0.0.0.0
a=ice-ufrag:yU12
a=ice-pwd:Jjm0K7LoqYepU5beCbu/gqCe
a=ice-options:trickle
a=fingerprint:sha-256 71:6F:4E:36:E9:C2:E6:6D:FB:25:16:72:61:69:2F:83:83:53:79:4B:6A:30:4F:CE:48:01:50:05:2A:91:CA:E7
a=setup:actpass
a=mid:video
a=extmap:1 urn:ietf:params:rtp-hdrext:toffset
a=extmap:2 http://www.webrtc.org/experiments/rtp-hdrext/abs-send-time
a=extmap:3 urn:3gpp:video-orientation
a=extmap:4 http://www.ietf.org/id/draft-holmer-rmcat-transport-wide-cc-extensions-01
a=extmap:5 http://www.webrtc.org/experiments/rtp-hdrext/playout-delay
a=extmap:6 http://www.webrtc.org/experiments/rtp-hdrext/video-content-type
a=extmap:7 http://www.webrtc.org/experiments/rtp-hdrext/video-timing
a=extmap:8 http://www.webrtc.org/experiments/rtp-hdrext/color-space
a=sendrecv
a=rtcp-mux
a=rtcp-rsize
a=rtpmap:96 VP8/90000
a=rtcp-fb:96 goog-remb
a=rtcp-fb:96 transport-cc
a=rtcp-fb:96 ccm fir
a=rtcp-fb:96 nack
a=rtcp-fb:96 nack pli
a=rtpmap:97 rtx/90000
a=fmtp:97 apt=96
a=rtpmap:98 VP9/90000
a=rtcp-fb:98 goog-remb
a=rtcp-fb:98 transport-cc
a=rtcp-fb:98 ccm fir
a=rtcp-fb:98 nack
a=rtcp-fb:98 nack pli
a=fmtp:98 profile-id=0
a=rtpmap:99 rtx/90000
a=fmtp:99 apt=98
a=rtpmap:100 VP9/90000
a=rtcp-fb:100 goog-remb
a=rtcp-fb:100 transport-cc
a=rtcp-fb:100 ccm fir
a=rtcp-fb:100 nack
a=rtcp-fb:100 nack pli
a=fmtp:100 profile-id=2
a=rtpmap:101 rtx/90000
a=fmtp:101 apt=100
a=rtpmap:127 H264/90000
a=rtcp-fb:127 goog-remb
a=rtcp-fb:127 transport-cc
a=rtcp-fb:127 ccm fir
a=rtcp-fb:127 nack
a=rtcp-fb:127 nack pli
a=fmtp:127 level-asymmetry-allowed=1;packetization-mode=1;profile-level-id=42001f
a=rtpmap:120 rtx/90000
a=fmtp:120 apt=127
a=rtpmap:125 H264/90000
a=rtcp-fb:125 goog-remb
a=rtcp-fb:125 transport-cc
a=rtcp-fb:125 ccm fir
a=rtcp-fb:125 nack
a=rtcp-fb:125 nack pli
a=fmtp:125 level-asymmetry-allowed=1;packetization-mode=0;profile-level-id=42001f
a=rtpmap:119 rtx/90000
a=fmtp:119 apt=125
a=rtpmap:124 H264/90000
a=rtcp-fb:124 goog-remb
a=rtcp-fb:124 transport-cc
a=rtcp-fb:124 ccm fir
a=rtcp-fb:124 nack
a=rtcp-fb:124 nack pli
a=fmtp:124 level-asymmetry-allowed=1;packetization-mode=1;profile-level-id=42e01f
a=rtpmap:107 rtx/90000
a=fmtp:107 apt=124
a=rtpmap:108 H264/90000
a=rtcp-fb:108 goog-remb
a=rtcp-fb:108 transport-cc
a=rtcp-fb:108 ccm fir
a=rtcp-fb:108 nack
a=rtcp-fb:108 nack pli
a=fmtp:108 level-asymmetry-allowed=1;packetization-mode=0;profile-level-id=42e01f
a=rtpmap:109 rtx/90000
a=fmtp:109 apt=108
a=rtpmap:35 AV1X/90000
a=rtcp-fb:35 goog-remb
a=rtcp-fb:35 transport-cc
a=rtcp-fb:35 ccm fir
a=rtcp-fb:35 nack
a=rtcp-fb:35 nack pli
a=rtpmap:36 rtx/90000
a=fmtp:36 apt=35
a=rtpmap:123 red/90000
a=rtpmap:118 rtx/90000
a=fmtp:118 apt=123
a=rtpmap:122 ulpfec/90000
a=ssrc-group:SIM 641900782 3943368063
a=ssrc-group:FID 641900782 3441713
a=ssrc-group:FID 3943368063 31504779
a=ssrc:641900782 cname:6NnFXLT7cULbX/w5
a=ssrc:641900782 msid:stream_id video_label
a=ssrc:641900782 mslabel:stream_id
a=ssrc:641900782 label:video_label
a=ssrc:3943368063 cname:6NnFXLT7cULbX/w5
a=ssrc:3943368063 msid:stream_id video_label
a=ssrc:3943368063 mslabel:stream_id
a=ssrc:3943368063 label:video_label
a=ssrc:3441713 cname:6NnFXLT7cULbX/w5
a=ssrc:3441713 msid:stream_id video_label
a=ssrc:3441713 mslabel:stream_id
a=ssrc:3441713 label:video_label
a=ssrc:31504779 cname:6NnFXLT7cULbX/w5
a=ssrc:31504779 msid:stream_id video_label
a=ssrc:31504779 mslabel:stream_id
a=ssrc:31504779 label:video_label

同时入会者1在媒体信息构建完成后,也需要搜集本地的候选地址(candidate),并将候选地址发送给janus服务端,候选地址的收集由SetLocalDescription触发,即入会者1CreateOffer后,得到本地sdp信息,然后调用SetLocalDescription设置本地sdp,然后在webrtc的回调函数OnIceCandidate得到候选地址,格式如下:

candidate:3128384608 1 udp 2122260223 10.0.0.29 55659 typ host generation 0 ufrag Fxqj network-id 1

这个地址就是本地与janus服务端进行媒体交互的地址,端口。
如果本地有多个地址,则OnIceCandidate会被触发多次,如下图所示,本机一共有三个本地地址,其中我禁掉了两个,所以OnIceCandidate的回调只触发一次。
在这里插入图片描述

我们关注下m=video 9 UDP/TLS/RTP/SAVPF 96 97 98 99 100 101 127 120 125 119 124 107 108 109 35 36 123 118 122,其中video代表的是视频,96,97,等等,这些数字代表媒体负荷类型,我们可以理解其为音视频编解码,比如数字0代表PCMU,8代表PCMA,从96开始,媒体负荷类型是不固定的,96所代表的媒体负荷类型由下面条件给出:

a=rtpmap:96 VP8/90000
a=rtcp-fb:96 goog-remb
a=rtcp-fb:96 transport-cc
a=rtcp-fb:96 ccm fir
a=rtcp-fb:96 nack
a=rtcp-fb:96 nack pli

可以看出96代表的是VP8编码,所以入会者1的sdp信息中支持了若干个媒体负荷类型。

同时我们可以看出video后面紧跟的数字是9,在正常的SIP交互时,这个数字代表发起端的媒体端口,很明显,此处不是。

当janus服务端收到这个请求时,它主要干两件事:
1.确定媒体负荷类型
即janus服务端要求入会者1以何种编码方式向其传送媒体信息
2.分配本地端口,便于入会者1向该地址发送媒体数据

先看第一件事情,janus服务端会查看其自身所支持的媒体负荷类型,这个在rtp.h文件中有定义,本人的janus版本有些老,只支持3种。
在这里插入图片描述
然后janus服务器会在其自身支持的媒体负荷类型和入会者1发过来的媒体负荷类型的交集中取一个媒体负荷类型,本人的janus代码里面取的是H264,然后构建出的sdp信息如下:

v=0
o=- 1657534564657969 1 IN IP4 127.0.0.1
s=VideoRoom 99352526
t=0 0
c=IN IP4 127.0.0.1
m=video 1 UDP/TLS/RTP/SAVPF 107
c=IN IP4 127.0.0.1
a=sendonly
a=rtpmap:107 H264/90000
a=fmtp:107 profile-level-id=42e01f;packetization-mode=1
a=rtcp-fb:107 ccm fir
a=rtcp-fb:107 nack
a=rtcp-fb:107 nack pli
a=rtcp-fb:107 goog-remb
a=extmap:3 urn:3gpp:video-orientation

a=extmap:5 http://www.webrtc.org/experiments/rtp-hdrext/playout-delay

可以看到这个sdp清爽多了,这个sdp会被入会者1保存起来。但是可以发现一个明显问题,这个sdp中无服务端的端口,入会者在这种情况下无法将媒体发布给服务端。为此,在ice(libnice库实现)层,janus服务器在此sdp基础上,添加了对应的端口,如下所示:

v=0
o=- 3472291487455110701 2 IN IP4 127.0.0.1
s=VideoRoom 99352526
t=0 0
a=group:BUNDLE video
a=msid-semantic: WMS janus
m=video 9 UDP/TLS/RTP/SAVPF 127 120
c=IN IP4 127.0.0.1
b=AS:4096
a=recvonly
a=mid:video
a=rtcp-mux
a=ice-ufrag:K0Xd
a=ice-pwd:0k5WszrUJXbK7ysbmGKVD4
a=ice-options:trickle
a=fingerprint:sha-256 D2:B9:31:8F:DF:24:D8:0E:ED:D2:EF:25:9E:AF:6F:B8:34:AE:53:9C:E6:F3:8F:F2:64:15:FA:E8:7F:53:2D:38
a=setup:active
a=rtpmap:127 H264/90000
a=fmtp:127 profile-level-id=42e01f;packetization-mode=1
a=rtcp-fb:127 ccm fir
a=rtcp-fb:127 nack
a=rtcp-fb:127 nack pli
a=rtcp-fb:127 goog-remb
a=rtcp-fb:127 transport-cc
a=extmap:3 urn:3gpp:video-orientation
a=extmap:5 http://www.webrtc.org/experiments/rtp-hdrext/playout-delay
a=rtpmap:120 rtx/90000
a=fmtp:120 apt=127
a=ssrc-group:FID 228912222 3881902705
a=candidate:1 1 udp 2015363327 127.0.0.1 20260 typ host
a=end-of-candidates

可以看出,janus端启动的端口是20260,将此sdp回给入会者1,则入会者1就会往janus服务器的20260端口发送H264编码的视频。

在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值