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_onlyfind_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 TCP
  • sofia/public/1860535xxxx@192.168.1.1:2345;transport=tls TLS

TTS 和 ASR

TTS 和 ASR 是人工智能必要的组成部分。XCC 集成了市面上大部分的公有云接口。

TTS 参数

  • engine:引擎名称。跟实现有关,目前可用的有alihuaweibaiduifly等。
  • voice:嗓音,跟具体引擎有关,可传入default,或查找相关引擎提供的嗓音值。

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:是否加标点,字符串truefalse
  • vad-mode:VAD 模式,VENDORNATIVE0 ~ 3等。

ali 相关参数

huawei 相关参数

文档:https://support.huaweicloud.com/api-sis/sis_03_0111.html

XCC Detect

原生 FreeSWITCH 实现的接口中,每个检测都需要起单独的线程,而且通过 Event 方式传递文本的消息,不利于控制。另外,原生的 FreeSWITCH 使用轮循、忙等待的方式检查有没有识别结果,效率不高,状态机特别复杂。

XCC 重新实现了语言检测接口,基本上还是使用原来的模块接口,但不再需要忙等待方式提供检测结果,而是直接将检测到的结果推到当前 Session 的消息处理队列中,实现更高效。

新接口接受 JSON 格式的参数输入,比 FreeSWITCH 原生接口更清晰、方便。

XCC 接口与原来的接口兼容,由于历史原因,在mod_huaweimod_ali中还保留了 FreeSWITCH 原生接口的状态机。新的模块中无需再实现这一复杂的状态机。有利于简化代码,提高效率。

媒体文件

在使用 Play 播放文件时,data参数支持如下文件类型:

音视频文件

  • 绝对路径:如/tmp/test.wav
  • HTTP 文件:如http://example.com/test.wav,支持httphttps
  • 静音:如: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。也支持相对大小,如5vw5vh,等,其中一个vwvh分别为图像宽度和高度的百分之一。
  • 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_dispositionSIP 相关
context呼叫源
duration总时长
end_stamp结束时间
uuid通话 UUID
bleg_uuidB 腿 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_MISSINGSIP 消息不全
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

参考资料

开发指南