FreeSWITCH之配置G729转码

本文介绍如何在FreeSWITCH中配置开源bcg729模块以支持G729编码,通过详细步骤指导读者实现节省带宽的目的。

在互联网大数据时代的背景下,作为服务器程序,高并发尤为重要,线路带宽资源就显得更加弥足珍贵了。目前比较流行语音编码有2种G711、G729。由于语音需要采用上下行对等的宽带,G711每线需要大约90kbit/s/S的带宽,而G729每线仅需要30kbit/s/S的带宽。所以采用G729编码就节约了大量带宽。
FreeSWITCH默认是不支持G729转码的,商业版本的G729效率是最高的,不过要10刀1个并发,相信很少公司会舍得采用这么高的成本去做业务。这里介绍一下freeswitch配置开源的bcg729进行转码的方法:

1.准备工作:与当前运行的FreeSWITCH版本一致的源码一份,Linux 虚拟机
2.编译bcg729:
2.1 在FreeSWITCH官网下下载源码 [freeswitch-1.10.06.tar.gz请添加链接描述](http://files.freeswitch.org/releases/freeswitch/freeswitch-1.6.19.tar.gz) 
            解压源码到/usr/src/freeswitch-1.6.19
2.2 进入源码../src/mod/endpoints目录
            cd /usr/src/freeswitch-1.6.19/src/mod/endpoints
2.3 Git检出FreeSWITCH适用的G729模块(这部分源码是对BCG729进行FreeSWITCH的适配)
            git clone https://github.com/xadhoom/mod_bcg729.git
2.4 将mod_bcg729改名为mod_g729
            mv mod_bcg729 mod_g729
2.5 返回FreeSWITCH源码主目录,执行配置
            ./configure
2.6 进入../src/mod/endpoints/mod_g729目录,并执行编译
            cd /usr/src/freeswitch-1.6.19/src/mod/endpoints/mod_g729
            make
            编译时如果提示找不到头文件,可以将FreeSWITCH源码include目录下的对应头文件复制到
            ../mod_g729/bcg729/include/目录,还有其他找不到的头文件可以使用find命令
            在FreeSWITCH源码目录下搜索,然后复制到../mod_g729/bcg729/include/目录,然后再重新编译
2.7 编译完成后,将mod_bcg729.so复制到FreeSWITCH的库目录,也可以直接替换FreeSWITCH的库目录下的G729库文件
            cp mod_bcg729.so /usr/lib/freeswitch/mod/
2.8 修改/etc/freeswitch/vars.xml
            <X-PRE-PROCESS cmd="set" data="global_codec_prefs=G729,OPUS,G722,PCMU,PCMA,VP8"/>
            <X-PRE-PROCESS cmd="set" data="outbound_codec_prefs=G729,OPUS,G722,PCMU,PCMA,VP8"/>
            <X-PRE-PROCESS cmd="set" data="media_mix_inbound_outbound_codecs=true"/>
          
2.9 配置/etc/freeswitch/sip_profile/internal.xml
            <param name="disable-transcoding" value="false"/>注释或者写成false,这行直接代表freeswitch是否开启转码功能
            <param name=”inbound-late-negotiation” value=”false”/>
            <param name=”inbound-zrtp-passthru” value=”false”/>
2.10 配置/etc/freeswitch/autoload_configs/modules.conf.xml启动自动加载mod_bcg729
            <load module="mod_bcg729"/>
3.重启FreeSWITCH
     service freeswitch restart
     或者也可以进入FreeSWITCH控制界面,命令加载mod_bcg729模块
     fs_cli
     unload mod_g729
     load mod_bcg729

    至此就配置完成了

<think>问题分析: 用户的问题是关于FreeSWITCH的SDP协商问题,具体是限制了SDP只携带G729编码器,但外部电话打进来时返回488(不可接受)错误。 可能的原因: 1. 对方不支持G729编码器:488错误表示对方拒绝了我们的SDP,因为我们的SDP中只包含G729,而对方可能不支持G729。 2. 编码器协商问题:即使FreeSWITCH加载了mod_g729,但可能由于某些原因,在协商时没有正确使用。 3. 媒体设置问题:可能在FreeSWITCH配置中,要求了G729,但对方不支持,而FreeSWITCH又没有提供其他编码器,导致协商失败。 解决思路: 1. 检查呼入的呼叫配置,确保在呼入时允许使用G729,同时也要考虑备用编码器,因为不是所有终端都支持G729。 2. 检查FreeSWITCH的全局编码设置和域(domain)的编码设置,确保G729被正确启用,并且优先级设置正确。 3. 检查SDP中的G729格式是否正确,包括payload type等。 步骤: 1. 检查全局编码设置:在FreeSWITCH中,使用`show codec`命令确认G729确实被加载并且可用。 2. 检查拨号计划(dialplan)中对于呼入呼叫的编码设置。可能需要在呼入时设置`absolute_codec_string`为G729,但也要考虑添加备用编码器(如PCMA/PCMU)以增加兼容性。 3. 检查SDP中的编码器列表:使用Wireshark抓包,查看INVITE消息中的SDP部分,确认FreeSWITCH发送的SDP中是否只包含G729,以及对方回复的488错误中是否包含对方支持的编码器。 配置修改建议: 如果对方不支持G729,那么我们需要在FreeSWITCH的呼入配置中添加其他编码器。例如,在拨号计划中设置多个编码器: 在拨号计划的context中,设置: <action application="set" data="absolute_codec_string=PCMA, PCMU, G729"/> 这样,FreeSWITCH会优先使用PCMA,然后是PCMU,最后是G729。这样即使对方不支持G729,也可以使用PCMA或PCMU。 但是,用户要求只携带G729,这可能是特殊需求(比如为了节省带宽)。如果必须只使用G729,那么需要确保对方支持G729。 如果对方支持G729,但仍然返回488,那么可能是其他原因,比如: - 媒体端口问题:防火墙阻止了媒体流。 - SDP中的其他属性问题,如ptime、媒体地址等。 另一种方法:在FreeSWITCH中,可以设置强制使用G729,但允许转码。这需要FreeSWITCH有足够的CPU资源进行转码,并且配置转码。例如,在拨号计划中: <action application="set" data="bypass_media=true"/> <!-- 如果不需要媒体绕过 --> <action application="set" data="absolute_codec_string=G729"/> <action application="set" data="media_webrtc=false"/> <action application="set" data="bridge_early_media=true"/> <action application="bridge" data="{absolute_codec_string=G729}sofia/gateway/..."/> 但注意,转码会增加服务器负担。 代码示例(配置修改): 以下是一个拨号计划的示例,设置多个编码器以增加兼容性,但优先使用G729,如果对方不支持则使用其他编码器: 在拨号计划中(如default.xml): ```xml <extension name="incoming_call"> <condition field="destination_number" expression="^(\d+)$"> <action application="set" data="absolute_codec_string=G729,PCMA,PCMU"/> <!-- 其他操作,如桥接 --> <action application="bridge" data="user/${dialed_extension}@${domain}"/> </condition> </extension> ``` 但是,如果用户要求必须只使用G729,那么需要确保对方支持G729。如果对方不支持,那么呼叫就会失败。因此,只携带G729的风险就是兼容性问题。 另外,检查mod_g729是否安装正确。在FreeSWITCH控制台执行: load mod_g729 show codec 应该能看到G729在列表中。 如果问题仍然存在,可以尝试在SIP Profile中设置negotiate_codec为true(默认就是true),并检查SIP Profile的其他设置。 总结: 488错误通常是由于SDP中的媒体属性(编码器)不被对方支持。因此,解决方案是: - 添加备用编码器(推荐,除非有特殊原因必须只用G729) - 确保对方支持G729(如果必须只用G729) 如果必须只用G729,那么需要和对方确认其支持G729,并且检查SDP中的G729格式是否正确(例如,payload type是否匹配)。 相关问题: 根据用户的问题,提出以下相关问题:</think>### 问题分析 当 FreeSWITCH 限制 SDP 只携带 G.729 编码器却返回 488 错误时,通常是由于以下原因: 1. **对方终端不支持 G.729** 2. **G.729 许可或加载问题** 3. **SDP 协商配置错误** 4. **媒体路径问题** ### 解决方案 以下是关键排查步骤和配置修改: #### 1. 验证 G.729 支持状态 在 `fs_cli` 中执行: ```bash show codec ``` 检查输出是否包含 `G729`(如 `G729a` 或 `G729b`)。正常输出示例: ``` type,name,ikey codec, G729, G729 ``` #### 2. 检查 G.729 许可 G.729 需要商业许可。在 `fs_cli` 中运行: ```bash g729_license ``` 如果返回 `-ERR no reply` 或未显示有效许可,需[购买许可证](https://www.signalwire.com/products/g729)。 #### 3. 配置 SDP 强制使用 G.729 修改 SIP Profile(如 `internal.xml`): ```xml <param name="inbound-codec-negotiation" value="generous"/> <!-- 关键参数 --> <param name="disable-transcoding" value="false"/> <!-- 允许转码 --> <param name="absolute-codec-string" value="G729"/> <!-- 强制G729 --> ``` #### 4. 抓包分析 SDP 协商 用 Wireshark 抓包检查: - **INVITE 请求**:是否携带 `a=rtpmap:18 G729/8000` - **488 响应**:查看 `Warning` 头字段,确认对方拒绝原因 #### 5. 测试媒体路径 在拨号计划中添加媒体测试: ```xml <action application="answer"/> <action application="playback" data="silence_stream://3000"/> <!-- 测试3秒媒体 --> ``` 如果播放失败,说明媒体路径问题(防火墙/NAT)。 #### 6. 关键日志检查 在 `freeswitch.log` 中搜索: ```log grep -i "g729" /var/log/freeswitch/freeswitch.log grep -i "488" /var/log/freeswitch/freeswitch.log ``` 常见错误日志: ```log [WARNING] mod_dptools: Codec G729 not found # G729未加载 [ERR] switch_core_media.c: No compatible codec! # 编码器不兼容 ``` ### 完整配置示例 **拨号计划 (`conf/dialplan/default.xml`)**: ```xml <extension name="force_g729"> <condition field="destination_number" expression="^.*$"> <action application="set" data="absolute_codec_string=G729"/> <action application="bridge" data="user/1000"/> </condition> </extension> ``` **SIP Profile (`conf/sip_profiles/internal.xml`)**: ```xml <profile name="internal"> <!-- 关键参数 --> <param name="inbound-codec-negotiation" value="generous"/> <param name="disable-transcoding" value="false"/> <param name="rtp-ip" value="$${local_ip_v4}"/> </profile> ``` ### 根本原因总结 | 原因 | 解决措施 | |---------------------|----------------------------------| | 对方不支持 G.729 | 添加转码或备用编码器 | | G.729 许可无效 | 购买官方许可证 | | SDP 协商模式错误 | 设置 `inbound-codec-negotiation=generous` | | 媒体端口阻塞 | 检查防火墙/UDP 端口(16384-32768)| ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值