背景
rtpengine提供媒体代理功能, 和sip代理(opensips或者kamailio)一起组成完整的代理服务。
针对rtpengine的使用,记录几个常用方法。
rtpengine的官方文档: rtpengine
当前测试的rtpegnine版本:
Version: 13.3.1.7+0~mr13.3.1.7 git-HEAD-c2223681
rtpengine 是否支持视频?
一直对rtpengine的视频支持不是很清楚,官方文档也没有明确说明。 rtpengine支持的编码有:

从支持的编码上看,都是音频编码,没有视频编码,所以我也认为是不支持视频的。
最近有空,就使用mircoSIP测试了视频功能,发现rtpengine支持视频。
完整的一通视频sip图:

媒体相关的信令:

可以看到音频用的是g711u,视频用的是h264
以下这通电话的详细sdp信令:
microSIP发出INVITE信令:

可以看到既有audio又有video
opensips转发INVITE信令:

opensips收到183ring信令:

opensips转发183ring信令:

- 接通之后,
microSIP发出媒体控制信令INFO:

opensips转发INFO信令:

目前视频流传输这块发现rtpengine有报错, 从效果来看,并没有卡顿情况:

综上所述, rtpengine支持视频,因为没有相应的编码,所以视频流透传。
rtpengine 的几个codec设置
在做媒体代理转发时,需要对sdp中的codec做调整, 而sdp是rtpengine生成的,
所以opensips或者kamailio调用rtpengine_manager时,设置codec参数可以调整sdp中的codec。
rtpengine提供的参数文档为: ng_control_protocol
codec-transcode
介绍
transcode 官方的解释是:
Similar to
offerbut allows codecs to be added to the list of offered codecs even if they were not present in the original list of codecs. In this case, the transcoding engine will be engaged. Only codecs that are supported for both decoding and encoding can be added in this manner. This also has the side effect of automatically stripping all unsupported codecs from the list of offered codecs, as rtpengine must expect to receive or even send in any codec that is present in the list.
意思就是: 可以添加原编码列表中没有的新编码,这个新的编码必须是rtpengine支持的fully supported的codecs.
此时会启用转码功能。另外也可以通过opus/48000/2/32000这样,设置采样率,声道数。
验证
codec-transcode-PCMU(源sdp含有的codecs)
sequenceDiagram
microSIP->>opensips: INVITE
Note over microSIP,opensips: PCMU,PCMA,telephone-event
opensips->>uas: INVITE
Note over opensips,uas: PCMU,PCMA,telephone-event
uas-->>opensips: 200OK
Note over uas,opensips: PCMA,telephone-event
opensips-->> microSIP: 200OK
Note over opensips, microSIP: PCMA,telephone-event
可以看到,codec-transcode-PCMU其实不起作用.
codec-transcode-G722(源sdp没有的codecs)
sequenceDiagram
microSIP->>opensips: INVITE
Note over microSIP,opensips: PCMU,PCMA,telephone-event
opensips->>uas: INVITE
Note over opensips,uas: PCMU,PCMA,G722,telephone-event
uas-->>opensips: 200OK
Note over uas,opensips: PCMA,telephone-event
opensips-->> microSIP: 200OK
Note over opensips, microSIP: PCMA,telephone-event
当和codec-strip-all codec-mask-all一起使用时,codec-transcode-PCMU不会启用转码,codec-transcode-G722会启用转码.
codec-strip
介绍
strip 官方的解释是:
Contains a list of strings. Each string is the name of a codec or RTP payload type that should be removed from the SDP. Codec names are case sensitive, and can be either from the list of codecs explicitly defined by the SDP through an
a=rtpmapattribute, or can be from the list of RFC-defined codecs. Examples arePCMU,opus, ortelephone-event. Codecs stripped using this option are only removed from the outgoing rewritten SDP and don’t affect the list of codecs that was offered by the source SDP. See theignoreoption above for a similar mechanism that affects the offer codecs.
意思就是: 从sdp中移除指定的编码. 可以是具体的某个编码,也可以是allorfull移除所有编码.
验证
codec-strip-PCMU(源sdp含有的codecs)
sequenceDiagram
microSIP->>opensips: INVITE
Note over microSIP,opensips: PCMU,PCMA,telephone-event
opensips->>uas: INVITE
Note over opensips,uas: PCMA,telephone-event
uas-->>opensips: 200OK
Note over uas,opensips: PCMA,telephone-event
opensips-->> microSIP: 200OK
Note over opensips, microSIP: PCMA,telephone-event
codec-strip-PCMA codec-transcode-G722(uas使用G722)
sequenceDiagram
microSIP->>opensips: INVITE
Note over microSIP,opensips: PCMU,PCMA,telephone-event
opensips->>uas: INVITE
Note over opensips,uas: PCMU,G722,telephone-event
uas-->>opensips: 200OK
Note over uas,opensips: G722,telephone-event
opensips-->> microSIP: 200OK
Note over opensips, microSIP: PCMU,telephone-event
codec-strip-G722(源sdp没有的codecs)
sequenceDiagram
microSIP->>opensips: INVITE
Note over microSIP,opensips: PCMU,PCMA,telephone-event
opensips->>uas: INVITE
Note over opensips,uas: PCMU,PCMA,telephone-event
uas-->>opensips: 200OK
Note over uas,opensips: PCMA,telephone-event
opensips-->> microSIP: 200OK
Note over opensips, microSIP: PCMA,telephone-event
这种方式下,codec-accept-G722不起作用.
-
codec-strip-all(删除所有)opensips转发INVITE时的sdp信息:1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16v=0 o=- 3959939030 3959939030 IN IP4 172.16.4.111 s=pjmedia b=AS:84 t=0 0 a=X-nat:0 m=audio 32560 RTP/AVP 0 8 101 c=IN IP4 172.16.4.111 b=TIAS:64000 a=rtpmap:0 PCMU/8000 a=rtpmap:8 PCMA/8000 a=rtpmap:101 telephone-event/8000 a=fmtp:101 0-16 a=ssrc:1854882148 cname:0baf6e5578824b50 a=sendrecv a=rtcp:32561可以看到好像并没有变化,查看
rtpengine的日志,有Warning:1 2 3 4[1750921364.090656] DEBUG: [0349a2eed9304f22ac7cb87970e1d5f7]: [codec] Stripping codec PCMU/8000/ (0) due to strip=all or strip=full [1750921364.090663] DEBUG: [0349a2eed9304f22ac7cb87970e1d5f7]: [codec] Stripping codec PCMA/8000/ (8) due to strip=all or strip=full [1750921364.090666] DEBUG: [0349a2eed9304f22ac7cb87970e1d5f7]: [codec] Stripping codec telephone-event/8000/0-16 (101) due to strip=all or strip=full [1750921364.090669] WARNING: [0349a2eed9304f22ac7cb87970e1d5f7]: [core] Usage error: List of codecs empty. Restoring original list of codecs. Results may be unexpected.rtpengine触发了保护机制,不允许删除所有的codecs.如果想查看效果,可以这样用
codec-strip-all codec-transcode-G722删除所有,新增G7221 2 3 4 5 6 7 8 9 10 11 12 13v=0 o=- 3959939604 3959939604 IN IP4 172.16.4.111 s=pjmedia b=AS:84 t=0 0 a=X-nat:0 m=audio 32710 RTP/AVP 9 c=IN IP4 172.16.4.111 b=TIAS:64000 a=rtpmap:9 G722/8000 a=ssrc:607722213 cname:2664202b2fde465f a=sendrecv a=rtcp:32711
codec-mask
介绍
mask 官方的解释是:
Similar to
stripexcept that codecs listed here will still be accepted and used for transcoding on the offering side. Useful only in combination withtranscode. For example, if an offer advertises Opus and the optionsmask=opus, transcode=G723are given, then the rewritten outgoing offer will contain only G.723 as offered codec, and transcoding will happen between Opus and G.723. In contrast, if onlytranscode=G723were given, then the rewritten outgoing offer would contain both Opus and G.723. On the other hand, ifstrip=opus, transcode=G723were given, then Opus would be unavailable for transcoding.
意思就是: 功能和strip类似,如果和transcode一起使用, 会设置A-leg方向的编码,也可以设置allorfull。
正常情况下, A---- opensips ----B, B返回200OK的编码,opensips会透传给A,
但是如果想改变opensips---A的200OK编码,就需要设置mask。
目前实际测试情况不太一样,并没有达到官方描述的效果,不知道是否是使用方法问题。
验证
codec-mask-PCMA(源sdp含有的codecs)
sequenceDiagram
microSIP->>opensips: INVITE
Note over microSIP,opensips: PCMU,PCMA,telephone-event
opensips->>uas: INVITE
Note over opensips,uas: PCMU,telephone-event
uas-->>opensips: 200OK
Note over uas,opensips: PCMU,telephone-event
opensips-->> microSIP: 200OK
Note over opensips, microSIP: PCMU,telephone-event
可以看到PCMA被删除了。
codec-mask-PCMA codec-transcode-G722(uas使用G722)
sequenceDiagram
microSIP->>opensips: INVITE
Note over microSIP,opensips: PCMU,PCMA,telephone-event
opensips->>uas: INVITE
Note over opensips,uas: PCMU,G722,telephone-event
uas-->>opensips: 200OK
Note over uas,opensips: G722,telephone-event
opensips-->> microSIP: 200OK
Note over opensips, microSIP: PCMU,telephone-event
codec-mask-G722(源sdp没有的codecs)
sequenceDiagram
microSIP->>opensips: INVITE
Note over microSIP,opensips: PCMU,PCMA,telephone-event
opensips->>uas: INVITE
Note over opensips,uas: PCMU,PCMA,telephone-event
uas-->>opensips: 200OK
Note over uas,opensips: PCMA,telephone-event
opensips-->> microSIP: 200OK
Note over opensips, microSIP: PCMA,telephone-event
这种方式下,codec-accept-G722不起作用.
codec-accept
介绍
accept 官方的解释是:
Similar to
maskandconsumebut doesn’t remove the codec from the list of offered codecs. This means that a codec listed underacceptwill still be offered to the remote peer, but if the remote peer rejects it, it will still be accepted towards the original offerer and then used for transcoding. It is a more selective version of what thealways transcodeflag does.
意思是: 和mask功能一样,但是不会删除codec, 当双向不一致会转码.
验证
codec-accept-PCMA(源sdp含有的codecs)
sequenceDiagram
microSIP->>opensips: INVITE
Note over microSIP,opensips: PCMU,PCMA,<br/>telephone-event
opensips->>+uas: INVITE
Note over opensips,uas: PCMU, PCMA,<br/>telephone-event
uas-->>-opensips: 200OK
Note over uas,opensips: PCMU,<br/>telephone-event
opensips-->> microSIP: 200OK
Note over opensips, microSIP: PCMA,<br/>telephone-event
可以看到,这种方式设置了A-leg的编码, A-leg和B-leg之间实现转码.
codec-accept-PCMA codec-transcode-G722(uas使用G722)
sequenceDiagram
microSIP->>opensips: INVITE
Note over microSIP,opensips: PCMU,PCMA,<br/>telephone-event
opensips->>+uas: INVITE
Note over opensips,uas: PCMU, PCMA,<br/>telephone-event
uas-->>-opensips: 200OK
Note over uas,opensips: G722,<br/>telephone-event
opensips-->> microSIP: 200OK
Note over opensips, microSIP: PCMA,<br/>telephone-event
codec-accept-G722(源sdp没有的codecs)
sequenceDiagram
microSIP->>opensips: INVITE
Note over microSIP,opensips: PCMU,PCMA,<br/>telephone-event
opensips->>+uas: INVITE
Note over opensips,uas: PCMU, PCMA,<br/>telephone-event
uas-->>-opensips: 200OK
Note over uas,opensips: PCMU,<br/>telephone-event
opensips-->> microSIP: 200OK
Note over opensips, microSIP: PCMU,<br/>telephone-event
这种方式下,codec-accept-G722不起作用.
codec-consume
介绍
consume 官方的解释是:
Identical to
maskbut enables the transcoding engine even if no other transcoding related options are given.
意思是: 和mask功能一样,但是会开启转码引擎,即使没有其他转码相关的选项。
验证
codec-consume-PCMA(源sdp含有的codecs)
sequenceDiagram
microSIP->>opensips: INVITE
Note over microSIP,opensips: PCMU,PCMA,telephone-event
opensips->>uas: INVITE
Note over opensips,uas: PCMU,telephone-event
uas-->>opensips: 200OK
Note over uas,opensips: PCMU,telephone-event
opensips-->> microSIP: 200OK
Note over opensips, microSIP: PCMA,telephone-event
可以看到,consume-PCMA设置后, 转发到B-leg的INVITE删除了PCMA,但是转发到A-leg的200OK,选择了PCMA, A-leg和B-leg实现转码。
codec-consume-PCMA codec-transcode-G722(uas使用G722)
sequenceDiagram
microSIP->>opensips: INVITE
Note over microSIP,opensips: PCMU,PCMA,telephone-event
opensips->>uas: INVITE
Note over opensips,uas: PCMU,G722,telephone-event
uas-->>opensips: 200OK
Note over uas,opensips: G722,telephone-event
opensips-->> microSIP: 200OK
Note over opensips, microSIP: PCMA,telephone-event
codec-consume-G722(源sdp没有的codecs)
sequenceDiagram
microSIP->>opensips: INVITE
Note over microSIP,opensips: PCMU,PCMA,telephone-event
opensips->>uas: INVITE
Note over opensips,uas: PCMU,PCMA,telephone-event
uas-->>opensips: 200OK
Note over uas,opensips: PCMU,telephone-event
opensips-->> microSIP: 200OK
Note over opensips, microSIP: PCMU, telephone-event
这种方式下,codec-accept-G722不起作用.
codec-except
介绍
except 官方的解释是:
Contains a list of strings. Each string is the name of a codec that should be included in the list of codecs offered. This is primarily useful to block all codecs (
strip -> allormask -> all) except the ones given in theexceptwhitelist. Codecs that were not present in the original list of codecs offered by the client will be ignored.
意思就是: 白名单,和codec-strip-allorcodec-mask-all一起使用才有效。
验证
codec-strip-all codec-except-PCMA(源sdp含有的codecs)
sequenceDiagram
microSIP->>opensips: INVITE
Note over microSIP,opensips: PCMU,PCMA,telephone-event
opensips->>uas: INVITE
Note over opensips,uas: PCMA
uas-->>opensips: 200OK
Note over uas,opensips: PCMA,telephone-event
opensips-->> microSIP: 200OK
Note over opensips, microSIP: PCMA
codec-strip-all codec-except-G722(源sdp没有的codecs)
sequenceDiagram
microSIP->>opensips: INVITE
Note over microSIP,opensips: PCMU,PCMA,telephone-event
opensips->>uas: INVITE
Note over opensips,uas: PCMU,PCMA,telephone-event
uas-->>opensips: 200OK
Note over uas,opensips: PCMU,telephone-event
opensips-->> microSIP: 200OK
Note over opensips, microSIP: PCMU,telephone-event
这种方式下,codec-accept-G722不起作用.
codec-offer
介绍
offer 官方的解释是:
This is identical to
exceptbut additionally allows the codec order to be changed. So the first codec listed inofferwill be the primary (preferred) codec in the output SDP, even if it wasn’t originally so.
意思就是:和except一样,但是会改变编码顺序.
验证
codec-strip-all codec-offer-PCMA codec-offer-PCMU(源sdp含有的codecs)
sequenceDiagram
microSIP->>opensips: INVITE
Note over microSIP,opensips: PCMU,PCMA,telephone-event
opensips->>uas: INVITE
Note over opensips,uas: PCMA,PCMU
uas-->>opensips: 200OK
Note over uas,opensips: PCMA,telephone-event
opensips-->> microSIP: 200OK
Note over opensips, microSIP: PCMA
可以看到,转发B-leg的INVITE时,编码顺序改变了。
codec-strip-all codec-except-PCMA codec-except-PCMU在转发B-leg的INVITE时, PCMU PCMA编码顺序不会变.
codec-strip-all codec-offer-G722(源sdp没有的codecs)
sequenceDiagram
microSIP->>opensips: INVITE
Note over microSIP,opensips: PCMU,PCMA,telephone-event
opensips->>uas: INVITE
Note over opensips,uas: PCMU,PCMA,telephone-event
uas-->>opensips: 200OK
Note over uas,opensips: PCMU,telephone-event
opensips-->> microSIP: 200OK
Note over opensips, microSIP: PCMU,telephone-event
这种方式下,codec-accept-G722不起作用.
codec-ignore
介绍
ignore 官方的解释是:
Similar to the
stripoption below, but affects only codecs listed in the incoming received SDP. Codecs listed here are treated as if they were never offered, and so will not be used for media towards the offerer. Note that codecs listed here would still be used in the outgoing rewritten offer SDP, unless the same codecs are also listed understrip. This means that if a codec is only ignored but not stripped, and if that codec is then accepted by the answerer, transcoding will necessarily be enabled.
验证
codec-ignore-PCMA(源sdp含有的codecs)
sequenceDiagram
microSIP->>opensips: INVITE
Note over microSIP,opensips: PCMU,PCMA,telephone-event
opensips->>uas: INVITE
Note over opensips,uas: PCMU,PCMA,telephone-event
uas-->>opensips: 200OK
Note over uas,opensips: PCMU,telephone-event
opensips-->> microSIP: 200OK
Note over opensips,microSIP: PCMA,telephone-event
可以看到,转发A-leg的200OK,使用了PCMA,实现转码. 其效果和accept一样
codec-ignore-G722(源sdp没有的codecs)
sequenceDiagram
microSIP->>opensips: INVITE
Note over microSIP,opensips: PCMU,PCMA,telephone-event
opensips->>uas: INVITE
Note over opensips,uas: PCMU,PCMA,telephone-event
uas-->>opensips: 200OK
Note over uas,opensips: PCMU,telephone-event
opensips-->> microSIP: 200OK
Note over opensips, microSIP: PCMU,telephone-event
这种方式下,codec-accept-G722不起作用.
rtpengine interface设置
当我们使用 opensips或者kamailio+rtpengine做sbc网关时, 需要根据内外网环境自动切换媒体ip,
此时rtpengine的监听interface设置就至关重要。下面是rtpengine.conf的设置介绍:
|
|
- 当有多个网卡时, 可以使用
interface = internal/192.168.2.234;external/23.34.45.54设置。 - 当有多个外网ip时,可以使用
interface = 23.34.45.54!23.34.45.55设置。
但是实际在使用过程中, sbc都是在内网部署,网关或者路由器做nat转换, 转发请求到sbc上。
此时rtpengine是单网卡,监听的ip是内网ip, 如何设置外网ip呢, 主要有两种方式:
interface = LOCAL_IP!PUBLIC_IP
这种方式设置,默认生成的SDP信息中的c=,o=会是PUBLIC_IP,
但是当我们想要c=,o=换成LOCAL_IP, 可以在rtpengine_manager("media-address=LOCAL_IP")强转成LOCAL_IP。
但是这种只会改变c=为LOCAL_IP, o=还是PUBLIC_IP。实际也不会有什么影响。毕竟真正使用的是c=
interface=pub/LOCAL_IP!PUBLIC_IP;priv/LOCAL_IP
这种是最佳方式,pub,priv这两个名字你可以随便起,但是当你使用rtpengine_manager()时,一定要和这两个名字一致。
在rtpengine的ng_control中,用的参数是direction=["priv","pub"]。
需要注意的是当我们使用opensips时,要用in-iface=priv out-iface=pub,这样往rtpengine发送的offer才会转成direction=["priv","pub"]。
opensips的官方文档rtpengine模块中介绍用的是in-iface=internal out-iface=external,
我们在rtpengine.conf中设置的是pub/LOCAL_IP!PUBLIC_IP;priv/LOCAL_IP, 要灵活变通,改成in-iface=priv out-iface=pub。
in-iface=priv out-iface=pub的含义是: 进来请求的sdp用的是priv的ip, 转发请求的sdp用的是pub的ip,这种是外呼的情况。
我们只需要在转发INVITE时,设置此参数即可, 收到183或者200OK时,不需要再设置。
interface = internal/LOCAL_IP;external/PUBLIC_IP
这种只能在双网卡的环境下才能使用, 单网卡的环境下,这样使用会报错。
|
|
即使在/etc/sysctl.conf中添加net.ipv4.ip_nonlocal_bind=1,能解决报错问题, 因为没有PUBLIC_IP网卡,还是会出现没有声音情况。