首页 > 其他分享 >freeswitch笔记(9)-esl outbound中如何放音采集按键?

freeswitch笔记(9)-esl outbound中如何放音采集按键?

时间:2023-02-07 18:24:05浏览次数:61  
标签:outbound new client org freeswitch import esl

关于这个功能,esl-client 上给出的源码示例极具误导性,根本跑不起来,见: https://github.com/esl-client/esl-client/blob/master/src/test/java/OutboundTest.java

 

正确姿势:必须在事件订阅的回调里,才能拿到用户按键值

 

示例代码:

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 package org.freeswitch.esl.client;   import org.freeswitch.esl.client.dptools.Execute; import org.freeswitch.esl.client.dptools.ExecuteException; import org.freeswitch.esl.client.internal.Context; import org.freeswitch.esl.client.outbound.IClientHandler; import org.freeswitch.esl.client.outbound.IClientHandlerFactory; import org.freeswitch.esl.client.outbound.SocketClient; import org.freeswitch.esl.client.transport.event.EslEvent; import org.freeswitch.esl.client.transport.message.EslHeaders.Name; import org.freeswitch.esl.client.transport.message.EslMessage; import org.slf4j.Logger; import org.slf4j.LoggerFactory;   import java.net.InetSocketAddress; import java.util.regex.Pattern;   import static com.google.common.base.Throwables.throwIfUnchecked;   public class OutboundDTMFTest {     private static Logger logger = LoggerFactory.getLogger(OutboundDTMFTest.class);     private static String sb = "/usr/local/freeswitch/sounds/en/us/callie/ivr/8000/";     String prompt = sb + "ivr-please_enter_extension_followed_by_pound.wav";     String failed = sb + "ivr-that_was_an_invalid_entry.wav";       public static void main(String[] args) {         new OutboundDTMFTest();     }       public OutboundDTMFTest() {         try {             //outbound test             final SocketClient outboundServer = new SocketClient(                     new InetSocketAddress("localhost"8086),                     new OutboundHandlerFactory());             outboundServer.startAsync();         catch (Throwable t) {             throwIfUnchecked(t);         }     }             public class OutboundHandlerFactory implements IClientHandlerFactory {           @Override         public IClientHandler createClientHandler() {             //just for sample , recommend use singleton pattern, to avoid new too many instance             return new OutboundHandler();         }     }         public class OutboundHandler implements IClientHandler {           StringBuffer buffer = new StringBuffer(10);         String pattern1 = "^\\d+";         String pattern2 = "^\\d+#$";           @Override         public void onConnect(Context context, EslEvent eslEvent) {             try {                 Execute exe = new Execute(context, "");                   //订阅DTMF事件                 EslMessage eslMessage = context.sendCommand("event plain DTMF");                 if (eslMessage.getHeaderValue(Name.REPLY_TEXT).startsWith("+OK")) {                     logger.info("subscribe event success!");                 }                   exe.answer();                   int timeOutSeconds = 30;                   //放音采集                 exe.playAndGetDigits(1,                         110, timeOutSeconds * 1000"#", prompt,                         failed, pattern1, timeOutSeconds * 1000);                   //等待用户输入按键                 long start = System.currentTimeMillis();                 while (true) {                     if (System.currentTimeMillis() - start > timeOutSeconds * 1000) {                         break;                     }                       if (buffer.length() > 0 && Pattern.matches(pattern2, buffer.toString())) {                         break;                     }                       Thread.sleep(50);                 }                   System.out.println("you pressed:" + buffer.toString());               catch (ExecuteException | InterruptedException e) {                 logger.error("Could not prompt for digits", e);             finally {                 context.closeChannel();             }           }           @Override         public void onEslEvent(Context ctx, EslEvent event) { //            System.out.println(event.getEventName());             if (event.getEventName().equalsIgnoreCase("DTMF")) {                 String key = event.getEventHeaders().get("DTMF-Digit");                 if ("#".equalsIgnoreCase(key)) {                     //检查是否输入正确(如果错误,请将之前输入的清空掉)                     if (!Pattern.matches(pattern1, buffer.toString())) {                         buffer.setLength(0);                         return;                     }                 }                 buffer.append(key);             }         }     } }

解释一下:

1. 首先要订阅DTMF事件,只有在事件回调里,才能拿到用户按键信息

2. playAndGetDigits 在outbound async full异步模式下,这个方法的返回值,其实没啥用,永远都是__undef__,所以要在后面循环检测结果,还要考虑用户一直不按键的情况,要有超时保底

3. 事件回调onEslEvent与用户进线onConnect是在2个不同的方法中,但是都是在同一个线程里的,所以为方便起见,用了一个线程安全的StringBuffer用来保存按键信息

4. 事件回调中,要考虑用户按错键的情况,比如提示用户按数字键,然后用户输入了字母或星号之类的,遇到这种要把之前的输入结果清掉。

标签:outbound,new,client,org,freeswitch,import,esl
From: https://www.cnblogs.com/kn-zheng/p/17099407.html

相关文章

  • freeswitch笔记(8)-esl outbound 填坑笔记
    github上的esl-client已经N年未更新了,上面有一堆bug,记录一下: 一、内存泄露org.freeswitch.esl.client.transport.message.EslFrameDecoder这个类,使用了netty的ByteBuf......
  • freeswitch笔记(7)-放音控制
    来电时,播放音乐是一个很常用的功能,下面是一些相关的命令:一、单次播放playback1originateuser/1000 &playback(ivr/8000/ivr-welcome_to_freeswitch.wav)......
  • freeswitch笔记(6)-会议功能简介
    电话会议是一个常用功能,freeswitch当然支持,下面是基本用法:一、发起会议1conference test bgdialuser/1004上面的命令表示,发起1个名为test的会话,......
  • freeswitch笔记(5)-小型呼叫中心设计思路
    这一篇用esl实战一把,利用eslclient来实现一个小型呼叫中心的原型,先看看下面这张图: 企业通常会对外公布一个400之类的服务电话,当用户拨打这个电话时,实际上背后是一堆客......
  • freeswitch笔记(4)-esl inbound模式的重连及内存泄露问题
    eslinboundclient,内部有一个canSend()方法:123publicbooleancanSend(){    return channel!=null&&channel.isConnected()&&authenticated......
  • FreeSwitch:send_dtmf/uuid_send_dtmf发送按键注意事项
    很多时候我们打电话到公司前台,会听到类似“欢迎致电XXX,办公电话请直拨分机,咨询XX请按1,咨询YY请按2”这样的语音提示。在一些特定流程中,系统自动发起呼叫打到前台,希望实现自......
  • freeswitch批量添加用户
    默认情况下,freeswitch内置了1000-1019这20个用户,如果需要添加更多用户,可以按如下步骤操作:一、复制用户文件\FreeSWITCH\conf\directory\default 下有1000.xml~1019.xm......
  • freeswitch: 如何指定主叫显示号码
    一、origiante时指定主叫号码正常情况下,如果在freeswitch控制台,输入类似下面 命令:originateuser/1000 &park被叫收到振铃提示时,显示的号码类似下面......
  • ESL中如何自定义事件及自定义事件的监听
    虽然freeswitch已经内置了一些标识的事件,比如:CHANNEL_CREATE(发起呼叫时触发),CHANNEL_HANGUP_COMPLETE(电话挂断时触发)...,但是有时候我们想根据业务需求,新增一些自定义的事......
  • .eslintrc.js文件内容/配置eslint/eslint参数
    首先放一个官网的链接​​​​​​Listofavailablerules-ESLint中文文档然后直接上代码这里以vue项目为例,主要两个文件,1是.eslintrc.js文件(配置),2是.eslintignore(忽......