信电助 - API开发接口文档

版本更新记录

2026.04.15 - V26.04.15

  • 增加千问3语音转文字模型

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 通用说明

1.3 开发时需要注意的细节

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 成功;其它表示失败
参数描述
ep_acc[in] 设备账号

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 {//超时还没有事件,继续重试读取 } }