在Asterisk PBX中能否原生实现SendDTMF与DTMF检测并行执行?
在Asterisk PBX中实现DTMF双向并行收发的原生方案
问题描述
我正在Asterisk PBX中实现一个基于DTMF信号的远程设备双向通信协议,需要在同一信道上无干扰地同时发送DTMF音并接收/解析传入的DTMF。
按顺序执行拨号计划会存在核心问题:
exten => s,n,SendDTMF(1) ; 发送DTMF期间无法监听,可能错过传入的信号 exten => s,n,Read(Input,,4) ; 仅在发送完成后才开始读取DTMF
目前已知原生Read()应用没有支持"监听时并行传输DTMF"的变体。我暂时用AGI Python脚本生成含指定DTMF序列的临时WAV文件,将其作为Read(result,file, ...)的第二个参数来实现,但希望找到更简洁的原生方案。
请问是否存在无需AGI/外部脚本的原生拨号计划方案,可实现真正的SendDTMF() + DTMF检测并行执行?
原生解决方案
有两种无需依赖外部工具的原生方案可以实现DTMF收发并行:
1. 利用Background()实现并行播放与监听
Background()应用的核心特性是播放音频的同时持续监听信道上的DTMF输入,完全适配你的需求:
- 提前用
DTMF2WAV工具生成对应目标DTMF序列的WAV文件(例如dtmf_seq_1.wav对应发送DTMF"1") - 在拨号计划中调用:
exten => s,n,Background(dtmf_seq_1) exten => s,n,Set(ReceivedDTMF=${DTMF_RECEIVED})
Background()播放音频时会自动捕获所有传入的DTMF信号,并将其存入DTMF_RECEIVED变量,播放结束后直接读取该变量即可获取期间收到的DTMF内容。
2. 异步SendDTMF结合实时DTMF监控(Asterisk 16+)
如果你的Asterisk版本在16及以上,可以利用SendDTMF的异步参数配合信道DTMF监控实现:
exten => s,n,Set(CHANNEL(dtmfmode)=rfc2833) ; 配置为RFC2833模式,避免音频DTMF干扰 exten => s,n,Set(CHANNEL(monitor_dtmf)=yes) ; 启用实时DTMF捕获 exten => s,n,SendDTMF(1,,a) ; 追加"a"参数开启异步发送,发送期间不阻塞信道 exten => s,n,Wait(2) ; 等待时长匹配DTMF发送的总时长 exten => s,n,Set(ReceivedDTMF=${MONITOR_DTMF})
异步发送DTMF的过程中,信道会持续监听并捕获传入的DTMF,结果会存入MONITOR_DTMF变量,等待结束后即可读取。
内容的提问来源于stack exchange,提问作者EPSG31468




