信电助 - API开发接口文档
版本更新记录
2026.04.15 - V26.04.15
2025.02.12 - V1.12
2023.09.12 - V1.11
- 修改缓冲录音开始函数参数,增加回调函数地址参数
- 修改缓冲录音停止函数参数,增加回调函数模式时可以设置停止超时
2023.09.11 - V1.10
- 增加缓冲播放功能
- 增加缓冲录音功能
- 增加VAD检测功能
- 增加录音文件自动转文字功能
- 增加可以把自定义字符串写入设备作为软件加密狗功能
- 优化部分算法逻辑细节
1 前言
1.1 编写此文件目的
说明怎么样通过agicall-ub API控制信电助usb录音盒/语音盒,以便第三方bs/cs软件(如:CRM系统,办公软件等)在windows,linux,android和国产信创麒麟,统信uos系统下能更好利用该设备来进行通话录音,来电弹屏,软件拨号,语音转文字等功能
1.2 通用说明
- 以下提到的"PSTN"为公共电话交换网,也就为接在设备line口的线路
- 以下提到的话机/电话机为接在设备phone口的设备
- 以下提到的内线也就为接在line口的程控交换机线路
- 以下提到的PC为usb口插着信电助设备的电脑。
- 以下提到的参数类型:int64 - 有符号64bit(8字节);int32 - 有符号32bit(4字节);uint32 - 无符号32bit(4字节);int16 - 有符号16bit(2字节);uint16 - 无符号16bit(2字节)
- [in]表示输入参数,[out]表示输出参数,[in,out]表示输入输出参数
- 音量设置默认100,200放大一倍,50缩小一半,0静音,1000放大10倍
1.3 开发时需要注意的细节
- 本sdk使用保留的参数值时都必须使用0, 保留的字符参数为空字符,如:””
- 本sdk输入输出的字符串统一都使用 json格式,如果您还不熟悉json格式,请查阅相关文档
- 本sdk输入字符串如果需要汉字,需要和agi_ub_cfg.json里设置的”encoding”一致,请查阅agi_ub_cfg参数文档说明
- 本sdk输出字符串默认使用gbk编码格式,如果需要utf-8,请在创建事件通道时指定为utf-8编码输出,如:agi_ub_evt_create_json_pipe("", "", "utf-8")
- 本sdk函数非特殊说明返回0表示成功,其它表示失败,80000002表示未初始化sdk
- 本sdk需要保存输出字符的内存大小建议使用4096字节,特殊情况可以适当放大,建议在读取事件前先用api查询当前事件需要的内存长度,agi_ub_evt_get_json_buf_size查询后根据长度动态分配内存长度,如果查询事件时内存不够api会返回80000001错误
- 本sdk里的提到的设备账号就是设备的7-8位的纯数字序列号,不是设备guid,如果设备账号用 “sndcard” 表示计算机的声卡设备
- 本sdk里提到的 ERR_NO 表示 0
1.4 安装驱动
方式一:
插入设备,windows会提示有新硬件插入,根据windows向导选择agi_ub\install-ub\win-driver\driverfile\TelmateWDM.INF驱动。
方式二:
插入设备,windows会提示有新硬件插入,取消该窗口,使用管理员身份执行开发包agi_ub\install-ub\win-driver\driverfile\installdrv.exe按提示安装。
备注:
当安装好驱动后,如果在主机换USB口后如果windows提示有新硬件插入,需要重新安装,一般安装设备换usb口是不需要重新安装驱动
linux或者国产系统下只需要使用管理员执行linux驱动包的agi-ub-access.sh来授权usb设备读写权限
安装信创电话助手时会自动安装驱动,不需要再手动安装
2 接口函数
2.1 基础功能类
2.1.1 获取sdk库版本
| 函数名 |
agi_ub_version |
| 功能描述 |
返回sdk库版本的json信息. 任何时候都可以调用该api获取sdk版本号 |
| 函数原型 |
int32 agi_ub_version(char *out_json_buf, int32 buf_size); |
| 返回值 |
0表示成功,其它表示失败 |
| 参数描述 |
| out_json_buf | [out] 指定需要保存返回json字符串的缓冲地址,使用前先分配好内存 |
| buf_size | [in] 指定out_json_buf已经分配好的内存的大小 |
|
| 相关函数 |
|
| 示例 |
|
2.1.2 初始化全局资源
| 函数名 |
agi_ub_init |
| 功能描述 |
初始化SDK全局资源,只需要在启动程序时启动一次 |
| 函数原型 |
int32 agi_ub_init(const char *in_json_param) |
| 返回值 |
0表示成功,其它表示失败, 返回 80000000 表示已经初始化过了 |
| 参数描述 |
| in_json_param | [in] 指定需要输入的json参数 - 保留 |
|
| 相关函数 |
agi_ub_uninit |
| 示例 |
|
2.1.3 释放全局资源
| 函数名 |
agi_ub_uninit |
| 功能描述 |
释放SDK全局资源,释放后设备相关api都不能正常使用,都会返回失败。该api应该在程序退出时释放 |
| 函数原型 |
int32 agi_ub_uninit() |
| 返回值 |
0表示成功,其它表示失败 |
| 参数描述 |
无 |
| 相关函数 |
agi_ub_init |
| 示例 |
|
2.1.4 检测全局资源是否已经初始化
| 函数名 |
agi_ub_isinit |
| 功能描述 |
检测sdk库是否已经初始化 |
| 函数原型 |
int32 agi_ub_isinit() |
| 返回值 |
0表示已经初始化,其它表示没初始化 |
| 参数描述 |
无 |
| 相关函数 |
agi_ub_init, agi_ub_uninit |
| 示例 |
|
2.1.5 检测当前打开的设备通道数量
| 函数名 |
agi_ub_count |
| 功能描述 |
检测sdk库当前打开的通道数量 |
| 函数原型 |
int32 agi_ub_count() |
| 返回值 |
0 - 256 表示设备通道数量,其它表示失败 |
| 参数描述 |
无 |
| 相关函数 |
agi_ub_create |
| 示例 |
|
2.1.6 异步打开设备模块
| 函数名 |
agi_ub_create |
| 功能描述 |
查找usb设备是否已经插入,同时启动异步打开设备模块 |
| 函数原型 |
int32 agi_ub_create(const char *in_json_param, char *out_json_buf, int32 buf_size) |
| 返回值 |
0表示找到设备等待异步打开成功后通知;900002表示没发现设备等待插入设备后sdk会打开后通知 |
| 参数描述 |
| in_json_param | [in] 指定需要输入的json参数 - 保留 |
| out_json_buf | [out] 指定需要保存返回json字符串的缓冲地址,使用前先分配好内存 - 保留 |
| buf_size | [in] 指定out_json_buf 已经分配好的内存的大小 - 保留 |
|
| 相关函数 |
agi_ub_destroy |
| 示例 |
|
2.1.7 删除设备模块
| 函数名 |
agi_ub_destroy |
| 功能描述 |
删除用agi_ub_create创建的设备模块资源, 删除后 sdk不再自动打开插入的设备 |
| 函数原型 |
int32 agi_ub_destroy(const char *in_json_param) |
| 返回值 |
0表示成功,其它表示失败 |
| 参数描述 |
| in_json_param | [in] 指定需要输入的json参数;空 - 表示删除全部usb设备;其它 - 保留 |
|
| 相关函数 |
agi_ub_create |
| 示例 |
|
2.1.8 获取设备信息
| 函数名 |
agi_ub_acc_info |
| 功能描述 |
获取设备所有信息和当前状态 |
| 函数原型 |
int32 agi_ub_acc_info(const char *ep_acc, char *out_json_buf, int32 buf_size); |
| 返回值 |
0表示成功,其它表示失败 |
| 参数描述 |
| ep_acc | [in] 设备账号 |
| out_json_buf | [out] 指定需要保存返回json字符串的缓冲地址,使用前先分配好内存 |
| buf_size | [in] 指定out_json_buf 已经分配好的内存的大小 |
|
2.2 通用设备操作类
2.2.1 通用设备操作扩展
| 函数名 |
agi_ub_action |
| 功能描述 |
通用设备进行操作,对相关设备操作的设备账号和action名,控制参数再次封装 |
| 函数原型 |
int32 agi_ub_action(const char *in_json, char *out_json_buf, int32 buf_size); |
| 返回值 |
0表示成功,其它表示失败 |
| 参数描述 |
| in_json | [in] 指定需要输入的json参数,是对设备账号,操作名和参数的json封装,用在某些没有单独函数的通用操作 |
| out_json_buf | [out] 指定需要保存返回json字符串的缓冲地址,使用前先分配好内存 |
| buf_size | [in] 指定out_json_buf 已经分配好的内存的大小 |
|
| 相关函数 |
agi_ub_action_param,agi_ub_acc_info, agi_ub_do_ctrl, agi_ub_dial_dtmf, agi_ub_callout, agi_ub_answer, agi_ub_hangup, agi_ub_playfile_start,agi_ub_playfile_stop,agi_ub_recfile_start, agi_ub_recfile_stop |
| 示例 |
|
2.2.2 通用设备操作方法二
| 函数名 |
agi_ub_action_param |
| 功能描述 |
通用设备进行操作,效果等同与agi_ub_action,只是参数结构不一样 |
| 函数原型 |
int32 agi_ub_action_param(const char *ep_acc, const char *act_name, const char *json_param, char *out_json_buf, int32 buf_size); |
| 返回值 |
0表示成功,其它表示失败 |
| 参数描述 |
| ep_acc | [in] 设备账号 |
| act_name | [in] 操作功能名,详情查阅相关文档 |
| json_param | [in] 本次功能操作对应的json格式参数,详情请查阅示例或相关文档 |
| out_json_buf | [out] 输出缓冲 |
| buf_size | [in] 缓冲大小 |
|
| 相关函数 |
agi_ub_action,agi_ub_acc_info, agi_ub_do_ctrl, agi_ub_dial_dtmf, agi_ub_callout, agi_ub_answer, agi_ub_hangup, agi_ub_playfile_start,agi_ub_playfile_stop,agi_ub_recfile_start, agi_ub_recfile_stop |
| 示例 |
|
2.2.3 设备控制开关操作
| 函数名 |
agi_ub_do_ctrl |
| 功能描述 |
设备控制操作 |
| 函数原型 |
int32 agi_ub_do_ctrl(const char *ep_acc, const char *ctrl_name, int32 value); |
| 返回值 |
0表示成功,其它表示失败 |
| 参数描述 |
| ep_acc | [in] 设备账号 |
| ctrl_name | [in] 控制名:led/api_hook/loud_spk等,详情请查阅相关文档 |
| value | [in] 控制值 0关闭/1打开/或者其它 |
|
| 相关函数 |
agi_ub_action,agi_ub_action_param |
| 示例 |
|
2.3 通话控制类
2.3.1 电话拨出呼叫
| 函数名 |
agi_ub_callout |
| 功能描述 |
电话拨出呼叫 |
| 函数原型 |
int32 agi_ub_callout(const char *ep_acc, const char *code, const char *json_rule, int32 au_dev); |
| 返回值 |
0 成功;80000004设备不合法;80000105设备正忙 |
| 参数描述 |
| ep_acc | [in] 设备账号 |
| code | [in] 需要拨出的号码,事件中的呼出callid就是本号码,并不一定是实际送入电话线的号码,比如:这里是呼叫13810450502, 但是根据拨号规则处理后送入电话线的是013810450502 |
| json_rule | [in] 拨号规则: json格式的拨出号码规则
dst_to: 手工指定拨号规则. 设备真实输出的号码,一般是code前面加了某些前缀
为空->就是等同code
如果不为空->那其它规则都不起作用
比如:9,0138104xxxxx是客户号码, 9是分机出局号码,一个逗号延迟500ms,可以多个,0表示外地号码需要加拨0
prefix:出局方式
0->自动根据设置的ext规则识别
1->强制加出局
2->内部分机不用增加出局
proxy - 是否增加代拨
0->自动根据设置的代拨号码增加
1->增加代拨前缀[代拨号码再line_param里设置]-保留
->不增加代拨前缀
area - 本市号码是否自动去掉区号
->根据本市区号自动过滤
->保留
->不删除开头区号[如果本市区号010, 拨号0108888888时也不去掉前面的010, 当电话本不同城市共享,建议给所有号码加上区号,拨号时设置本地区号来自动忽略]
mobile_add_zero - 外地手机是否自动加拨首位0
->根据归宿地自动首位加拨0
->首位不是0就强制加拨0
->不管首位是否是0都不处理加拨
mobile_del_zero - 本地手机是否自动去掉首位0
->根据归宿地自动去掉首位0
->不管是否哪里都去掉首位0
->不管归属哪里都不去掉首位0
end_char - 拨号结束字符,在拨号结束后自动追加拨号,一般针对数字线路,ip线路,sim卡设备等使用追加#来表示拨号结束,让上层设备可以立即开始发送号码,加快拨号速度 |
| au_dev | [in] 通话音频设备:拨号结束后使用哪种音频耳机麦克风设备连通电话线进行通话
0->后台配置的默认音频设备
其它->不使用音频音频设置,api自行选择控制音频链路 |
|
| 示例 |
Json::Value json_rule;
json_rule["end_char"] = "#";
int nRet = agi_ub_callout("", "8001", json_rule.toFastString().c_str(), 0);
if (nRet == ERR_NO)
{
//打开设备喇叭,测试音频拨号过程,起到免提功能,实际拨号可以不用
agi_ub_do_ctrl("", "loud_spk", AGI_UB_LOUD_SPK_LINE);
}
|
2.3.2 模拟发送DTMF按键音
| 函数名 |
agi_ub_dial_dtmf |
| 功能描述 |
通话或摘机状态中模拟发送DTMF按键,可用在通话中对方提示按键操作或二次拨号等,等效于模拟手动在电话机上按键 |
| 函数原型 |
int32 agi_ub_dial_dtmf(const char *ep_acc, const char *code); |
| 返回值 |
0 成功;其它表示失败 |
| 参数描述 |
| ep_acc | [in] 设备账号 |
| code | [in] DTMF号码,1-9,*,#的按键号码,可以一个或者多个 |
|
2.3.3 来电时软摘机接听
| 函数名 |
agi_ub_answer |
| 功能描述 |
来电时进行软摘机操作,效果等同api_hook操作,录音盒不支持该功能。
跟api_hook区别是该函数在执行时会检测当前是否有来电,如果没有就会返回失败,如果有来电就会执行软摘机,并且打开设置的通话音频耳机直接可以进行通话,api_hook不管是否有来电都会执行软摘机
|
| 函数原型 |
int32 agi_ub_answer(const char *ep_acc, int32 au_dev); |
| 返回值 |
0 成功;其它表示失败 |
| 参数描述 |
| ep_acc | [in] 设备账号 |
| au_dev | [in] 音频设备
0 -> 使用设置的默认耳机设备
其它->不使用耳机。 如果后面需要耳机设备通话,使用api控制打开对应耳机操作
|
|
2.3.4 软挂机操作
| 函数名 |
agi_ub_hangup |
| 功能描述 |
软挂机操作,对应agi_ub_answer软摘机,内部本质还是调用api_hook进行软挂机
不是对phone口话机进行挂机操作,如果phone口话机处于摘机状态,软挂机后线路还是不会结束,必须把phone口话机放下线路才会进入空闲状态
只有当设备处于软挂机并且电话机已经放下去了,电话线才会处于空闲状态。
|
| 函数原型 |
int32 agi_ub_hangup(const char *ep_acc); |
| 返回值 |
0 成功;其它表示失败 |
| 参数描述 |
|
2.4 音频播放类
2.4.1 播放音频文件
| 函数名 |
agi_ub_playfile_start |
| 功能描述 |
播放音频文件到设备或者声卡
|
| 函数原型 |
int32 agi_ub_playfile_start(const char *ep_acc, const char *file, int32 repeat_cnt); |
| 返回值 |
0 成功;其它表示失败 |
| 参数描述 |
| ep_acc | [in] 设备账号 |
| file | [in] 文件路径,多个文件播放可以用"||"来分隔
文件路径可以使用http://x.x.x.x/a.wav远程文件
本地磁盘的路径支持相对目录, 相对本sdk的dll/so所在的目录下, 如: "audio/a.wav" 表示本sdk目录下的audio/a.wav
如果要同时播放多个文件,使用 || 分隔,比如:"a.wav||b.wav||c.wav"
如果需要播放文本,指定"text:"前缀参数,比如:"text:你好欢迎光临",其中text:表示固定前缀,后面是需要播放的汉字
支持音频文件和文本混合播放,比如:"a.wav||text:你好,欢迎光临||b.wav||c.wav"
|
| repeat_cnt | [in] 重复播放次数,如果设置1实际就是播放2次,设置2实际就是播放3次... |
|
2.4.2 停止播放音频文件
| 函数名 |
agi_ub_playfile_stop |
| 功能描述 |
停止播放音频文件到设备或者声卡
|
| 函数原型 |
int32 agi_ub_playfile_stop(const char *ep_acc, int32 uuid); |
| 返回值 |
0 成功;其它表示失败 |
| 参数描述 |
| ep_acc | [in] 设备账号 |
| uuid | [in] 播放句柄UUID,开始播放时返回的uuid, 保留该功能,目前可以用 0 |
|
2.4.3 播放用户缓冲音频数据流
| 函数名 |
agi_ub_playbuf_start |
| 功能描述 |
启动播放用户缓冲音频数据流, 支持8K,16位pcm音频。 如果上次已经播放的,在开始前必须停止上次播放
|
| 函数原型 |
int32 agi_ub_playbuf_start(const char *ep_acc, const char *json_param, char *out_json_buf, int32 buf_size); |
| 返回值 |
0 成功;其它表示失败 |
| 参数描述 |
| ep_acc | [in] 设备账号 |
| json_param | [in] 缓冲参数 |
| out_json_buf | [out] 指定需要保存返回json字符串的缓冲地址,使用前先分配好内存 |
| buf_size | [in] 指定out_json_buf已经分配好的内存的大小 |
|
| 示例 |
Json::Value json_param;
//缓冲延迟 500ms
json_param["sample_ms"] = 500;
//临时复制缓冲,一次写入不要超过该时间长度的音频,单位毫秒
json_param["buf_ms"] = 200;
//动态缓冲,防止音频网络抖动引起卡顿,建议60-200,动态缓冲越大播放延迟就越大,防音频延迟抖动性能越好
json_param["jitter_ms"] = 100;
char out_json_buf[4096] = { 0 };
if (agi_ub_playbuf_start("", json_param.toFastString_().c_str(), out_json_buf, 4096) != ERR_NO)
{
Logout("->启动缓冲播放失败");
}
else
{
Json::Value json_ret;
Json::Reader r;
r.parse(out_json_buf, out_json_buf + strlen(out_json_buf), json_ret);
m_playbuf_handle = json_ret["uuid"].asInt();//保存该缓冲通道句柄,该功能保留,目前为0
Logout("->开始缓冲播放...");
}
|
2.4.4 停止播放用户缓冲音频数据流
| 函数名 |
agi_ub_playbuf_stop |
| 功能描述 |
停止播放用户缓冲音频数据流
|
| 函数原型 |
int32 agi_ub_playbuf_stop(const char *ep_acc, int32 uuid); |
| 返回值 |
0 成功;其它表示失败 |
| 参数描述 |
| ep_acc | [in] 设备账号 |
| uuid | [in] 开始播放时返回的uuid, 保留该功能,目前可以用 0 |
|
| 示例 |
agi_ub_playbuf_stop("", 0);
|
2.4.5 发送用户缓冲音频数据流
| 函数名 |
agi_ub_playbuf_send |
| 功能描述 |
发送用户缓冲音频数据流,8K 16位音频流,一次不要写入太多,建议20ms一次,8K16位就是160个采样,320字节的音频数据,一次要超过初始化的 json_param["buf_ms"] = 200;就会返回失败 |
| 函数原型 |
int32 agi_ub_playbuf_send(const char *ep_acc, int32 uuid, char *audio_buf, int32 audio_size); |
| 返回值 |
0 成功;其它表示失败, 返回ERR_OVERFLOW [80000100]表示写入缓冲满, 不要丢弃语音包,过会重试 |
| 参数描述 |
| ep_acc | [in] 设备账号 |
| uuid | [in] 开始播放换成时返回的uuid, 保留该功能,目前可以用0 |
| audio_buf | [in] 音频数据 |
| audio_size | [in] 音频数据字节长度, 16位音频的数据就是 采样数量*2 |
|
| 示例 |
//播放缓冲的音频文件是否已经打开启动
if (m_pf_PlayBuf)
{
if (m_nSample_Num <= 0)//上次播放是否有剩余的音频数据
{
//从文件读取16位的320个采样音频数据, 实际内存应该是640字节
m_nSample_Num = (int)fread(&m_sBuf[0], 2, 320, m_pf_PlayBuf);
}
if (m_nSample_Num > 0)//有多少个16位采样音频数据可以播放
{
int ret = agi_ub_playbuf_send("", m_playbuf_handle , &m_sBuf[0], m_nSample_Num * sizeof(short));
if (ret == ERR_NO)
{
//ERR_NO播放成功, 复位数量0, 下次重新读取新数据
m_nSample_Num = 0;
}
//写入失败就保留数据,定时下次循环重新写入
//
}
}
|
2.5 录音相关类
2.5.1 手动开始文件录音
| 函数名 |
agi_ub_recfile_start |
| 功能描述 |
手动启动文件录音,如果已经在自动启动了录音,保持录音状态并返回成功 |
| 函数原型 |
int32 agi_ub_recfile_start(const char *ep_acc, const char *file); |
| 返回值 |
0 成功;其它表示失败 |
| 参数描述 |
| ep_acc | [in] 设备账号 |
| file | [in] 保留 |
|
2.5.2 手动停止文件录音
| 函数名 |
agi_ub_recfile_stop |
| 功能描述 |
手动停止文件录音 |
| 函数原型 |
int32 agi_ub_recfile_stop(const char *ep_acc, int32 uuid); |
| 返回值 |
0 成功;其它表示失败 |
| 参数描述 |
| ep_acc | [in] 设备账号 |
| uuid | [in] 录音UUID,开始录音时返回的uuid,保留该功能,目前可以用0 |
|
2.5.3 开始音频流录音-支持回调模式
| 函数名 |
agi_ub_recbuf_start |
| 功能描述 |
缓冲音频流录音,创建一个缓冲录音通道,默认返回8K,16位PCM音频,允许多个模块独自建立缓冲录音通道,对支持双通道设备才采用立体声双轨分开读取的方式,以便也用来区分通话人,如果不需要回调模式,建议使用agi_ub_recbuf_start_s来代替该函数
|
| 函数原型 |
int32 agi_ub_recbuf_start(const char *ep_acc, ptr_recbuf_callback p_recbuf_callback, void *ptr_user_data, const char *json_param, char *out_json_buf, int32 buf_size); |
| 返回值 |
0 成功;其它表示失败 |
| 参数描述 |
| ep_acc | [in] 设备账号 |
| p_recbuf_callback |
[in] 回调函数,用在C或者C++模式开发,非特殊情况建议不使用该功能
函数原型为: typedef int32 (AGI_CALLBACK *ptr_recbuf_callback)(void *p_userdata, char *out_audio_buf, int32 audio_buf_num, const char *json_param);
如果该函数地址不为空,表示使用回调方式采集音频数据, 就不要去定时调用agi_ub_recbuf_recv去读取,避免缓冲冲突
|
| ptr_user_data | [in] 回调时用户自定义数据,c++中一般使用当前类指针this |
| json_param | [in] 格式的扩展参数字符串,可查看下面agi_ub_recbuf_start_s函数的示例操作 |
| out_json_buf | [out] 指定需要保存返回json字符串的缓冲地址,使用前先分配好内存 |
| buf_size | [in] 指定out_json_buf 已经分配好的内存的大小 |
|
2.5.4 开始音频流录音-无回调模式
| 函数名 |
agi_ub_recbuf_start |
| 功能描述 |
这个函数等效agi_ub_recbuf_start函数的功能,就是比agi_ub_recbuf_start减少一个回调函数的参数,简化了不需要回调方式的调用过程, 如果没有特殊回调模式需求,建议使用该函数来代替agi_ub_recbuf_start |
| 函数原型 |
int32 agi_ub_recbuf_start_s(const char *ep_acc, const char *json_param, char *out_json_buf, int32 buf_size); |
| 返回值 |
0 成功;其它表示失败 |
| 参数描述 |
| ep_acc | [in] 设备账号 |
| json_param | [in] 格式的扩展参数字符串,可查看下面示例操作 |
| out_json_buf | [out] 指定需要保存返回json字符串的缓冲地址,使用前先分配好内存 |
| buf_size | [in] 指定out_json_buf 已经分配好的内存的大小 |
|
| 示例 |
Json::Value json_param;
//数据类型
//0:原始混音
//1:回音抵消后的
//2:回音抵消后的再次NLP算法清除残余噪音
json_param["data_type"] = 2;
//最大缓冲长度,0默认200ms,大概1600字节内存
//缓冲越大,延迟可能越大,但不容易丢数据,时时要求高可以减少缓冲数
json_param["max_buf_size"] = 1600;
//默认参数
//0:读取时内存有多少音频就返回多少
//1:读取时缓冲音频数据不够返回失败
//读取长度不要超过设置的最大缓冲max_buf_size,建议每次10ms/20ms,160-320长度
//回调模式下该参数忽略
json_param["recv_type"] = 1;
//必须大写的L或者R,双声道录音只对双轨设备有用,单轨设备只使用左声道,默认可以不设置
//L:左声道 line口客户语音
//R:右声道 phone口坐席语音
//不设置默认就是左声道
json_param["channel_type"] = "L";
//指定读取时返回的音频采样率,支持8000和16000
//json_param["sample_rate"] = 8000;
//音量,100表示默认原始音量,200放大一倍,50缩小一半
//json_param["volume"] = 100;
char out_json_buf[4096] = {0};
int ret = agi_ub_recbuf_start_s("", json_param.toFastString().c_str(), out_json_buf, 4096);
if (ret != ERR_NO)
{
Logout("启动缓冲录音失败");
}
else
{
//把返回的json字符串转换到json类对象
Json::Value json_ret;
Json::Reader r;
r.parse(out_json_buf, out_json_buf + strlen(out_json_buf), json_ret);
//保存该缓冲通道句柄, 读取时需要指定从该句柄读取
m_recbuf_handle = json_ret["uuid"].asInt();
}
|
2.5.5 停止音频流录音
| 函数名 |
agi_ub_recbuf_stop |
| 功能描述 |
停止一个缓冲录音通道,句柄必须是agi_ub_recbuf_start/agi_ub_recbuf_start_s成功后返回的json参数的"uuid"字段读取 |
| 函数原型 |
int32 agi_ub_recbuf_stop(const char *ep_acc, const char *json_param, int32 uuid, char *out_json_buf, int32 buf_size); |
| 返回值 |
0 成功;其它表示失败 |
| 参数描述 |
| ep_acc | [in] 设备账号 |
| uuid | [in] 启动缓冲录音通道的uuid, 必须是agi_ub_recbuf_start/agi_ub_recbuf_start_s成功后返回的json参数的"uuid"字段读取 |
| json_param | [in] 格式的扩展参数字符串,可查看下面示例操作 |
| out_json_buf | [out] 指定需要保存返回json字符串的缓冲地址,使用前先分配好内存 |
| buf_size | [in] 指定out_json_buf 已经分配好的内存的大小 |
|
| 示例 |
//带json参数的停止示例
if (m_recbuf_handle > 0)
{
Json::Value json_param;
//如果正在回调等待100ms超时,如果没有使用回调方式,可以不设置,可以输入空字符串。可以参考下面简单的停止示例
json_param["timeout"] = 100;
char out_json_buf[4096] = {0};
agi_ub_recbuf_stop("", m_recbuf_handle, json_param.toFastString().c_str(), out_json_buf, 4096);
m_recbuf_handle = 0;
}
//===================
//简单的停止示例
if (m_recbuf_handle > 0)
{
agi_ub_recbuf_stop("", m_recbuf_handle, "", nullptr, 0);
m_recbuf_handle = 0;
}
//==================
|
2.5.6 读取录音缓冲数据
| 函数名 |
agi_ub_recbuf_recv |
| 功能描述 |
读取一定数量的音频数据,返回后内部自动删除,同一个uuid不要多线程读取 |
| 函数原型 |
int32 agi_ub_recbuf_recv(const char *ep_acc, int32 uuid, char *out_audio_buf, int32 audio_buf_num, char *out_json_buf, int32 buf_size); |
| 参数描述 |
| ep_acc | [in] 设备账号 |
| uuid | [in] 启动缓冲录音通道的uuid, 必须是agi_ub_recbuf_start/agi_ub_recbuf_start_s成功后返回的json参数的"uuid"字段读取 |
| audio_buf | [out] 保存返回的音频数据缓冲 |
| audio_size | [in] 分配的audio_buf音频数据缓冲区大小 |
| out_json_buf | [out] 指定需要保存返回json字符串的缓冲地址,使用前先分配好内存 |
| buf_size | [in] 指定out_json_buf 已经分配好的内存的大小 |
|
| 示例 |
if (m_recbuf_handle > 0)
{
//也可以适当多分配几个字节,当前使用标准160个采样,16位的就是320字节内存
short out_audio_buf[160];
char out_json_buf[4096] = { 0 };
int r = agi_ub_recbuf_recv("", m_recbuf_handle, (char *)&out_audio_buf[0], 320, out_json_buf, 4096);
if (r == ERR_NO)
{
Json::Value json_ret;
Json::Reader r;
r.parse(out_json_buf, out_json_buf + strlen(out_json_buf), json_ret);
//返回的音频采样数量,就是内存长度 除2
int32 audio_sample_num = json_ret["length"].asInt()/sizeof(short));
}
}
|
2.5 事件管道控制类
2.6.1 创建事件数据管道
| 函数名 |
agi_ub_evt_create_json_pipe |
| 功能描述 |
创建一个获取事件数据的管道,注意:创建后的管道如果持续60秒不调用读取就会被自动释放该管道id |
| 函数原型 |
int32 agi_ub_evt_create_json_pipe(const char *ep_acc, const char *p_class_name, const char *p_charset); |
| 返回值 |
返回事件通道id, 小于0表示失败 |
| 参数描述 |
| ep_acc | [in] 设备账号名,空表示是全部设备事件都可以读取 |
| p_class_name | [in] 事件类名,空表示全部事件类
account - 设备状态事件
dialog - 呼叫相关事件
calllog - 呼叫记录事件 |
| p_charset | [in] 指定返回事件内容的字符编码格式,"gbk"或"utf-8", 如果输入的不是"utf-8", 那全部采用"gbk" |
|
| 相关函数 |
agi_ub_evt_destroy_json_pipe |
| 示例 |
int pipe_id = agi_ub_evt_create_json_pipe("", "", "utf-8");
if (pipe_id < 0)
{
logout("创建管道失败");
}
|
2.6.2 释放事件数据管道
| 函数名 |
agi_ub_evt_destroy_json_pipe |
| 功能描述 |
释放有agi_ub_evt_create_json_pipe创建的事件通道资源 |
| 函数原型 |
int32 agi_ub_evt_destroy_json_pipe(int32 pipe_id) |
| 返回值 |
0表示成功,其它表示失败 |
| 参数描述 |
| pipe_id | [in] 有agi_ub_evt_create_json_pipe创建时的返回的管道id |
|
| 相关函数 |
agi_ub_evt_create_json_pipe |
| 示例 |
|
2.6.3 获取事件内容数据长度
| 函数名 |
agi_ub_evt_get_json_buf_size |
| 功能描述 |
获取当前事件管道里最先需要读取的事件内容建议分配的缓冲长度
一般可以不读取直接分配4096长度的内存,该长度足够读取事件数据,但是如果启用了录音文件转文字功能,如果录音较长,返回的文本比较多,可能内存不够,建议先使用该api读取长度,动态分配足够内存后再获取事件数据
|
| 函数原型 |
int32 agi_ub_evt_get_json_buf_size(int32 pipe_id, int32 timeout_ms) |
| 返回值 |
返回缓冲长度, 小于0表示失败, 0表示当前没有数据 |
| 参数描述 |
| pipe_id | [in] 有agi_ub_evt_create_json_pipe创建时的返回的管道id |
| timeout_ms | [in] 如果当前队列没有事件, 阻塞等候多久,单位ms, 0表示不等候
如果在主线程里调用不要阻塞,建议用0,定时读取
如果是在独立的线程里读取,可以考虑阻塞几百毫秒,好处是当阻塞等待中有事件触发可以立即获取,减少定时期间的延迟 |
|
| 相关函数 |
agi_ub_evt_create_json_pipe |
| 示例 |
|
2.6.4 读取管道事件数据
| 函数名 |
agi_ub_evt_pop_json_buf_data |
| 功能描述 |
读取当前管道里最早的事件数据,读取后队列里就立即删除当前这个事件数据 |
| 函数原型 |
int32 agi_ub_evt_pop_json_buf_data(int32 pipe_id, int32 timeout_ms, char* out_json_buf, int32 buf_size) |
| 返回值 |
0表示成功,其它表示失败 |
| 参数描述 |
| pipe_id | [in] 有agi_ub_evt_create_json_pipe创建时的返回的管道id |
| timeout_ms | [in] 如果当前队列没有事件, 阻塞等候多久,单位ms, 0表示不等候
如果在主线程里调用不要阻塞,建议用0,定时读取
如果是在独立的线程里读取,可以考虑阻塞几百毫秒,好处是当阻塞等待中有事件触发可以立即获取,减少定时期间的延迟 |
| out_json_buf | [out] 指定需要保存返回json字符串的缓冲地址,使用前先分配好内存 |
| buf_size | [in] 指定out_json_buf 已经分配好的内存的大小 |
|
| 相关函数 |
agi_ub_evt_create_json_pipe |
| 示例 |
//在独立线程里执行的读取操作过程
std::string s_out_buf;
//创建一个管道id,使用utf-8返回字符串编码
int pipe_id = agi_ub_evt_create_json_pipe("", "", "utf-8");
while (true)
{
//判断当前是否有事件缓冲数据
//如果当前没有事件,等200ms, 这样可以避免线程死循环,不需要单独sleep了,还能更实时的获取事件通知
int32 buf_size = agi_ub_evt_get_json_buf_size(pipe_id, 200);
if (buf_size > 0)
{
//分配内存大小,可以多分配几个
s_out_buf.reserv(buf_size + 256);
//前面agi_ub_evt_get_json_buf_size已经判断有事件,这里也没必要等候,直接读取就行
int32 ret = agi_ub_evt_pop_json_buf_data(pipe_id, 0, (char*)s_out_buf.c_str(), s_out_buf.capacity());
if (ret == ERR_NO)
{
Json::Value json_ret;
Json::Reader r;
r.parse(s_out_buf.c_str(), s_out_buf.c_str() + strlen(s_out_buf.c_str()), json_ret);
if (json_ret["class"].asString() == "account")
{
//处理设备相关事件
proc_account_event(json_ret["account"].asString(), json_ret["data"], json_ret["time"]);
}
else if (json_ret["class"].asString() == "dialog")
{
//处理呼叫相关事件
proc_dialog_event(json_ret["account"].asString(), json_ret["data"], json_ret["time"]);
}
else if (json_evt_cb["class"].asString() == "calllog")
{
//生成了一条呼叫记录事件
std::cout << "create calllog..." << std::endl;
}
}
else if (ret == 80000101)
{
//没有事件内容,正常不会发生
//因为agi_ub_evt_get_json_buf_size已经判断有事件数据了
//除非事件在别的地方被读取后删除了
}
else if (ret != 80000101)
{
//其它错误,正常缓冲足够就不应该发生
std::cout << "pop_json_buf_data failed=" << ret << std::endl;
}
}
else
{//超时还没有事件,继续重试读取
}
}
|