XCC API
附录
常见问题解答(FAQ)
XSwitch 是否可以支持单机版使用?
带 XUI 的 XSwitch 本身设计是简单易用,支持单机版单租户
XSwitch 是否支持集群?
支持,只是带 XUI 的版本在界面上有些限制。
XSwitch 是否支持双机热备?
是的。参见 https://docs.xswitch.cn/dev/xcc-api/cluster/#ha。
XSwitch 是否支持 Lua?
XSWitch 支持原生 FreeSWITCH 支持的所有能力,包括 Lua。事实上,XSwitch 的后台的 Rest API 全部使用 Lua 开发的。
XSwitch 是否支持 ESL?
XSWitch 支持原生 FreeSWITCH 支持的所有能力,包括 ESL。
XSwitch 底层使用了 XML 动态绑定,是否支持还其它的绑定?
XSwitch 同时支持多种 XML 绑定,但是顺序不好控制,必要时,可以禁用 XSwitch 内置的绑定。
在使用 XCC API 进行开发时,最好使用哪种语言?
我们推荐使用 Go 语言,但实际上你应该使用你最擅长的语言,详见我该使用什么语言开发。
为什么不提供 Java SDK?
每个人的应用场景和调用习惯不同,我们相信直接使用 NATS 接口能最大限度的给你自由,详见我该使用什么语言开发。
呼叫字符串
FreeSWITCH 原生的呼叫字符串。
本地分机
分机注册到 FreeSWITCH,FreeSWITCH 可以直接呼叫。
user/分机号
多注册支持
系统支持多注册,也可以同时呼叫多个分机。
多个 SIP 客户端注册同一分机号
如果多个 SIP 分机注册到 FreeSWITCH 或 XSwitch,在 SIP Profile 中开启multiple-registration
的情况下,多个 SIP 分机可以同振。使用 SIP 协议的 WebRTC 分机(如 sip.js 实现的分机)默认与普通 SIP 分机行为相同。
SIP 分机和 WebRTC 分机
在原生 FreeSWITCH 中,SIP 分机和 WebRTC(Verto)分机默认同振。
在 XSwitch 中,如果分机类型为 SIP,则仅振铃 SIP 分机,如果分机类型为 WebRTC,则 SIP 分机和 WebRTC(Verto)分机同振。
顺振支持
如果要支持顺振,可以在CallParams.Params
中增加find_sip_device_only
和find_webrtc_device_only
参数,构造两个 CallParam,然后在Destination
中指定ringall: false
(即顺振)。
通过 IP 呼出
直接通过 IP 白名单方式对接。对方需要对 FreeSWITCH 开通 IP 白名单。具体的 IP 和端口号跟 FreeSWITCH 侧的 SIP 配置有关。
sofia/public/号码@ip:port
如果使用 TCP 或 TLS 链路,可以添加参数
sofia/public/号码@ip:port;transport=tcp
通过网关呼出
在 FreeSWITCH 侧可以配置一个网关,网关可以以注册或非注册方式与对端对接。对端需要提供至少以下信息:
realm
: 域名或 IP 地址username
: 用户名password
: 密码
具体网关名称需要在 FreeSWITCH 侧配置。
格式:
sofia/gateway/网关名称/被叫号码
示例
user/1000
呼叫本地用户user/1001
sofia/public/1860535xxxx@192.168.1.1
默认端口为5060
sofia/public/1860535xxxx@192.168.1.1:2345
:指定端口sofia/public/1860535xxxx@192.168.1.1:2345;transport=tcp
TCPsofia/public/1860535xxxx@192.168.1.1:2345;transport=tls
TLS
TTS 和 ASR
TTS 和 ASR 是人工智能必要的组成部分。XCC 集成了市面上大部分的公有云接口。
TTS 参数
engine
:引擎名称。跟实现有关,目前可用的有ali
、huawei
、baidu
、ifly
等。voice
:嗓音,跟具体引擎有关,可传入default
,或查找相关引擎提供的嗓音值。
- 阿里 Voice 相关配置:https://help.aliyun.com/document_detail/84435.html
- 华为相关参数配置:https://support.huaweicloud.com/api-sis/sis_03_0111.html
ASR 参数
ASR 检测一个很关键的部分是 VAD(Voice Activity Detection),即首先要检测是否有人讲话,再去识别内容。以下图为例,横向为时间轴t
,纵向为语音波形。其中thresh
为语音检测阈值,即小于该值认为没有声音。该值在公有云连续识别时一般不用设置。如果使用 XSwitch 原生的 VAD,则需要设置。
_-_ .. ~~. thresh _-/ \_-^-_/ __ / \ thresh ---------/ \ / \ ---------------------- / \__/ \ ---------------------------|----------|----------|---------> t no-input| | | | |~~| | | | voice-ms_/ |Begin Speaking | | | |Speaking ... Partial ... Partial ... |End Speaking | | |silence-ms|silence-ms|End Speaking | | | | speech-timeout |End Speaking
- 如果在
no-input-timeout
内用户一直没有讲话,则会返回no-input
。 - 当开始检测到语音时,如果连续
voice-ms
时间检测到语音活动(~~
波浪线部分),则为认讲话开始。 - 在语音检测过程中可能会返回中间结果(Partial)。中间结果是不稳定的,当检测到更多内容时,ASR 引擎会根据语义理解等进行修正。
- 当语音强度低于阈值时,启动
silence-ms
计数,超时后认为讲话结束。如果在超时前又检测到强度回升,则继续检测。 - 直到检测到语音强度低于阈值越过
silence-ms
时,认为讲话结束,返回最终结果。
打断
默认情况下,ASR 返回结果会“打断”当前的放音(如果还没有播放完的话),nobreak
参数可以控制是否打断。
有时候,用户程序希望能根据识别的结果进行条件打断,可以使用offset
参数实现。识别结果中返回的offset
为当前播放的文件被打断的位置。下一次调用时使用该offset
可以从该offset
位置开始播放。目前仅对文件类型的播放有效,尚不支持 TTS。
通用参数
以下参数在所有引擎中通用。注意,这些是引擎原始参数,值为字符串类型,如在 DetectSpeech 接口中应该放到params
中。
no-input-timeout
:毫秒,未检测到语音超时,通常为2000-10000
。speech-timeout
:毫秒,讲话超时。从检测到讲话开始算,或者从放完音开始算。通常大于2000
,小于60000
。voice-ms
:毫秒,连续检测到语音时长,通常为20-100
。silence-ms
:毫秒,尾部静音时长,通常为800-2000
。engine
:引擎名称partial
:是否产生中间结果add-punct
:是否加标点,字符串true
或false
。vad-mode
:VAD 模式,VENDOR
、NATIVE
、0 ~ 3
等。
ali 相关参数
segment-recording-prefix
:分段录音前缀(路径),如果不设置则禁用分段录音。disable-engine-data
:不发送 ASR 引擎返回的原始数据。- 文档:https://help.aliyun.com/document_detail/84435.html
huawei 相关参数
文档:https://support.huaweicloud.com/api-sis/sis_03_0111.html
XCC Detect
原生 FreeSWITCH 实现的接口中,每个检测都需要起单独的线程,而且通过 Event 方式传递文本的消息,不利于控制。另外,原生的 FreeSWITCH 使用轮循、忙等待的方式检查有没有识别结果,效率不高,状态机特别复杂。
XCC 重新实现了语言检测接口,基本上还是使用原来的模块接口,但不再需要忙等待方式提供检测结果,而是直接将检测到的结果推到当前 Session 的消息处理队列中,实现更高效。
新接口接受 JSON 格式的参数输入,比 FreeSWITCH 原生接口更清晰、方便。
XCC 接口与原来的接口兼容,由于历史原因,在mod_huawei
和mod_ali
中还保留了 FreeSWITCH 原生接口的状态机。新的模块中无需再实现这一复杂的状态机。有利于简化代码,提高效率。
媒体文件
在使用 Play 播放文件时,data
参数支持如下文件类型:
音视频文件
- 绝对路径:如
/tmp/test.wav
。 - HTTP 文件:如
http://example.com/test.wav
,支持http
和https
。 - 静音:如:
silence_stream://3000
,其中 3000 为表单的毫秒数。 - 铃音:TGML 约定的铃音,如
tone_stream://%(1000,4000,450)
为中国回铃音。详情参见: https://freeswitch.org/confluence/display/FREESWITCH/TGML - 多文件拼接:使用英文
!
分隔(文件名中不能有!
),如file_string:///tmp/1.wav!/tmp/2.wav
系统支持以下文件类型:
.wav
.mp3
.mp4
.mkv
.m4a
.mov
.webm
支持以下协议:
http
rtmp
rtmps
rtsp
图片文件
可以把 PNG 文件当成视频文件用。如:/tmp/test.png
。文件路径前可以加参数,如{png_ms=10000}/tmp/test.png
表示播放10
秒。支持的参数列表如下:
png_ms
:时长,毫秒audio_file
:音频文件路径png_fps
:帧率,默认为5
alpha
:是否支持 Alpha 通道text
:文本,可以以 TTS 方式播放,但需要提供下列参数tts_engine
:TTS 引擎tts_voice
:TTS 发音人dtext
:显示文本fg
:显示文本前景色,Web 格式,如#FFFFFF
。bg
:显示文件背景色,Web 格式,如#000000
,支持透明度(Alpha Channel),如#00000020
。size
:字体大小,像素值,如24
。也支持相对大小,如5vw
、5vh
,等,其中一个vw
或vh
分别为图像宽度和高度的百分之一。scale_w
:缩放图像宽度,像素scale_h
:缩放图像高度,像素
特殊文件,可以直接在内存中生成图片,如:{png_ms=10000,fg=#ffffff,bg=#0000ff,scale_w=1280,scale_h=720}/.png
。
除 PNG 外,还支持以下扩展名的文件:
*.jpg
*.jpeg
*.bmp
通过 Go 语言生成呼叫字符串和文件字符串
在 Go 语言 SDK 中有一个 FSDS 工具可以帮助生成相应的呼叫字符串和文件字符串。FSDS 指 FreeSWITCH Dial String,亦指 File String and Dial String,用于格式化生成文件字符串和叫叫字符串。详情参见:https://git.xswitch.cn/xswitch/xctrl/src/branch/master/docs/fsds.md ,下面是几个示例。
呼叫字符串生成示例
生成 user
呼叫字符串:
endpoint := fsds.User{ Endpoint: &fsds.Endpoint{ FSDS: &fsds.FSDS{ Params: map[string]string{"param1": "value1", "param2": "value2"}, CallerIDName: "test1", CallerIDNumber: "test2", }, Type: "sofia", Dest: "1234", }, Domain: "domain", } callString := u.String()
输出结果:
{param1=value1,param2=value2,caller_id_name=test1,caller_id_number=test2}sofia/1234@domain
文件字符串生成
PNG 文件:
file := &fsds.File{ FSDS: &fsds.FSDS{ Params: map[string]string{ "png_ms": "20000", "dtext": "请输入会议号", }, }, Path: "/tmp/test.jpg", } fileString := file.String()
输出结果:
{png_ms=20000,dtext=请输入会议号}/tmp/test.jpg
CDR 相关说明
默认 XCC-CDR 字段说明
话单字段 | 中文说明 |
---|---|
caller_id_name | 主叫名称 |
start_stamp | 开始时间 |
billsec | 计费时长 |
account_code | 计费号码 |
network_addr | 网络地址 |
abs_path | 录音文件绝对路径 |
answer_stamp | 应答时间 |
sip_hangup_disposition | SIP 相关 |
context | 呼叫源 |
duration | 总时长 |
end_stamp | 结束时间 |
uuid | 通话 UUID |
bleg_uuid | B 腿 UUID |
direction | 方向,inbound 为向内,outbound 向外 |
destination_number | 被叫号码 |
network_port | 网络端口 |
realm | 域 |
caller_id_number | 主叫号码 |
hangup_cause | 挂机原因 |
常用挂机原因说明
挂机原因 | 中文说明 |
---|---|
ORIGINATOR_CANCEL | 主叫挂机 |
NORMAL_CLEARING | 正常释放 |
NORMAL_TEMPORARY_FAILURE | 临时故障 |
WRONG_CALL_STATE | 呼叫状态异常 |
USER_BUSY | 用户忙 |
LOSE_RACE | 别处应答 |
MEDIA_TIMEOUT | 媒体超时 |
CALL_REJECTED | 拒绝呼叫 |
UNALLOCATED_NUMBER | 空号 |
NO_ROUTE_DESTINATION | 无法路由 |
NO_USER_RESPONSE | 久叫不应 |
NO_ANSWER | 无应答 |
NORMAL_UNSPECIFIED | 未定义 |
NETWORK_OUT_OF_ORDER | 网络异常 |
RECOVERY_ON_TIMER_EXPIRE | 呼叫超时 |
USER_NOT_REGISTERED | 用户未注册 |
SUBSCRIBER_ABSENT | 用户缺席 |
GATEWAY_DOWN | 网关故障 |
MANDATORY_IE_MISSING | SIP 消息不全 |
SYSTEM_SHUTDOWN | 系统关机 |
INCOMPATIBLE_DESTINATION | 目的地不兼容 |
EXCHANGE_ROUTING_ERROR | 交换路由错误 |
MANAGER_REQUEST | 强制挂机 |
DESTINATION_OUT_OF_ORDER | 目的地异常 |
SERVICE_NOT_IMPLEMENTED | 服务未实现 |
常用挂机原因说明:https://freeswitch.org/confluence/display/FREESWITCH/Hangup+Cause+Code+Table
参考资料
- 如何在 XSwitch 中使用 XCC API:https://docs.xswitch.cn/howto/xcc
- XSwitch 相关文档:https://git.xswitch.cn/xswitch/docs
- 示例代码:https://git.xswitch.cn/xswitch/xcc-examples
- Go 语言 SDK:https://git.xswitch.cn/xswitch/xctrl