FreeSWITCH在呼叫失败的情况下播放语音提示

看到好多网友问到这个问题。一般我们在打电话时会听到“您拨的电话正在通话中,请稍后再拨....”,或“电话无应答...”之类的提示,我们在 freeswitch 里也可以这样做。

其实很简单,默认的配置在呼叫失败时会转到 voicemail (语音信箱),我们只需要在这里修改,让他播放一个语音提示,然后再进入语音信箱(或直接挂 断也行)。

找到 <extension name="Local_Extension">部分的最后几行

<action application="bridge" data="user/${dialed_extension}@${domain_name}"/>

<action application="answer"/>

<action application="sleep" data="1000"/>

<action application="bridge" data="loopback/app=voicemail:default ${domain_name} ${dialed_extension}"/>

其中,第一个 bridge 是说明去呼叫被叫号码,如果呼叫失败,则 dialplan 继续往下走,依次是

应答

睡一会

进入 voicemail

OK, 我们只需要把最后一个bridge那行改成

<action application="playback" data="${originate_disposition}.wav"/>

重新打电话试一下吧,如果被叫忙,则 originate_disposition 变量就是 USER_BUSY ,用户没注册就是 USER_NOT_REGISTERED 之类的,你只需要保证相关目录下有相对应的声音文件即可(如果LOG中提示找不到声音文件的话试试自己录一个)。

当然,呼不通的原因可能有很多,你总不可能录上所有的声音文件是吧,有两种方法:

1) 使用一个 lua (或其它语言) 的脚本

<action appliction="lua" data="/tmp/xxx.lua"/>

在 lua 脚本中可以拿到这个 originate_disposition 变量,从而可以使用 if then else 之类的逻辑播放各种声音文件。

2) 当然,如果你脚本也不想编辑的话,实现上 FreeSWITCH 的 dialplan 功能是非常强大的,你只需要将呼叫转到播放不同声音文件的 dialplan:

<action application="transfer" data="play-cause-${originate_disposition}"/>

然后创建如下 dialplan extension:

<condition field="destination_number" expression="^play-cause-USER_BUSY$"> <action application="playback" "/tmp/sounds/user-busy.wav"/> </condition>

<condition field="destination_number" expression="^play-cause-USER_NOT_REGISTERED$"> <action application="playback" "/tmp/sounds/user-not-registered.wav"/> </condition>

<condition field="destination_number" expression="^play-cause0(.*)$"> <!-- for all other reasons, play this file --> <action application="log" data="WARNING hangup cause: $1"/> <action application="playback" "/tmp/sounds/unknown-error.wav"/> </condition>

小结:

当然,能播放上面的声音文件还有一个前提,就是在第一个 bridge 前面要有以下两行:

<action application="set" data="hangup_after_bridge=true"/> <action application="set" data="continue_on_fail=true"/>

第一行的作用是,如果第一个 bridge 成功了,被叫挂断电话后我们就没有必要再播放该声音了,因此直接挂机。当然这一行可以没有,那么你在后面的 originate_disposition 里如果发现值是 "NORMAL_CLEARING" (正常挂机)的情况再决定是否播放相关语音。

第二行的作用是,如果呼叫失败(空号,拒接等),继续往下走,否则(值为 false 的情况)到这里就挂机了。该变量的值还可以有以下几种,表示只有遇到这几种情况才播放语音,其它的就直接挂机。

<action application="set" data="continue_on_fail=NORMAL_TEMPORARY_FAILURE,USER_BUSY,NO_ANSWER,TIMEOUT,NO_ROUTE_DESTINATION"/>

时间: 2024-08-13 22:12:24

FreeSWITCH在呼叫失败的情况下播放语音提示的相关文章

python3 在文件确实存在的情况下,运行提示找不到文件

提示 [Errno 2] No such file or directory: 但是路径下确实存在此文件,在不改动的情况下,再次运行,执行成功. 百思不得其解,看到此链接下的回答 http://bbs.csdn.net/topics/391934998?page=1 尝试使用 os.path.normpath() 替换os.path.join(),先记录待测试.

linux在telnet情况下root登录提示login incorrect

root登录时总是提示 login incorrect SSH可以登录 别的用户也可以通过telnet登录 唯独root不可以 解决方法: vi /etc/pam.d/login # auth requisite pam_securetty.so 注释这行 linux默认情况下root用户使用telnet是登录不了的,需要修改/etc/secrueety文件 可以把这个文件重命名或者加入pts/1之内的数据 如图 这样就可以在root情况下用telnet远程登录了 安装telnet 后,root

【Unity游戏开发之一】Time.timeScale=0暂停游戏的情况下播放动画

前提条件:在项目中用过Time.timeScale = 0来实现游戏暂停 问题: 暂停游戏后,暂停界面的按钮可能需要播放一个idle时的动画,Time.timeScale=0 会影响动画播放. 受Time.timeScale影响的因素: 1.物理模拟. FixedUpdate - 当Time.timeScale=0时,FixedUpdate 函数不会被执行. 2.Coroutines. - Time.timeScale=0 协程函数不会停止,但是会停止WaitForSeconds. 协成函数还是

IIS主机在某些情况下无法播放视频的设置方法

默认情况下,Windows Server的IIS主机是不支持FLV文件类型,通过http访问是无法播放视频. MIME类型就是设定某种扩展名的文件用一种应用程序来打开的方式类型,当该扩展名文件被访问的时候,浏览器会自动使用指定应用程序来打开. 设置MIME,让IIS支持更多文件类型. 在IIS中添加FLV的MIME类型: IIS里面的站点属性->http头->添加Mime类型 扩展名填写:.flv Mime类型填写:flv-application/octet-stream 重新启动该站点 其它

iOS开发——在不支持横屏情况下,实现播放器全屏播放

在使用MPMoviePlayerController实现播放器播放时,发现不能全屏播放,原来是因为项目不支持横屏,把支持横屏的选项勾住就OK啦,但是其他页面不支持横屏,这个方法就行不通了. 在网上找了很多的资料,很多都是在iOS 6之后就舍弃的,都没用,下面我就来介绍下,在不支持横屏的情况下,实现视频播放器的全屏播放. 1. 首先在AppDelegate.h 定义@property (nonatomic, assign) BOOL allowRotation; // 标记是否可以旋转 2. 同时

人在四种情况下容易失败

人在四种情况下容易失败: (1)没有自信 (2)发生意外事情 (3)环境很差 (4)身体不适 这四种情况背后最根本,共通东西就是不安情绪. 人在内心不安时候,容易看不清周围事物,让人在处理棘手问题过程中,失去冷静判断力. 这回导致缺乏目的的行为和疏忽大意的失误.接下来该做什么,就无法进行恰当判断了. 所谓不安,就是交感神经非常活跃,副交感神经完全没有动静的状态,是一种自主神经极端紊乱的状态. 通过静坐和有意识的进行慢慢呼吸,能够让自主神经功能稳定下来,应对各种情况变化. 人,真的很难保持淡定之心

C++对象模型——&quot;无继承&quot;情况下的对象构造(第五章)

5.2 继承体系下的对象构造 当定义一个object如下: T object; 时,实际上会发生什么事情呢?如果T有一个constructor(不论是由user提供或是由编译器合成),它会被调用.这很明显,比较不明显的是,constructor的调用真正伴随了什么? constructor可能内带大量的隐藏码,因为编译器会扩充每一个constructor,扩充程度视 class T的继承体系而定.一般而言,编译器所做的扩充操作大约如下: 1.记录在member initialization li

【性能测试】jmeter的坑(1)——如何在多网卡情况下正确连接

问题现象: 性能测试时,使用的服务器配置了双网卡,windows客户机配置了四网卡,坑爹的配置,内外网的隔离,导致在使用jmeter进行分布式测试的时候总是连接失败. 原因分析: Jmeter采用了rmi进行远程调用,在开启RMI服务时,如果服务端有多个网卡,它只是使用其中任意一个网卡,默认情况下,导致jmeter的controller机器和agent机器不在同一个网段内,无法互通,导致失败 解决方法: 我们要在多网卡的服务器上开启RMI服务的话必须指定IP,使他们能够在同一个网段内. 需要以下

spring 注解 事务,声明事务共存的情况下,先后顺序

最近在项目中,因为已配置全局声明式事务.不知道是否本来就配得有问题,导致一个多线程插入的方法会因为连接池不够用而导致失败. 就打算试试用注解式事务,然后发现不起作用,就想是不是嵌套事务的问题.然后找到这个哥们的文章,就解决了问题.这里转载一份 转载:http://blog.csdn.net/jeep_ouc/article/details/43056977 COME FROM 首先先看配置文件: <!-- hibernate --> <bean id="sessionFacto