中文简体 English
- C/C++ 接口文档,适用于 MacOS / Windows
- 1. 初始化
- 1.1 初始化设备
- 2. SDK版本号和日志系统
- 2.1 SDK版本号
- 2.2 设置日志级别和路径
- 3. 设备搜索
- 3.1 搜索局域网内设备
- 3.2 重新启动设备搜索
- 3.3 停止搜索设备
- 3.3 获取当前搜索状态
- 4. 登录设备
- 4.1 创建SDK句柄(1)(IVY设备建议使用此接口)
- 4.1.1 创建SDK句柄(3)(IVY低功耗设备必须使用此接口)
- 4.2 创建SDK句柄(2)(Foscam设备建议使用此接口)
- 4.3 销毁SDK句柄
- 4.4 检测当前句柄对应设备的状态
- 4.5 登录设备
- 4.6 登出设备
- 4.7 获取登录成功后P2P连接的TURN服务器信息
- 4.8 指定P2P的turn服务器
- 4.9 指定FoscamP2P连接分派服务器区域
- 5. 设备直播
- 5.1 打开直播视频
- 5.2 关闭直播视频
- 5.3 打开直播音频
- 5.4 关闭直播音频
- 5.5 开始直播录像
- 5.6 停止直播录像
- 6. 对讲
- 6.1 打开对讲
- 6.2 关闭对讲
- 6.3 发送对讲数据
- 7. 设备回放
- 7.1 获取设备的录像列表
- 7.2 打开回放
- 7.3 关闭回放
- 7.4 回放控制
- 7.5 开始回放录像下载(IVY设备)
- 7.6 取消回放录像下载(IVY设备)
- 7.7 开始回放录像下载(FosamIPC)
- 7.8 取消回放录像下载(FosamIPC)
- 7.9 开始回放录像下载(FosamNVR)
- 7.10 取消回放录像下载(FosamNVR)
- 8. 获取直播/回放视频音频数据
- 8.1 获取直播已经解码后的数据
- 8.2 获取直播原始音视频数据
- 8.3 获取回放已解码音视频数据
- 8.4 获取回放原始音视频数据
- 8.5 解码回放视频数据
- 9. 发送命令
- 9.1 发送命令(推荐使用)
- 9.2 发送CGI
- 10. 辅助接口
- 10.1 获取事件
- 10.1.1 获取事件2
- 10.2 将关键帧转成一张图片
- 10.3 查询SDK接口调用状态
- 11. 门铃接听接口
- 接口适用范围
- 11.1 创建门铃设备句柄并登录
- 11.2 打开门铃视频
- 11.3 关闭门铃视频
- 11.4 打开门铃音频
- 11.5 关闭门铃音频
- 11.6 打开门铃对讲
- 11.7 关闭门铃对讲
- 11.8 发送对讲数据给门铃
- 11.9 获取门铃数据(已解码)
- 11.10 获取门铃数据(未解码)
- 11.11 门铃本地录像开始
- 11.12 门铃本地录像结束
- 11.13 检测门铃句柄状态
- 11.14 获取门铃事件
- 11.15 设置OpenTalk对讲标志(仅在iOS平台下适用)
- 11.16 门铃接听状态查询
- 12 获取图片接口(仅支持IVY设备)
- 12.1 获取图片列表
- 12.2 获取图片数据
- 13. RTSP API (非线程安全)
- 13.1 打开RTSP
- 13.2 关闭RTSP
- 13.3 获取RTSP流(原始视频+PCM音频)
- 13.4 获取RTSP流(解码视频+PCM音频)
- 14. 双向视频
- 14.1 打开双向视频
- 14.2 关闭双向视频
- 14.3 发送视频
- 14.4 发送音频
- 14.5 拒绝视频
- 14.6 获取双向视频状态
C/C++ 接口文档,适用于 MacOS / Windows
1. 初始化
1.1 初始化设备
- 描述
初始化SDK,使用SDK前必须调用且调用一次即可。
void IVYIO_API IVYIO_Init()
- 参数
无
- 返回值
无
- 备注
初始化时SDK内部会启动搜索线程,初始化P2P,启动内部时钟线程。
- 调用示例
IVYIO_Init();
2. SDK版本号和日志系统
2.1 SDK版本号
- 描述
获取SDK版本号
void IVYIO_API IVYIO_Version(char *szVer)
- 参数
szVer | 缓冲区 |
---|
- 返回值
无
- 备注
存放版本号缓冲区建议至少大于32个字节
- 调用示例
char szVersion[64] = {0};
IVYIO_Version(szVersion);
2.2 设置日志级别和路径
- 描述
设置日志打印和日志界别
void IVYIO_API IVYIO_SetLog(int iLevel, char *szPath, int iMaxSize)
- 参数
iLevel | 日志级别 |
---|---|
szPath | 保存文件路径 |
iMaxSize | 日志文件最大值,单位为M |
iLevel级别
0 | IVYIO_LOG_LEVEL_NO | 不输出日志 |
---|---|---|
1 | IVYIO_LOG_LEVEL_ERR | 只输出错误 |
2 | IVYIO_LOG_LEVEL_DBG | 只输出调试 |
3 | IVYIO_LOG_LEVEL_ALL | 输出全部 |
- 返回值
无
- 备注
SDK默认日志级别是全部输出,如果szPath为NULL或者长度为0,不会有日志写到指定路径;iMaxSize可以为0,表示使用默认大小5M
- 调用示例
#ifdef _WIN32
char szPath[MAX_PATH] = "d:\\sdklog\\sdk.log";
#else
char szPath[512] = "/sdklog/sdk.log";
#endif
IVYIO_SetLog(IVYIO_LOG_LEVEL_ALL, szPath, 0);
3. 设备搜索
3.1 搜索局域网内设备
- *描述
搜索局域网内设备
void IVYIO_API IVYIO_Discovery(IVYIO_DEV_NODE *nodes, int *iCountOfNode)
- 参数
nodes | 存放设备节点的IVYIO_DEV_NODE类型数组 |
---|---|
iCountOfNode | 设备节点数量,作为输入,为nodes数组元素数量,作为输出,表示实际搜索到的数量 |
- 返回值
无
- 备注
无
- 调用示例
IVYIO_DEV_NODE nodes[32] = {0};
memset(nodes, 0, sizeof(nodes));
int count = sizeof(nodes) / sizeof(IVYIO_DEV_NODE);
IVYIO_Discovery(nodes, &count);
if (count > 0)
{
......
}
3.2 重新启动设备搜索
- 描述
重新启动设备搜索
void IVYIO_API IVYIO_RestartDiscovery()
- 参数
无
- 返回值
无
- 备注
无
- 调用示例
IVYIO_RestartDiscovery();
3.3 停止搜索设备
- 描述
停止设备搜索
void IVYIO_API IVYIO_StopDiscovery()
- 参数
无
- 返回值
无
- 备注
停止搜索后,SDK将会使用P2P进行连接。
- 调用示例
IVYIO_StopDiscovery();
3.3 获取当前搜索状态
- 描述
获取当前设备搜索的状态
int IVYIO_API IVYIO_GetDiscoveryState()
- 参数
无
- 返回值
SDK当前设备搜索状态
0 | 设备搜索运行中 |
---|---|
1 | 设备搜索已经停止 |
- 备注
无
- 调用示例
int state = IVYIO_GetDiscoveryState();
if (0 == state)
{
......
}
else if (1 == state)
{
......
}
else
{
......
}
4. 登录设备
4.1 创建SDK句柄(1)(IVY设备建议使用此接口)
- 描述
创建SDK实例句柄
IVYIO_HANDLE IVYIO_API IVYIO_Create(IVY_URL *url, char *szUid, char *szUser, char *szPassword, IVYIO_P2P_MODE mode)
- 参数
url | 结构体,存放目标设备的连接地址和端口;地址可以是DDNS或者IP |
---|---|
szUid | 目标设备的UID,可以为空 |
szUser | 目标设备的用户名,不能为空 |
szPassword | 目标设备的密码,不能为空 |
mode | P2P连接模式 0:UDP方式 1:TCP方式 2:自动 |
- 返回值
SDK句柄,返回句柄时递增的,释放过后在创建也会递增
- 备注
如果mode使用UDP模式,内部的P2P连接会使用UDP方式;如果使用TCP方式,P2P连接使用TCP连接,如果使用AUTO模式,那么SDK内部会自动进行切换,一次UDP方式,一次TCP方式。
如果你没有手动停止设备搜索,SDK在连接的时候会先搜索局域网内搜索你连接的设备(通过UID或者IP进行匹配,UID优先,然后是IP),如果搜索到,就直接走局域网,所以,如果你的UID是正确的,IP地址和端口错误也可以进行连接。
当设备不在局域网内时,根据参数不同,SDK连接会有不同行为:
- URL和UID同时存在,SDK首先使用UID连接,如果连接失败,再使用IP去连接。
- 只有UID,SDK只会使用UID去连接。
- 只有URL,SDK只会使用URL去连接。
- 引用
typedef struct _IVYIO_URL_
{
char szUrl[256]; // IP或者DDNS
unsigned short usPort; // IP或者DDNS对应的IP
}ATTRIBUTE_PACKED IVYIO_URL, *PIVYIO_URL;
- 调用示例
IVYIO_URL url;
memset(&url, 0, sizeof(url));
strcpy(url.szUrl, "192.168.1.1");
url.usPort = 88;
IVYIO_HANDLE handle = IVYIO_Create(&url, "ABCDABCDABCDABCDABCD2222", "username", "password", IVYIO_P2P_MODE_UDP);
4.1.1 创建SDK句柄(3)(IVY低功耗设备必须使用此接口)
- 描述
创建SDK实例句柄,如果lowPower为0,接口功能和使用方法和IVYIO_Create完全一致。
IVYIO_HANDLE IVYIO_API IVYIO_Create_1(IVY_URL *url, char *szUid, char *szUser, char *szPassword, IVYIO_P2P_MODE mode, int lowPower)
- 参数
url | 结构体,存放目标设备的连接地址和端口;地址可以是DDNS或者IP |
---|---|
szUid | 目标设备的UID,可以为空 |
szUser | 目标设备的用户名,不能为空 |
szPassword | 目标设备的密码,不能为空 |
mode | P2P连接模式 0:UDP方式 1:TCP方式 2:自动 |
lowPower | 是否是低功耗设备 0:和IVYIO_Create行为一样 1:表明当前设备是低功耗设备,SDK内部会启动接口调用计时器,超过指定时间没有调用SDK接口,SDK可以告诉应用,应用可以通过IVYIO_ApiCallTimeIsUp查询 |
- 返回值
SDK句柄,返回句柄时递增的,释放过后在创建也会递增
- 备注
如果mode使用UDP模式,内部的P2P连接会使用UDP方式;如果使用TCP方式,P2P连接使用TCP连接,如果使用AUTO模式,那么SDK内部会自动进行切换,一次UDP方式,一次TCP方式。
如果你没有手动停止设备搜索,SDK在连接的时候会先搜索局域网内搜索你连接的设备(通过UID或者IP进行匹配,UID优先,然后是IP),如果搜索到,就直接走局域网,所以,如果你的UID是正确的,IP地址和端口错误也可以进行连接。
当设备不在局域网内时,根据参数不同,SDK连接会有不同行为:
- URL和UID同时存在,SDK首先使用UID连接,如果连接失败,再使用IP去连接。
- 只有UID,SDK只会使用UID去连接。
- 只有URL,SDK只会使用URL去连接。
- 引用
typedef struct _IVYIO_URL_
{
char szUrl[256]; // IP或者DDNS
unsigned short usPort; // IP或者DDNS对应的IP
}ATTRIBUTE_PACKED IVYIO_URL, *PIVYIO_URL;
- 调用示例
IVYIO_URL url;
memset(&url, 0, sizeof(url));
strcpy(url.szUrl, "192.168.1.1");
url.usPort = 88;
IVYIO_HANDLE handle = IVYIO_Create_1(&url, "ABCDABCDABCDABCDABCD2222", "username", "password", IVYIO_P2P_MODE_UDP, 1);
4.2 创建SDK句柄(2)(Foscam设备建议使用此接口)
IVYIO_HANDLE IVYIO_API IVYIO_CreateEx_1(IVYIO_URL *url, char *szUid, char *szMac, char *szUser, char *szPassword, IVYIO_P2P_MODE mode, int devType, int streamType)
- 描述
此接口功能和 IVYIO_Create 一致,相同参数具有相同的意义和功能(参考 IVYIO_Create),所有描述均适用于此接口,下面主要描述不同的参数含义。
- 参数
url | 同 IVYIO_Create |
---|---|
szUid | 同 IVYIO_Create |
szMac | 目标设备的MAC,可以为空 |
szUser | 同 IVYIO_Create |
szPassword | 同 IVYIO_Create |
mode | 同 IVYIO_Create |
devType | 设备类型, 参见 IVYIO_DEV_TYPE 定义,设备类型也可以从 IVYIO_Discovery 中获取 |
streamType | 打开设备的码流类型,主码流或者子码流,参见 IVYIO_VIDEO_STREAM_TYPE 定义 |
- 调用示例
// Create SDK handle for Foscam IPC with main stream video
IVYIO_URL url;
memset(&url, 0, sizeof(url));
strcpy(url.szUrl, "192.168.1.1");
url.usPort = 88;
IVYIO_HANDLE handle = IVYIO_CreateEx_1(&url, "ABCDABCDABCDABCDABCD2222", "", "admin", "", IVYIO_P2P_MODE_UDP, IVYIO_DEV_FOS_IPC, IVYIO_MAIN_VIDEO_STREAM);
- 备注
何如用UID区分Foscam设备还是IVY设备,如果UID的21位(从0开始)是‘2’或者‘4’,表示此设备是IVY设备,其他情况说明设备是Foscam设备
4.3 销毁SDK句柄
- 描述
销毁SDK句柄并且释放资源
void IVYIO_API IVYIO_Destroy(IVYIO_HANDLE handle)
- 参数
handle | SDK句柄 |
---|
- 返回值
无
- 备注
调用此接口后,handle对应的SDK实例占用内存全部被释放。
请不要在不同线程销毁相同句柄,SDK无法处理这种操作,会引起Crash。
因为SDK为了让多个销毁操作可以同时进行,无法保证同一个句柄销毁的问题;如果SDK保证了同一句柄在不同线程销毁,那么当遇到多个句柄同时销毁的情况,运行速度会变的很慢,因为SDK必须使用同步保证句柄逐个销毁。
4.4 检测当前句柄对应设备的状态
- 描述
检测当前设备状态,是在线还是离线
IVYIO_HANDLE_STATE IVYIO_API IVYIO_CheckHandle(IVYIO_HANDLE handle)
- 参数
handle | SDK句柄 |
---|
- 返回值
设备状态,参见定义 IVYIO_HANDLE_STATE
0 | 初始化状态 |
---|---|
1 | 正在连接 |
2 | 设备在线 |
3 | 设备离线 |
4 | 达到最大用户数 |
5 | 设备被锁 |
6 | 用户名或者密码错误 |
7 | 拒绝访问 |
8 | 未知 |
9 | 非法句柄 |
10 | 用户取消操作 |
- 引用
typedef enum
{
IVYIO_HANDLE_STATE_INIT = 0,
IVYIO_HANDLE_STATE_CONNECTTING = 1,
IVYIO_HANDLE_STATE_ONLINE = 2,
IVYIO_HANDLE_STATE_OFFLINE = 3,
IVYIO_HANDLE_STATE_MAX_USERS = 4,
IVYIO_HANDLE_STATE_LOCKED = 5,
IVYIO_HANDLE_STATE_USR_OR_PWD_ERR = 6,
IVYIO_HANDLE_STATE_DENY = 7,
IVYIO_HANDLE_STATE_UNKNOWN,
IVYIO_HANDLE_STATE_INVALID_HANDLE
}IVYIO_HANDLE_STATE;
- 备注
有些状态只是一瞬间存在,可能无法获取到, 比如 IVYIO_HANDLE_STATE_USR_OR_PWD_ERR, 密码错误后,设备可能会断开和SDK的连接,所以状态可能会变成 IVYIO_HANDLE_STATE_OFFLINE。
对于 IVYIO_HANDLE_STATE_MAX_USERS / IVYIO_HANDLE_STATE_LOCKED / IVYIO_HANDLE_STATE_USR_OR_PWD_ERR /
IVYIO_HANDLE_STATE_DENY 几种状态,可以使用IVYIO_Login的返回结果来做判断,因为这个结果最为准确而且容易处理。
如果是当前设备是IVY设备或者是FoscamIPC,建议不使用此接口,推荐使用IVYIO_GetEvent来判断设备是否断线即可,其他状态可以在登录接口获取到。
- 调用示例
while (bRunning)
{
IVYIO_HANDLE_STATE state = IVYIO_CheckHandle(handle);
switch (state)
{
case IVYIO_HANDLE_STATE_INIT:
case IVYIO_HANDLE_STATE_CONNECTTING:
// SDK is connectting device
break;
case IVYIO_HANDLE_STATE_ONLINE:
// SDK connected already.
break;
case IVYIO_HANDLE_STATE_INVALID_HANDLE:
// Handle error
break;
case IVYIO_HANDLE_STATE_OFFLINE:
// SDK disconnected
break;
default:
// Other state can ignore
break;
}
}
4.5 登录设备
- 描述
登陆设备
IVYIO_RESULT IVYIO_API IVYIO_Login(IVYIO_HANDLE handle, int iTimeout)
- 参数
handle | SDK句柄 |
---|---|
iTimeout | 超时时间,单位ms |
- 返回值
操作结果
0 | 成功 |
---|---|
1 | 失败 |
2 | 句柄错误 |
3 | 用户名和密码错误 |
4 | 参数错误 |
5 | API运行时错误 |
6 | 拒绝访问 |
7 | 设备已经锁住 |
8 | 达到最大用户数 |
9 | 对讲被占用 |
10 | 用户已经取消操作 |
11 | 超时 |
12 | 不支持的操作 |
13 | 未知 |
14 | 不在线 |
- 引用
typedef enum
{
IVYIO_RESULT_OK = 0,
IVYIO_RESULT_FAIL,
IVYIO_RESULT_HANDLE_ERR,
IVYIO_RESULT_USR_OR_PWD_ERR,
IVYIO_RESULT_ARGS_ERR,
IVYIO_RESULT_APITIME_ERR,
IVYIO_RESULT_DENY,
IVYIO_RESULT_LOCKED,
IVYIO_RESULT_MAX_USER,
IVYIO_RESULT_TALK_OPENED_BY_OTHERS,
IVYIO_RESULT_CANCEL_BY_USER,
IVYIO_RESULT_TIMEOUT,
IVYIO_RESULT_UNSUPPORT,
IVYIO_RESULT_UNKNOWN,
IVYIO_RESULT_OFFLINE
}IVYIO_RESULT;
- 调用示例
// Login in 5s
IVYIO_RESULT rst = IVYIO_Login(handle, 1000 * 5);
4.6 登出设备
- 描述
登出设备
void IVYIO_API IVYIO_Logout(IVYIO_HANDLE handle)
- 参数
handle | SDK句柄 |
---|
- 备注
登出操作只是断开所有与设备的连接,不会释放资源。
对于IVY设备,连接断开后,SDK内部不会进行重连,需要再次调用IVYIO_Login才会进行再一次连接。
对于Foscam设备,连接断开后,SDK内部还会自动进行重连,所以,如果不想要Foscam设备去自动重连,可以调用IVYIO_Destroy去销毁句柄。
如果发现无法连接上设备,IVYIO_Destroy后再次创建句柄去登录可能更有效。
- 调用示例
IVYIO_Destory(handle);
4.7 获取登录成功后P2P连接的TURN服务器信息
- 描述
获取登录成功后P2P连接的TURN服务器信息
void IVYIO_API IVYIO_GetCurTurnServer(IVYIO_HANDLE handle, IVYIO_TURN_INFO *turn)
- 参数
handle | SDK句柄 |
---|---|
IVYIO_TURN_INFO | turn服务器信息 |
- 备注
请保证在登录(login api)成功后调用该接口,如果是局域网,turn信息不会被填充。
请注意IVYIO_TURN_INFO->ip中可能含有’\n’字符,并且后边会有字符(打印出这个字符串可能会出现2行),这个是p2p返回的信息,不要漏掉,所以,请保证这个IVYIO_TURN_INFO->ip字符串按照以’\0’结尾来处理。
‘\n’后边的字符是p2p库处理ipv4/ipv6的标志。
如果将IVYIO_TURN_INFO->ip保存在文件中,可能出现ip占用两行的情况。
比如:获取的ip为 28.32.3.42,实际内存中的值为 “28.32.3.42\n2”,请一定注意“\n”
- 引用
typedef struct _IVYIO_TURN_INFO_
{
unsigned short port;
char ip[64];
} IVYIO_TURN_INFO, *PIVYIO_TURN_INFO;
- 调用示例
IVYIO_TURN_INFO turn;
memset(&turn, 0, sizeof(turn));
IVYIO_GetCurTurnServer(handle, &turn);
4.8 指定P2P的turn服务器
- 描述
使用指定P2P的Turn服务器,使用后SDK直接调过请求分派服务器,直接连接turn开始打洞
IVYIO_RESULT IVYIO_API IVYIO_UseTurnServer(IVYIO_HANDLE handle, IVYIO_TURN_INFO *turn)
- 参数
handle | SDK句柄 |
---|---|
IVYIO_TURN_INFO | turn服务器信息 |
- 备注
设置turn后,SDK不会再去请求分派服务器,而是直接使用设置turn服务器去进行P2P连接,这样可以节省请求分派服务器的时间。
如果turn为空,或者turn不合法,如,ip长度为0,port为0,SDK会自动去请求分派服务器,保证p2p可以正常运行。
- 请在create之后login之前使用该接口
- 如果想要改变turn服务器,请destory之后create再调用该接口。
- 引用
typedef struct _IVYIO_TURN_INFO_
{
unsigned short port;
char ip[64];
} IVYIO_TURN_INFO, *PIVYIO_TURN_INFO;
- 调用示例
IVYIO_TURN_INFO turn;
memset(&turn, 0, sizeof(turn));
// read turn info from file
XXXX_Read(&turn);
IVYIO_UseTurnServer(handle, &turn);
4.9 指定FoscamP2P连接分派服务器区域
- 描述
当设备是IVY设备,并且UID[22]对应的字符是“GHIJ”中的一个,客户端需要指定SDK连接的分派服务器区域;如果不指定,SDK将会连接所有的分派服务器。
IVYIO_RESULT IVYIO_API IVYIO_SetDispatchLocationType(IVYIO_HANDLE handle, int location)
- 参数
handle | SDK句柄 |
---|---|
location | 区域 0:国内 1:国外 |
- 备注
此接口支持IVY设备,在login之前,一定要调用此接口,否则SDK内部默认连接的将会是所有分派服务器;
如果location的值非法,SDK也将会连接所有分派服务器。
- 调用示例
IVYIO_HANDLE handle = IVYIO_CreateXXX(......);
// indicate china
IVYIO_SetDispatchLocationType(handle, 0);
IVYIO_login(handle);
...
5. 设备直播
5.1 打开直播视频
- 描述
打开视频
IVYIO_RESULT IVYIO_API IVYIO_OpenVideo(IVYIO_HANDLE handle, void *args, int iTimeout, int iChannel)
- 参数
handle | SDK句柄 |
---|---|
args | 打开视频参数, 不同设备有不同的参数 |
iTimeout | 超时,单位ms |
iChannel | 通道号,可以一次打开多个设备,按位表示(bit0-bit31表示0-31通道),比如0x06,表示打开通道1和通道2 |
- 返回值
操作结果
- 备注
由于此接口支持多种设备打开视频,所以不同设备args参数会有不同的输入。当调用此接口打开视频的时候,SDK会在此时申请直播需要的内存(视频缓冲区,音频缓冲区)和解码器,当你调用关闭视频的时候,SDK会释放所申请的内存的解码器。同时媒体通道也是在这个时候连接上的,但是关闭的时候连接不会断开。
Foscam IPC / IVY IPC | args参数为指向 IVYIO_OPEN_VIDEO_ARGS_TYPE0 结构的指针,结构成员openVideoArgsType的值必须指定为0 ; iChannel为0) |
---|---|
IVY NVR | args参数为指向 IVYIO_OPEN_VIDEO_ARGS_TYPE0 结构的指针,结构成员openVideoArgsType的值必须指定为0 ; iChannel按位表示,bit0 - bit31 表示通道1-通道32,可同时指定多个通道) |
Foscam NVR | args参数位指向 IVYIO_OPEN_VIDEO_ARGS_TYPE1 结构的指针,结构成员openVideoArgsType的值必须指定为1 ; iChannel按位表示,bit0 - bit31 表示通道1-通道32,可同时指定多个通道 |
- 注意
请一定保持 IVYIO_OpenVideo / IVYIO_CloseVideo / IVYIO_OpenPlaybackEx / IVYIO_OpenPlayback / IVYIO_ClosePlayback 之间串行调用,不可并行调用,否则可能会出现获取不到直播或者回放视频流的情况,主要因为这几个接口有状态的维护。
- 引用
typedef struct _IVYIO_OPEN_VIDEO_ARGS_TYPE0_
{
int openVideoArgsType; // always 0
int streamType; // 0: main stream 1: sub stream
}ATTRIBUTE_PACKED IVYIO_OPEN_VIDEO_ARGS_TYPE0, *PIVYIO_OPEN_VIDEO_ARGS_TYPE0;
typedef struct _IVYIO_OPEN_VIDEO_ARGS_TYPE1_
{
int openVideoArgsType; // always 1
int streamType; // 0: main stream 1: sub stream
int videoMode; // please set 0
int qcMode; // please set 0
int chMode; // please set 0
int reDecChs; // please set 0
}ATTRIBUTE_PACKED IVYIO_OPEN_VIDEO_ARGS_TYPE1, *PIVYIO_OPEN_VIDEO_ARGS_TYPE1;
- 调用示例
if (IVYIO_DEV_IPC == devType || IVYIO_DEV_FOS_IPC == devType || IVYIO_DEV_FOS_DOORBELL == devType)
{
// Foscam IPC / IVY IPC open video with main stream
IVYIO_OPEN_VIDEO_ARGS_TYPE0 open;
open.openVideoArgsType = 0;
open.streamType = 0;
IVYIO_RESULT rst = IVYIO_OpenVideo(handle, &open, 1000 * 5, 0);
}
else if (IVYIO_DEV_NVR == devType)
{
// IVY NVR open video with main stream in channel 1 and channel 3
IVYIO_OPEN_VIDEO_ARGS_TYPE0 open;
open.openVideoArgsType = 0;
open.streamType = 0;
IVYIO_RESULT rst = IVYIO_OpenVideo(handle, &open, 1000 * 5, 0x05);
}
else if (IVYIO_DEV_FOS_NVR == devType)
{
// Foscam NVR open video with main stream in channel 1 and channel 2
IVYIO_OPEN_VIDEO_ARGS_TYPE1 open;
open.openVideoArgsType = 1;
open.streamType = 0;
open.videoMode = 0;
open.qcMode = 0;
open.chMode = 0;
open.reDecChs = 0;
IVYIO_RESULT rst = IVYIO_OpenVideo(handle, &open, 1000 * 5, 0x03);
}
5.2 关闭直播视频
- 描述
关闭视频
IVYIO_RESULT IVYIO_API IVYIO_CloseVideo(IVYIO_HANDLE handle, int iTimeout, int iChannel)
- 参数
handle | SDK句柄 |
---|---|
iTimeout | 超时,单位ms |
iChannel | 通道号,Foscam IPC / IVY IPC 通道值为0, Foscam NVR / IVY NVR 按位指定关闭通道 |
- 返回值
操作结果
- 备注
关闭操作会将对应的视频内存释放,所以,在关闭视频之前不要再获取视频数据或者已经拿到的数据不要再使用(除非数据已经拷贝到你自己的内存中),否则会引起Crash。
- 调用示例
if (IVYIO_DEV_IPC == devType || IVYIO_DEV_FOS_IPC == devType || IVYIO_DEV_FOS_DOORBELL == devType)
{
// Foscam IPC / IVY IPC close video
IVYIO_RESULT rst = IVYIO_CloseVideo(handle, 1000 * 5, 0);
}
else if (IVYIO_DEV_NVR == devType || IVYIO_DEV_FOS_NVR == devType)
{
// IVY NVR / Foscam NVR close video channel 4 and channel 5
IVYIO_RESULT rst = IVYIO_CloseVideo(handle, 1000 * 5, 0x18);
}
- 注意
请一定保持 IVYIO_OpenVideo / IVYIO_CloseVideo / IVYIO_OpenPlaybackEx / IVYIO_OpenPlayback / IVYIO_ClosePlayback 之间串行调用,不可并行调用,否则可能会出现获取不到直播或者回放视频流的情况,主要因为这几个接口有状态的维护。
5.3 打开直播音频
- 描述
打开音频
IVYIO_RESULT IVYIO_API IVYIO_OpenAudio(IVYIO_HANDLE handle, IVYIO_AUDIO_STREAM_TYPE stream, int iTimeout, int iChannel)
- 参数
handle | SDK句柄 |
---|---|
stream | 音频码流类型,0:主码流 1:子码流 |
iTimeout | 超时,单位ms |
iChannel | 通道号,同打开视频 |
- 返回值
操作结果
- 备注
打开音频之前,必须要打开视频,因为只有在打开视频的时候才会有媒体通道和设备建立连接,同理,如果关闭了视频,也无法打开音频,因为关闭视频的时候虽然媒体通道没有关闭,但是音频缓冲区已经被释放掉了。
- 调用示例
if (IVYIO_DEV_IPC == devType || IVYIO_DEV_FOS_IPC == devType || IVYIO_DEV_FOS_DOORBELL == devType)
{
// Foscam IPC / IVY IPC open audio with main stream
IVYIO_RESULT rst = IVYIO_OpenAudio(handle, IVYIO_MAIN_AUDIO_STREAM, 1000 * 5, 0);
}
else if (IVYIO_DEV_NVR == devType)
{
// IVY NVR open audio with main stream in channel 1 and channel 3
IVYIO_RESULT rst = IVYIO_OpenAudio(handle, IVYIO_MAIN_AUDIO_STREAM, 1000 * 5, 0x05);
}
else if (IVYIO_DEV_FOS_NVR == devType)
{
// We don't need to call this api, because Foscam NVR opened audio already when call open video api.
}
5.4 关闭直播音频
- 描述
关闭音频
IVYIO_RESULT IVYIO_API IVYIO_CloseAudio(IVYIO_HANDLE handle, int iTimeout, int iChannel)
- 参数
handle | SDK句柄 |
---|---|
iTimeout | 超时,单位ms |
iChannel | 通道号,同打开视频 |
- 返回值
操作结果
- 备注
无
- 调用示例
if (IVYIO_DEV_IPC == devType || IVYIO_DEV_FOS_IPC == devType || IVYIO_DEV_FOS_DOORBELL == devType)
{
// Foscam IPC / IVY IPC close video
IVYIO_RESULT rst = IVYIO_CloseAudio(handle, 1000 * 5, 0);
}
else if (IVYIO_DEV_NVR == devType)
{
// IVY NVR / Foscam NVR close video channel 4 and channel 5
IVYIO_RESULT rst = IVYIO_CloseAudio(handle, 1000 * 5, 0x18);
}
else if ( IVYIO_DEV_FOS_NVR == devType)
{
// We don't need to call this api, because Foscam NVR closed audio already when call close video api.
}
5.5 开始直播录像
- 描述
开始录像
IVYIO_RESULT IVYIO_API IVYIO_StartRecord(IVYIO_HANDLE handle, IVYIO_RECORD_TYPE type, const char *szFileName, int iMaxSize, int iChannel)
- 参数
handle | SDK句柄 |
---|---|
type | 录像类型 0:AVI 1:MP4 |
szFileName | 录像完整路径名字 |
iMaxSize | 录像文件最大值,0表示使用默认值256M,单位为M |
iChannel | 通道0-31,一次只能使用一个通道 |
- 返回值
操作结果
- 备注
如果录像达到最大值,会产生录像达到最大值事件,如果分辨率有改变,也会产生分辨率改变的事件。
- 录像过程中可能会产生的事件
事件ID | 含义 | 处理方式 |
---|---|---|
2052 | 没有足够的空间 | 停止录像 |
2053 | 文件达到最大值 | 停止录像,重新录像 |
2054 | 分辨率改变 | 停止录像,重新录像 |
2055 | 路径不存在 | 停止录像 |
2056 | 未知录像错误 | 停止录像 |
typedef enum
{
IVYIO_RECORD_ERROR_NO_ENOUGE_SPACE = 2052,
IVYIO_RECORD_ERROR_MAX_FILE,
IVYIO_RECORD_ERROR_SOLUTION_CHG,
IVYIO_RECORD_ERROR_FILE_PATH_NOEXIST,
IVYIO_RECORD_ERROR_UNKNOW
}IVYIO_RECORD_EVENT;
- 调用示例
if (IVYIO_DEV_FOS_IPC == devType || IVYIO_DEV_IPC == devType || IVYIO_DEV_FOS_DOORBELL == devType)
{
#ifdef _WIN32
IVYIO_RESULT rst = IVYIO_StartRecord(handle, IVYIO_RECORD_MP4, "c:\\record.mp4", 0, 0);
#else
IVYIO_RESULT rst = IVYIO_StartRecord(handle, IVYIO_RECORD_MP4, "/record/record.mp4", 0, 0);
#endif
}
else if (IVYIO_DEV_FOS_NVR == devType || IVYIO_DEV_NVR == devType)
{
// Start record on channel 5
#ifdef _WIN32
IVYIO_RESULT rst = IVYIO_StartRecord(handle, IVYIO_RECORD_MP4, "c:\\record.mp4", 0, 5);
#else
IVYIO_RESULT rst = IVYIO_StartRecord(handle, IVYIO_RECORD_MP4, "/record/record.mp4", 0, 5);
#endif
}
5.6 停止直播录像
- 描述
停止录像
IVYIO_RESULT IVYIO_API IVYIO_StopRecord(IVYIO_HANDLE handle, int iChannel)
- 参数
handle | SDK句柄 |
---|---|
iChannel | 通道0-31,一次只能使用一个通道 |
- 返回值
操作结果
- 调用示例
if (IVYIO_DEV_FOS_IPC == devType || IVYIO_DEV_IPC == devType || IVYIO_DEV_FOS_DOORBELL == devType)
{
#ifdef _WIN32
IVYIO_RESULT rst = IVYIO_StopRecord(handle, 0);
#else
IVYIO_RESULT rst = IVYIO_StopRecord(handle, 0);
#endif
}
else if (IVYIO_DEV_FOS_NVR == devType || IVYIO_DEV_NVR == devType)
{
// Start record on channel 5
IVYIO_RESULT rst = IVYIO_StopRecord(handle, 5);
}
6. 对讲
6.1 打开对讲
- 描述
打开对讲
IVYIO_RESULT IVYIO_API IVYIO_OpenTalk(IVYIO_HANDLE handle, int iTimeout, int iChannel)
- 参数
handle | SDK句柄 |
---|---|
iTimeout | 超时,单位ms |
iChannel | 通道号0-31,一次只能打开一个通道,如果要打开通道0,iChannel为0,如果要打开通道1,iChannel为1 |
- 返回值
操作结果
- 调用示例
if (IVYIO_DEV_IPC == devType || IVYIO_DEV_FOS_IPC == devType || IVYIO_DEV_FOS_DOORBELL == devType)
{
IVYIO_RESULT rst = IVYIO_OpenTalk(handle, 1000 * 5, 0);
}
else if (IVYIO_DEV_NVR == devType || IVYIO_DEV_FOS_NVR == devType)
{
// Open talk channel 2
IVYIO_RESULT rst = IVYIO_OpenTalk(handle, 1000 * 5, 2);
}
6.2 关闭对讲
- 描述
关闭对讲
IVYIO_RESULT IVYIO_API IVYIO_CloseTalk(IVYIO_HANDLE handle, int iTimeout, int iChannel)
- 参数
handle | SDK句柄 |
---|---|
iTimeout | 超时,单位ms |
iChannel | 同打开对讲 |
- 返回值
操作结果
- 调用示例
if (IVYIO_DEV_IPC == devType || IVYIO_DEV_FOS_IPC == devType || IVYIO_DEV_FOS_DOORBELL == devType)
{
IVYIO_RESULT rst = IVYIO_CloseTalk(handle, 1000 * 5, 0);
}
else if (IVYIO_DEV_NVR == devType || IVYIO_DEV_FOS_NVR == devType)
{
// Close talk channel 2
IVYIO_RESULT rst = IVYIO_CloseTalk(handle, 1000 * 5, 2);
}
6.3 发送对讲数据
- 描述
发送对讲数据
IVYIO_RESULT IVYIO_API IVYIO_SendTalkData(IVYIO_HANDLE handle, unsigned char *data, int iSizeOfData, int iChannel)
- 参数
handle | SDK句柄 |
---|---|
data | 对讲数据buffer |
iSizeOfData | 对讲数据大小 |
iChannel | 同打开对讲 |
- 返回值
操作结果
- 调用示例
unsigned char talkData[960] = {0};
// Get talk data to talkData
// Talk data sample is 8000, data size is 960 bytes
......
if (IVYIO_DEV_IPC == devType || IVYIO_DEV_FOS_IPC == devType || IVYIO_DEV_FOS_DOORBELL == devType)
{
IVYIO_RESULT rst = IVYIO_SendTalkData(handle, talkData, sizeof(talkData), 0);
}
else if (IVYIO_DEV_NVR == devType || IVYIO_DEV_FOS_NVR == devType)
{
// Send talk to channel 2
IVYIO_RESULT rst = IVYIO_SendTalkData(handle, talkData, sizeof(talkData), 2);
}
7. 设备回放
7.1 获取设备的录像列表
- 描述
获取回放列表
IVYIO_RESULT IVYIO_API IVYIO_GetPlaybackRecordList(IVYIO_HANDLE handle, void *args, void *list, int iTimeout, int iChannel)
- 参数
handle | SDK句柄 |
---|---|
args | 指向请求录像列表结构体指针 |
list | 指向回放列表结构体指针 |
iTimeout | 超时,单位ms |
iChannel | 通道号,同打开视频 |
- 返回值
操作结果
- 备注
录像的搜索时间不能跨天,最多就是一天的开始到结束,0:00 - 23:59:59; 通常应用都是搜索某一天的录像
- 不同设备类型对应的args和list
设备类型 | args | list |
---|---|---|
IVY IPC | IVYIO_GET_RECORD_LIST_ARGS_TYPE0 | IVY_RECORD_LIST_ARGS_TYPE0 |
IVY NVR | IVYIO_GET_RECORD_LIST_ARGS_TYPE0 | IVY_RECORD_LIST_ARGS_TYPE0 |
Foscam IPC | IVYIO_GET_RECORD_LIST_ARGS_TYPE2 | IVYIO_RECORD_LIST_ARGS_TYPE2 |
Foscam IPC (如果能力集val12中bit5支持) | IVYIO_GET_RECORD_LIST_ARGS_TYPE4 | IVYIO_RECORD_LIST_ARGS_TYPE4 |
Foscam NVR | IVYIO_GET_RECORD_LIST_ARGS_TYPE3 | IVYIO_RECORD_LIST_ARGS_TYPE3 |
- IVYIO_GET_RECORD_LIST_ARGS_TYPE0中type定义
录像类型 | 值 |
---|---|
手动录像 | 1 |
计划录像 | 2 |
移动报警录像 | 4 |
声音报警录像 | 8 |
IO报警录像 | 16 |
温度报警录像 | 32 |
湿度报警录像 | 64 |
人形侦测报警录像 | 128 |
一键报警录像 | 256 |
录像类型是按位表示的,如果要搜索多种类型的录像,请将 IVYIO_GET_RECORD_LIST_ARGS_TYPE0 结构的type按位设置
// Get play back records list
typedef struct _IVYIO_GET_RECORD_LIST_ARGS_TYPE0_
{
int getRecordListArgsType; // always set 0
unsigned long long sTime; // start time, timestamp, unit second
unsigned long long eTime; // end time, timestamp, unit second
int type; // record type
int startNo; // Start index for search recording
int cnt; // Search count, max 40;
} ATTRIBUTE_PACKED IVYIO_GET_RECORD_LIST_ARGS_TYPE0, *PIVYIO_GET_RECORD_LIST_ARGS_TYPE0;
// Play back records list
typedef struct _IVYIO_RECORD_INFO_TYPE0_ {
char channel;
unsigned long long sTime; // start time, timestamp, unit second
unsigned long long eTime; // end time, timestamp, unit second
unsigned int recordType; // record type, same as type in IVYIO_GET_RECORD_LIST_ARGS_TYPE0
} ATTRIBUTE_PACKED IVYIO_RECORD_INFO_TYPE0, *PIVYIO_RECORD_INFO_TYPE0;
typedef struct _IVYIO_RECORD_LIST_ARGS_TYPE0_
{
unsigned int totalCnt;
unsigned int curCnt;
IVYIO_RECORD_INFO_TYPE0 list[40];
} ATTRIBUTE_PACKED IVYIO_RECORD_LIST_ARGS_TYPE0, *PIVYIO_RECORD_LIST_ARGS_TYPE0;
- IVYIO_GET_RECORD_LIST_ARGS_TYPE2中recordType定义
录像类型 | 值 |
---|---|
计划录像 | 0 |
报警录像 | 1 |
全部录像 | 2 |
#define MAX_COUNT_OF_RECORD_FOS 10
#define MAX_LENGTH_OF_RECORD_FOS 256
typedef struct _IVYIO_GET_RECORD_LIST_ARGS_TYPE2_
{
int getRecordListArgsType; // always set 2
char recordPath[256]; // fill zero for each byte
unsigned int startTime; // Start time, UTC time, unit second
unsigned int endTime; // End time, UTC Time, unit second
int recordType; // 0:schedule 1:alarm 2:all
int startNo;
}ATTRIBUTE_PACKED IVYIO_GET_RECORD_LIST_ARGS_TYPE2, *PIVYIO_GET_RECORD_LIST_ARGS_TYPE2;
typedef struct _IVYIO_RECORD_LIST_ARGS_TYPE2_
{
int totalCnt; //total count.
int curCnt; //current count.
char recordInfo[MAX_COUNT_OF_RECORD_FOS][MAX_LENGTH_OF_RECORD_FOS];
}ATTRIBUTE_PACKED IVYIO_RECORD_LIST_ARGS_TYPE2, *PIVYIO_RECORD_LIST_ARGS_TYPE2;
- IVYIO_GET_RECORD_LIST_ARGS_TYPE4中recordType定义
录像类型 | 值 |
---|---|
计划录像 | 0x00000001 << 0 |
手动录像 | 0x00000001 << 1 |
移动报警录像 | 0x00000001 << 2 |
声音报警录像 | 0x00000001 << 3 |
IO报警录像 | 0x00000001 << 4 |
温度报警录像 | 0x00000001 << 5 |
湿度报警录像 | 0x00000001 << 6 |
人形报警录像 | 0x00000001 << 7 |
LIVECD录像 | 0x00000001 << 8 |
TM报警录像 | 0x00000001 << 9 |
按键报警录像 | 0x00000001 << 10 |
越线报警录像 | 0x00000001 << 11 |
留言报警录像 | 0x00000001 << 12 |
人脸报警录像 | 0x00000001 << 13 |
#define MAX_COUNT_OF_RECORD_FOS 10
#define MAX_LENGTH_OF_RECORD_FOS 256
typedef enum
{
IVYIO_FOS_RECORD_TYPE_V3_SCHEDULE = 0x00000001 << 0, // 计划
IVYIO_FOS_RECORD_TYPE_V3_MANUAL = 0x00000001 << 1, // 手动
IVYIO_FOS_RECORD_TYPE_V3_MDALARM = 0x00000001 << 2, // 移动报警
IVYIO_FOS_RECORD_TYPE_V3_SDALARM = 0x00000001 << 3, // 声音报警
IVYIO_FOS_RECORD_TYPE_V3_IOALARM = 0x00000001 << 4, // IO报警
IVYIO_FOS_RECORD_TYPE_V3_TDALARM = 0x00000001 << 5, // 温度
IVYIO_FOS_RECORD_TYPE_V3_HDALARM = 0x00000001 << 6, // 湿度
IVYIO_FOS_RECORD_TYPE_V3_HMALARM = 0x00000001 << 7, // 人形报警
IVYIO_FOS_RECORD_TYPE_V3_LIVERCD = 0x00000001 << 8,
IVYIO_FOS_RECORD_TYPE_V3_TMALARM = 0x00000001 << 9,
IVYIO_FOS_RECORD_TYPE_V3_BKALARM = 0x00000001 << 10, // 按键
IVYIO_FOS_RECORD_TYPE_V3_CLALARM = 0x00000001 << 11, // 越线
IVYIO_FOS_RECORD_TYPE_V3_LMALARM = 0x00000001 << 12, // 留言
IVYIO_FOS_RECORD_TYPE_V3_FDALARM = 0x00000001 << 13, // 人脸
IVYIO_FOS_RECORD_TYPE_V3_CRALARM = 0x00000001 << 15 // 车辆
} IVYIO_FOS_RECORD_TYPE_V3;
typedef struct _IVYIO_GET_RECORD_LIST_ARGS_TYPE4_
{
int getRecordListArgsType; // always 4
int recordPath; // Must be 0, SD card
unsigned int startTime; // timestamp, unit second
unsigned int endTime; // timestamp, unit second
int recordType; // See IVYIO_FOS_RECORD_TYPE_V3, each bit represents a record type
int startNo;
int cnt; // max 50
}ATTRIBUTE_PACKED IVYIO_GET_RECORD_LIST_ARGS_TYPE4, *PIVYIO_GET_RECORD_LIST_ARGS_TYPE4;
typedef struct _IVYIO_RECORD_INFO_TYPE4_
{
unsigned int startTime; // timestamp, unit second
unsigned int endTime; // timestamp, unit second
unsigned int recordType; // See IVYIO_FOS_RECORD_TYPE_V3
char fileName[256];
}ATTRIBUTE_PACKED IVYIO_RECORD_INFO_TYPE4, *PIVYIO_RECORD_INFO_TYPE4;
typedef struct _IVYIO_RECORD_LIST_ARGS_TYPE4_
{
int totalCnt;
int curCnt;
IVYIO_RECORD_INFO_TYPE4 list[50];
}ATTRIBUTE_PACKED IVYIO_RECORD_LIST_ARGS_TYPE4, *PIVYIO_RECORD_LIST_ARGS_TYPE4;
- IVYIO_GET_RECORD_LIST_ARGS_TYPE3中recordType定义
注意:1. Foscam NVR搜索的通道号按位表示,不要多个通道分开搜索,否则获取的数据只有最后一次搜索通道的内容;2. 为了优化搜索录像速度,只有当startNO为0的时候,SDK才会去搜索录像(FoscamNVR搜索录像接口会一次搜索出所有录像),如果不是0,只是单纯的去内存拿数据
录像类型 | 值 |
---|---|
计划录像 | 1 |
手动录像 | 2 |
移动报警录像 | 4 |
io报警录像 | 8 |
按位表示每一种录像,可同时搜索多种录像。
typedef struct _IVYIO_GET_RECORD_LIST_ARGS_TYPE3_
{
int getRecordListArgsType;
unsigned long long startTime; // unit is second, timestamp
unsigned long long endTime; // unit is second,timestamp
int recordType; // 1:schedule 2:manual 4:motion 8:ioalarm 1|2|4|8:all
int startNo;
}ATTRIBUTE_PACKED IVYIO_GET_RECORD_LIST_ARGS_TYPE3, *PIVYIO_GET_RECORD_LIST_ARGS_TYPE3;
typedef struct _IVYIO_RECORD_INFO_
{
unsigned int indexNO;
char channel;
unsigned int fileSize;
unsigned int tmStart;
unsigned int tmEnd;
char recordType;
}ATTRIBUTE_PACKED IVYIO_RECORD_INFO, *PIVYIO_RECORD_INFO;
typedef struct _IVYIO_RECORD_LIST_ARGS_TYPE3_
{
int total;
int curCnt;
IVYIO_RECORD_INFO recordInfo[MAX_COUNT_OF_RECORD_FOS];
}ATTRIBUTE_PACKED IVYIO_RECORD_LIST_ARGS_TYPE3, *PIVYIO_RECORD_LIST_ARGS_TYPE3;
- 调用示例
if (IVYIO_DEV_IPC == devType)
{
// IVY IPC
// Get all type of recording list from index 0
// Search recordings between 2021-04-28 00:00:00 - 2021-04-28 23:59:59
unsigned long long startUTCTime = 1619539200; // A day start
unsigned long long endUTCTime = 1619539200 + 24 * 60 * 60 - 1; // A day end
IVYIO_GET_RECORD_LIST_ARGS_TYPE0 get;
memset(&get, 0, sizeof(get));
get.getRecordListArgsType = 0;
get.sTime = startUTCTime;
get.eTime = endUTCTime;
get.startNo = 0;
get.cnt = 40;
get.type = 1 | 2 | 4 | 8;
IVYIO_RECORD_LIST_ARGS_TYPE0 list;
memset(&list, 0, sizeof(list));
IVYIO_RESULT rst = IVYIO_GetPlaybackRecordList(handle, &get, list, 1000 * 10, 0);
}
else if (IVYIO_DEV_NVR == devType)
{
// IVY NVR
// Get type '1/2/4/8' recording list from index 0
// Search recordings between 2021-04-28 00:00:00 - 2021-04-28 23:59:59 at channel0/1/2
unsigned long long startUTCTime = 1619539200; // A day start
unsigned long long endUTCTime = 1619539200 + 24 * 60 * 60; // A day end
IVYIO_GET_RECORD_LIST_ARGS_TYPE0 get;
memset(&get, 0, sizeof(get));
get.getRecordListArgsType = 0;
get.sTime = startUTCTime;
get.eTime = endUTCTime;
get.startNo = 0;
get.cnt = 40;
get.type = 1 | 2 | 4 | 8;
IVYIO_RECORD_LIST_ARGS_TYPE0 list;
memset(&list, 0, sizeof(list));
IVYIO_RESULT rst = IVYIO_GetPlaybackRecordList(handle, &get, list, 1000 * 10, 0x07);
}
else if (IVYIO_DEV_FOS_IPC == devType)
{
// Foscam IPC
if (Ability_val12_bit5_support())
{
IVYIO_GET_RECORD_LIST_ARGS_TYPE4 get;
memset(&get, 0, sizeof(get));
get.getRecordListArgsType = 4;
get.recordPath = 0;
get.startTime = 1619539200; // 2021-04-28 00:00:00
get.endTime = 1619539200 + 24 * 60 * 60 - 1; // 2021-04-28 23:59:59
get.recordType = IVYIO_FOS_RECORD_TYPE_V3_SCHEDULE | IVYIO_FOS_RECORD_TYPE_V3_MANUAL | IVYIO_FOS_RECORD_TYPE_V3_MDALARM | IVYIO_FOS_RECORD_TYPE_V3_SDALARM;
get.startNo = 10; // From index 10
get.cnt = 50;
IVYIO_RECORD_LIST_ARGS_TYPE4 list;
memset(&list, 0, sizeof(list));
IVYIO_RESULT rst = IVYIO_GetPlaybackRecordList(handle, &get, list, 1000 * 10, 0);
}
else
{
// All Foscam IPC support
IVYIO_GET_RECORD_LIST_ARGS_TYPE2 get;
memset(&get, 0, sizeof(get));
get.getRecordListArgsType = 2;
get.startTime = 1619539200; // 2021-04-28 00:00:00
get.endTime = 1619539200 + 24 * 60 * 60 - 1; // 2021-04-28 23:59:59
get.recordType = 2; // all type
get.startNo = 10; // From index 10
IVYIO_RECORD_LIST_ARGS_TYPE2 list;
memset(&list, 0, sizeof(list));
IVYIO_RESULT rst = IVYIO_GetPlaybackRecordList(handle, &get, list, 1000 * 10, 0);
}
}
else if (IVYIO_DEV_FOS_NVR == devType)
{
// Foscam NVR
// Get all type of recordings on channel0/1/2
IVYIO_GET_RECORD_LIST_ARGS_TYPE3 get;
get.getRecordListArgsType = 3;
get.startTime = 1619539200; // 2021-04-28 00:00:00
get.endTime = 1619539200 + 24 * 60 * 60 - 1; // 2021-04-28 23:59:59
get.recordType = 1 | 2 | 4 | 8; // All type recordings
get.startNo = 0;
IVYIO_RECORD_LIST_ARGS_TYPE3 list;
memset(&list, 0, sizeof(list));
IVYIO_RESULT rst = IVYIO_GetPlaybackRecordList(handle, &get, list, 1000 * 10, 0x07);
}
7.2 打开回放
- 描述
打开录像,不同的设备类型,有不同的参数
IVYIO_RESULT IVYIO_API IVYIO_OpenPlayback(IVYIO_HANDLE handle, void *args, int iTimeout, int iChannel)
- 参数
handle | SDK句柄 |
---|---|
args | 指向打开回放结构体的指针 |
iTimeout | 超时,单位ms |
iChannel | 通道号,同打开视频 |
- 返回值
操作结果
- 备注
- 打开回放和打开直播采用同样的方式,关于回放的音视频缓冲区和解码器都是在打开的时候申请的,在关闭的时候释放掉。
- Foscam NVR 使用 IVYIO_OPEN_PLAY_BACK_ARGS_TYPE2的sTime和eTime表示要打开录像时间范围,offsetTime是范围中的一个时间,表示从这个时间开始播放。一般其实时间都是某一天的开始和结束时间。
- 如果是FoscamNVR,我们建议打开一整天的录像,这样数据流就会将一整天的数据给过来,很方便。
- 注意
请一定保持 IVYIO_OpenVideo / IVYIO_CloseVideo / IVYIO_OpenPlaybackEx / IVYIO_OpenPlayback / IVYIO_ClosePlayback 之间串行调用,不可并行调用,否则可能会出现获取不到直播或者回放视频流的情况,主要因为这几个接口有状态的维护。
- args对应的结构体类型
设备类型 | args |
---|---|
Foscam IPC | 字符串,一个SD卡录像地址 |
Foscam Doorbell | 字符串,一个SD卡录像地址 |
Foscam NVR | IVYIO_OPEN_PLAY_BACK_ARGS_TYPE2 |
IVY IPC | IVYIO_OPEN_PLAY_BACK_ARGS_TYPE0 |
IVY NVR | IVYIO_OPEN_PLAY_BACK_ARGS_TYPE0 |
如果当前设备是IPC,iChannel值的设置请参考OpenVideo
- 结构体定义
typedef struct _IVYIO_OPEN_PLAY_BACK_ARGS_TYPE2_
{
int openPlaybackArgsType; // always 2
unsigned int sTime; // Search recording start time
unsigned int eTime; // Search recording end time
unsigned int offsetTime; // Time between in start time and end time
int videoMode; // always set 0
}ATTRIBUTE_PACKED IVYIO_OPEN_PLAY_BACK_ARGS_TYPE2, *PIVYIO_OPEN_PLAY_BACK_ARGS_TYPE2;
typedef struct _IVYIO_OPEN_PLAY_BACK_ARGS_TYPE0_
{
int openPlaybackArgsType; // always 0
unsigned long long sTime; // Search recording start time
unsigned long long eTime; // Search recording end time
int streamType; // 0:main 1:sub
}ATTRIBUTE_PACKED IVYIO_OPEN_PLAY_BACK_ARGS_TYPE0, *PIVYIO_OPEN_PLAY_BACK_ARGS_TYPE0;
- 调用示例
if (IVYIO_DEV_FOS_IPC == devType || IVYIO_DEV_FOS_DOORBELL == devType)
{
// Foscam IPC
if (Ability_val12_bit5_support())
{
IVYIO_GET_RECORD_LIST_ARGS_TYPE4 get;
memset(&get, 0, sizeof(get));
get.getRecordListArgsType = 4;
get.recordPath = 0;
get.startTime = 1619539200;
get.endTime = 1619539200 + 24 * 60 * 60 - 1;
get.recordType = IVYIO_FOS_RECORD_TYPE_V3_SCHEDULE | IVYIO_FOS_RECORD_TYPE_V3_MANUAL | IVYIO_FOS_RECORD_TYPE_V3_MDALARM | IVYIO_FOS_RECORD_TYPE_V3_SDALARM;
get.startNo = 10; // From index 10
get.cnt = 50;
IVYIO_RECORD_LIST_ARGS_TYPE4 list;
memset(&list, 0, sizeof(list));
if (IVYIO_RESULT_OK == IVYIO_GetPlaybackRecordList(handle, &get, list, 1000 * 10, 0))
{
rst = IVYIO_OpenPlayback(handle, list.list[0], 1000 * 5, 0);
}
}
else
{
// All Foscam IPC support
IVYIO_GET_RECORD_LIST_ARGS_TYPE2 get;
memset(&get, 0, sizeof(get));
get.getRecordListArgsType = 2;
get.startTime = 1619539200; // 2021-04-28 00:00:00
get.endTime = 1619539200 + 24 * 60 * 60 - 1; // 2021-04-28 23:59:59
get.recordType = 2; // all type
get.startNo = 10; // From index 10
IVYIO_RECORD_LIST_ARGS_TYPE2 list;
memset(&list, 0, sizeof(list));
if (IVYIO_RESULT_OK == IVYIO_GetPlaybackRecordList(handle, &get, list, 1000 * 10, 0))
{
rst = IVYIO_OpenPlayback(handle, list.recordInfo[0], 1000 * 5, 0);
}
}
}
else if (IVYIO_DEV_FOS_NVR == devType)
{
IVYIO_GET_RECORD_LIST_ARGS_TYPE3 get;
get.getRecordListArgsType = 3;
get.startTime = 1619539200; // 2021-04-28 00:00:00
get.endTime = 1619539200 + 24 * 60 * 60 - 1; // 2021-04-28 23:59:59
get.recordType = 1 | 2 | 4 | 8; // All type recordings
get.startNo = 0;
#ifdef _WE_SUGGEST
// Open all day of recordings
IVYIO_RECORD_LIST_ARGS_TYPE3 list;
memset(&list, 0, sizeof(list));
if (IVYIO_RSULT_OK == IVYIO_GetPlaybackRecordList(handle, &get, list, 1000 * 10, 0x07))
{
// Open channel 0 and channel 1
IVYIO_OPEN_PLAY_BACK_ARGS_TYPE2 open;
open.openPlaybackArgsType = 2;
open.sTime = 1619539200; // 2021-04-28 00:00:00
open.eTime = 1619539200 + 24 * 60 * 60 - 1; // 2021-04-28 23:59:59
open.offsetTime = 0;
open.videoMode = 0;
rst = IVYIO_OpenPlayback(handle, &open, 1000 * 5, 0x07);
}
#else
// Open one recording
IVYIO_RECORD_LIST_ARGS_TYPE3 list;
memset(&list, 0, sizeof(list));
if (IVYIO_RSULT_OK == IVYIO_GetPlaybackRecordList(handle, &get, list, 1000 * 10, 0x07))
{
// Open channel 0 and channel 1
IVYIO_OPEN_PLAY_BACK_ARGS_TYPE2 open;
open.openPlaybackArgsType = 2;
open.sTime = list.recordInfo[0].tmStart;
open.eTime = list.recordInfo[0].tmEnd;
open.offsetTime = 0;
open.videoMode = 0;
rst = IVYIO_OpenPlayback(handle, &open, 1000 * 5, 0x07);
}
#endif
}
else if (IVY_DEV_IPC == devType)
{
IVYIO_GET_RECORD_LIST_ARGS_TYPE0 get;
memset(&get, 0, sizeof(get));
get.getRecordListArgsType = 0;
get.sTime = 1619539200;
get.eTime = 1619539200 + 24 * 60 * 60 - 1;
get.startNo = 0;
get.cnt = 40;
get.type = 1 | 2 | 4 | 8;
IVYIO_RECORD_LIST_ARGS_TYPE0 list;
memset(&list, 0, sizeof(list));
if (IVYIO_RESULT_OK == IVYIO_GetPlaybackRecordList(handle, &get, list, 1000 * 10, 0))
{
IVYIO_OPEN_PLAY_BACK_ARGS_TYPE0 open;
open.openPlaybackArgsType = 0;
open.sTime = list.list[0].sTime;
open.eTime = list.list[0].eTime;
open.streamType = 0; // main stream
rst = IVYIO_OpenPlayback(handle, &open, 1000 * 5, 0);
}
}
else if (IVY_DEV_NVR == devType)
{
IVYIO_GET_RECORD_LIST_ARGS_TYPE0 get;
memset(&get, 0, sizeof(get));
get.getRecordListArgsType = 0;
get.sTime = 1619539200;
get.eTime = 1619539200 + 24 * 60 * 60 - 1;
get.startNo = 0;
get.cnt = 40;
get.type = 1 | 2 | 4 | 8;
IVYIO_RECORD_LIST_ARGS_TYPE0 list;
memset(&list, 0, sizeof(list));
if (IVYIO_RESULT_OK == IVYIO_GetPlaybackRecordList(handle, &get, list, 1000 * 10, 0x07))
{
IVYIO_OPEN_PLAY_BACK_ARGS_TYPE0 open;
open.openPlaybackArgsType = 0;
open.sTime = list.list[0].sTime;
open.eTime = list.list[0].eTime;
open.streamType = 0; // main stream
rst = IVYIO_OpenPlayback(handle, &open, 1000 * 5, 0x07);
}
}
7.3 关闭回放
- 关闭回放
IVYIO_RESULT IVYIO_API IVYIO_ClosePlayback(IVYIO_HANDLE handle, void *args, int iTimeout, int iChannel)
- 参数
handle | SDK句柄 |
---|---|
args | 指向关闭回放结构体指针 |
iTimeout | 超时,单位ms |
iChannel | 通道号 |
- 返回值
操作结果
- args参数结构体如下
设备类型 | args |
---|---|
Foscam IPC | none |
Foscam NVR | none |
Foscam DoorBell | none |
IVY IPC | IVYIO_CLOSE_PLAY_BACK_ARGS_TYPE0 |
IVY NVR | IVYIO_CLOSE_PLAY_BACK_ARGS_TYPE0 |
如果是IPC设备,无论是Foscam还是IVY,iChannel的值要和OpenPlayback一致
- 注意
请一定保持 IVYIO_OpenVideo / IVYIO_CloseVideo / IVYIO_OpenPlaybackEx / IVYIO_OpenPlayback / IVYIO_ClosePlayback 之间串行调用,不可并行调用,否则可能会出现获取不到直播或者回放视频流的情况,主要因为这几个接口有状态的维护。
- 调用示例
if (IVYIO_DEV_FOS_IPC == devType || IVYIO_DEV_FOS_DOORBELL == devType || IVYIO_DEV_FOS_NVR == devType)
{
IVYIO_RESULT rst = IVYIO_ClosePlayback(handle, NULL, 1000 * 5, 0);
}
else if (IVYIO_DEV_NVR == devType || IVYIO_DEV_IPC == devType)
{
IVYIO_CLOSE_PLAY_BACK_ARGS_TYPE0 close;
close.openPlaybackArgsType = 0;
IVYIO_RESULT rst = IVYIO_ClosePlayback(handle, &close, 1000 * 5, 0);
}
7.4 回放控制
- 描述
回放控制
IVYIO_RESULT IVYIO_API IVYIO_PlaybackCmdEx(IVYIO_HANDLE handle, IVYIO_PLAYBACK_CMD cmd, unsigned char *cmdData, unsigned char *outData, int *sizeOfOutData, int iTimeout, int iChannel)
- 参数
handle | SDK句柄 |
---|---|
cmd | 0:回放暂停 1:回放恢复 2:SEEK回放 3: 快放 4:慢放 5:倒放(3-5目前只有Foscam NVR支持) |
cmdData | 命令对应的数据结构 |
outData | 返回数据内存 |
sizeOfOutData | 返回数据的长度 |
iTimeout | 超时,单位ms |
iChannel | 通道号0-31,一次只能操作一个通道,如果要打开通道0,iChannel为0,如果要打开通道1,iChannel为1 |
- 返回值
操作结果
1. 如果是IPC,不需要通道,如果是NVR,当前接口所有命令是针对所有的通道。
- 注意事项
1. 对于SEEK操作,Foscam IPC会返回真实的SEEK时间; 其他设备不会返回。
2. 只有Foscam NVR 支持快放/慢放/倒放操作,其他设备不支持。
3. Foscam NVR打开录像最好是从一天的开始到结束,这样我们看任意时刻录像只需要SEEK即可,不需要重新打开回放。
其他设备必须按搜索到的录像时间或者路径来打开,因此SEEK只能实在打开的录像段时间内,如果是另外一段录像,必须要重新打开。
typedef enum
{
IVYIO_PLAYBACK_CMD_PAUSE = 0,
IVYIO_PLAYBACK_CMD_RESUME = 1,
IVYIO_PLAYBACK_CMD_SEEK = 2,
IVYIO_PLAYBACK_CMD_FAST_FORWARD = 3,
IVYIO_PLAYBACK_CMD_SLOW_FORWARD = 4,
IVYIO_PLAYBACK_CMD_FAST_REVERSE = 5
}IVYIO_PLAYBACK_CMD;
不同设备支持的回放命令
Foscam IPC
命令 | 是否支持该命令 | cmdData结构 | outData 结构 |
---|---|---|---|
0 | YES | ignore | ignore |
1 | YES | ignore | ignore |
2 | YES | 无符号整型数据指针, 表示要SEEK的时间 | 无符号整型数据指针;表示设备返回的真实seek时间,应用传入的SEEK时间对于设备来说只是近似的时间,设备会返回一个真实的时间,应用应该以返回的SEEK为准 |
3 | NO | ||
4 | NO | ||
5 | NO |
- Foscam NVR
命令 | 是否支持该命令 | cmdData结构 | outData 结构 |
---|---|---|---|
0 | YES | IVYIO_PLAY_BACK_PAUSE_TYPE0 | ignore |
1 | YES | IVYIO_PLAY_BACK_RESUME_TYPE0 | ignore |
2 | YES | 无符号整型数据指针, SEEK时间,时间单位是秒,比如,当前 00:00:00 - 23:59:59,SEEK的值就是中间的某一时间点的时间戳 | ignore |
3 | YES | IVYIO_FOS_NVR_PLAY_BACK_CMD_VALUE | ignore |
4 | YES | IVYIO_FOS_NVR_PLAY_BACK_CMD_VALUE | ignore |
5 | YES | IVYIO_FOS_NVR_PLAY_BACK_CMD_VALUE | ignore |
// Foscam NVR fast/slow-forward/fast-reverse
// fast forward: 4x, 8x, 16x, 32 -> value: 4, 8, 16, 32
// slow fowward: 1/2x, 1/4x, 1/8x, 1/16x, 1/32x -> value: 2, 4, 8, 16, 32
// fast reverse: 4x, 8x, 16x, 32 -> value: 4, 8, 16, 32
typedef struct _IVYIO_FOS_NVR_PLAY_BACK_CMD_VALUE_
{
unsigned int time; // start time, unit second
int value; // cmd value
}ATTRIBUTE_PACKED IVYIO_FOS_NVR_PLAY_BACK_CMD_VALUE, *PIVYIO_FOS_NVR_PLAY_BACK_CMD_VALUE;
- IVYIO_FOS_NVR_PLAY_BACK_CMD_VALUE.value 数据描述:
PLAYBACK_CMD_FAST_FORWARD | 支持(4/8/16/32倍),对应值位4/8/16/32 |
---|---|
PLAYBACK_CMD_SLOW_FORWARD | 支持(2/4/8/16/32倍),对应值位2/4/8/16/32 |
PLAYBACK_CMD_FAST_REVERSE | 支持(4/8/16/32倍),对应值位4/8/16/32 |
对于Foscam NVR,如果已经快放/慢放/倒放,想回复正常,调用PLAYBACK_CMD_FAST_FORWARD,指定时间,设置value为1
- IVY IPC / IVY NVR
命令 | 是否支持该命令 | cmdData结构 | outData 结构 |
---|---|---|---|
0 | YES | IVYIO_PLAY_BACK_PAUSE_TYPE0 | ignore |
1 | YES | IVYIO_PLAY_BACK_RESUME_TYPE0 | ignore |
2 | YES | IVYIO_PLAY_BACK_SEEK_ARGS_TYPE0(IPC:毫秒 NVR:秒) | ignore |
3 | YES | IVYIO_PLAY_BACK_FAST_FORWARD_ARGS_TYPE0 | ignore |
4 | NO | ||
5 | NO |
- IVYIO_PLAY_BACK_FAST_FORWARD_ARGS_TYPE0.value 数据描述:
IVYIO_PLAYBACK_CMD_FAST_FORWARD | 支持(2/4/8/16/32倍),对应值 2/4/8/16/32 |
---|
typedef struct _IVYIO_PLAY_BACK_SEEK_ARGS_TYPE0_
{
int openPlaybackArgsType; // always 0
unsigned long long time; // 捷高单位 s,雷神 ms
}ATTRIBUTE_PACKED IVYIO_PLAY_BACK_SEEK_ARGS_TYPE0, *PIVYIO_PLAY_BACK_SEEK_ARGS_TYPE0;
typedef struct _IVYIO_PLAY_BACK_PAUSE_TYPE0_
{
int openPlaybackArgsType; // always 0
}ATTRIBUTE_PACKED IVYIO_PLAY_BACK_PAUSE_TYPE0, *PIVYIO_PLAY_BACK_PAUSE_TYPE0;
typedef struct _IVYIO_PLAY_BACK_RESUME_TYPE0_
{
int openPlaybackArgsType; // always 0
}ATTRIBUTE_PACKED IVYIO_PLAY_BACK_RESUME_TYPE0, *PIVYIO_PLAY_BACK_RESUME_TYPE0;
typedef struct _IVYIO_PLAY_BACK_FAST_FORWARD_ARGS_TYPE0_
{
int openPlaybackArgsType;
int value;
}ATTRIBUTE_PACKED IVYIO_PLAY_BACK_FAST_FORWARD_ARGS_TYPE0, *PIVYIO_PLAY_BACK_FAST_FORWARD_ARGS_TYPE0;
- 调用示例
if (IVYIO_DEV_FOS_IPC == devType || IVYIO_DEV_FOS_DOORBELL == devType)
{
// Pause
// Device will stop send playback data
IVYIO_RESULT rst = IVYIO_PlaybackCmdEx(handle, IVYIO_PLAYBACK_CMD_PAUSE, NULL, NULL, NULL, 1000 * 5, 0);
......
// Resume
// Device will send playback data again
rst = IVYIO_PlaybackCmdEx(handle, IVYIO_PLAYBACK_CMD_RESUME, NULL, NULL, NULL, 1000 * 5, 0);
......
// Seek
// 2021/4/29 1:00:00 timestamp is 1619629200
// 2021/4/29 2:00:00 timestamp is 1619632800
// 2021/4/29 1:30:00 timestamp is 1619631000
// if one recording start time is 1:00:00 and end time is 2:00:00, want to seek to 1:30:00
unsigned int seekTime = 1619631000;
unsigned int actualSeekTime = 0;
rst = IVYIO_PlaybackCmdEx(handle, IVYIO_PLAYBACK_CMD_SEEK, &seekTime, &actualSeekTime, sizeof(unsigned int), 1000 * 5, 0);
}
if (IVYIO_DEV_FOS_NVR == devType)
{
// Pause
// Device will stop send playback data on all channels, we can ignore channel
IVYIO_RESULT rst = IVYIO_PlaybackCmdEx(handle, IVYIO_PLAYBACK_CMD_PAUSE, NULL, NULL, NULL, 1000 * 5, 0);
......
// Resume
// Device will send playback data again on all channels, we can ignore channel
rst = IVYIO_PlaybackCmdEx(handle, IVYIO_PLAYBACK_CMD_RESUME, NULL, NULL, NULL, 1000 * 5, 0);
......
// Seek
// 2021-04-28 00:00:00 start timestamp 1619539200
// 2021-04-28 23:59:59 end timestamp 1619539200 + 24 * 60 * 60 - 1
// For Foscam NVR we open playback all day (00:00:00-23:59:59)usually,then we can seek any time instead of opening playback other time.
// This will seek to the time on all channels, we can ignore channel
unsigned int seekTime = 1619631000;
rst = IVYIO_PlaybackCmdEx(handle, IVYIO_PLAYBACK_CMD_SEEK, &seekTime, NULL, 0, 1000 * 5, 0);
......
// Fast forward on all channels, we can ignore channels
// 32x for timestamp 1619539200 (2021-04-28 00:00:00)
IVYIO_FOS_NVR_PLAY_BACK_CMD_VALUE fastForward;
fastForward.time = 1619539200;
fastForward.value = 32;
rst = IVYIO_PlaybackCmdEx(handle, IVYIO_PLAYBACK_CMD_FAST_FORWARD, &fastForward, NULL, sizeof(unsigned int), 1000 * 5, 0);
......
// Slow forward on all channels, we can ignore channels
// 16x for timestamp 1619539200 (2021-04-28 00:00:00)
IVYIO_FOS_NVR_PLAY_BACK_CMD_VALUE slowForward;
slowForward.time = 1619539200;
slowForward.value = 16;
rst = IVYIO_PlaybackCmdEx(handle, IVYIO_PLAYBACK_CMD_SLOW_FORWARD, &slowForward, NULL, sizeof(unsigned int), 1000 * 5, 0);
......
// Fast reverse on all channels, we can ignore channels
// 8x for timestamp 1619539200 (2021-04-28 00:00:00)
IVYIO_FOS_NVR_PLAY_BACK_CMD_VALUE fastReverse;
fastReverse.time = 1619539200;
fastReverse.value = 8;
rst = IVYIO_PlaybackCmdEx(handle, IVYIO_PLAYBACK_CMD_FAST_REVERSE, &fastReverse, NULL, sizeof(unsigned int), 1000 * 5, 0);
}
else if (IVYIO_DEV_IPC == devType)
{
// Pause
// Device will stop send playback data
IVYIO_PLAY_BACK_PAUSE_TYPE0 pause;
pause.openPlaybackArgsType = 0;
IVYIO_RESULT rst = IVYIO_PlaybackCmdEx(handle, IVYIO_PLAYBACK_CMD_PAUSE, &pause, NULL, NULL, 1000 * 5, 0);
......
// Resume
// Device will send playback data again
IVYIO_PLAY_BACK_RESUME_TYPE0 resume;
resume.openPlaybackArgsType = 0;
rst = IVYIO_PlaybackCmdEx(handle, IVYIO_PLAYBACK_CMD_RESUME, &resume, NULL, NULL, 1000 * 5, 0);
......
// Seek
// 2021/4/29 1:00:00 timestamp is 1619629200
// 2021/4/29 2:00:00 timestamp is 1619632800
// 2021/4/29 1:30:00 timestamp is 1619631000
// if one recording start time is 1:00:00 and end time is 2:00:00, want to seek to 1:30:00
IVYIO_PLAY_BACK_SEEK_ARGS_TYPE0 seek;
seek.openPlaybackArgsType = 0;
seek.time = 1619631000;
rst = IVYIO_PlaybackCmdEx(handle, IVYIO_PLAYBACK_CMD_RESUME, &seek, NULL, NULL, 1000 * 5, 0);
}
else if (IVYIO_DEV_NVR == devType)
{
// If devcies is online on channel 0 / 1 / 2
// Pause
// Device will stop send playback data on channel 0 / 1 / 2
IVYIO_PLAY_BACK_PAUSE_TYPE0 pause;
pause.openPlaybackArgsType = 0;
IVYIO_RESULT rst = IVYIO_PlaybackCmdEx(handle, IVYIO_PLAYBACK_CMD_PAUSE, &pause, NULL, NULL, 1000 * 5, 0x07);
......
// Resume
// Device will send playback data again on channel 0 / 1 / 2
IVYIO_PLAY_BACK_RESUME_TYPE0 resume;
resume.openPlaybackArgsType = 0;
rst = IVYIO_PlaybackCmdEx(handle, IVYIO_PLAYBACK_CMD_RESUME, &resume, NULL, NULL, 1000 * 5, 0x07);
......
// Seek
// 2021/4/29 1:00:00 timestamp is 1619629200
// 2021/4/29 2:00:00 timestamp is 1619632800
// 2021/4/29 1:30:00 timestamp is 1619631000
// if one recording start time is 1:00:00 and end time is 2:00:00, want to seek to 1:30:00
IVYIO_PLAY_BACK_SEEK_ARGS_TYPE0 seek;
seek.openPlaybackArgsType = 0;
seek.time = 1619631000;
rst = IVYIO_PlaybackCmdEx(handle, IVYIO_PLAYBACK_CMD_RESUME, &seek, NULL, NULL, 1000 * 5, 0x07);
}
7.5 开始回放录像下载(IVY设备)
- 描述
下载录像,该API只能下载IVY IPC 和 IVY NVR录像。
注意:打开回放和录像下载不能同时进行
IVYIO_RESULT IVYIO_API IVYIO_DownLoadRecord(IVYIO_HANDLE handle, IVYIO_DOWNLOAD_RECORD *records, const char *dstPath, int timeout)
- 参数
handle | SDK句柄 |
---|---|
records | 指向IVYIO_DOWNLOAD_RECORD结构的指针。所需参数可以从搜索录像的接口中获取 |
dstPath | 目的路经,不需要包含文件名,SDK内部会自动生成文件名 |
timeout | 超时 |
typedef struct _IVYIO_DOWNLOAD_RECORD_
{
unsigned int channel; // 0-31 means channel 0 - 31
unsigned int startTime; // recording start time, you can get it from getPlaybackRecordlist api
unsigned int endTime; // recording end time, you can get it from getPlaybackRecordlist api
unsigned int recordType; // see IVY device record type define in IVYIO_GetPlaybackRecordList
}ATTRIBUTE_PACKED IVYIO_DOWNLOAD_RECORD, *PIVYIO_DOWNLOAD_RECORD;
- 返回值
操作结果
- 产生事件
2063 | 录像进度事件 |
---|
- 备注
此接口只支持IVY设备和FoscamNVR设备,其他设备不支持。
对于IV设备,一次只能下载一个录像,不能并行下载,如果当前录像没有下载完成,接口返回
IVYIO_RESULT_DOWNLOADING(17),下载进度事件 IVY_CTRL_MSG_RECORD_DOWNLOAD_PROGRESS(2063)。设备每发送完一个录像数据,会断开下载连接,所以每个一个录像都需要调用一次下载接口。因为每次调用时SDK会去进行连接。
如果录像下载进度达到100%,不要调用IVYIO_DownLoadCannel。反之,如果录像下载没有达到100%,可以调用,并且下载的部分录像是可以播放的。
- 调用示例
IVYIO_DOWNLOAD_RECORD record;
if(IVYIO_DEV_IPC == devType)
{
record.channel = 0;
record.startTime = 1619751051; // 2021-04-30 10:50:51
record.endTime = 1619751171; // 2021-04-30 10:52:51
record.recordType = 4; // motion detected record
}
else if (IVYIO_DEV_NVR == devType)
{
record.channel = 2; // Download channel 2 recording
record.startTime = 1619751051; // 2021-04-30 10:50:51
record.endTime = 1619751171; // 2021-04-30 10:52:51
record.recordType = 4; // motion detected record
}
#ifdef _WIN32
IVYIO_RESULT rst = IVYIO_DownLoadRecord(handle, &record, "C:\\record.mp4", 1000 * 5);
#else
IVYIO_RESULT rst = IVYIO_DownLoadRecord(handle, &record, "/record/record.mp4", 1000 * 5);
#endif
if (IVYIO_RESULT_OK != rst)
IVYIO_DownLoadCannel();
// Another thread get event
IVYIO_EVENT event;
memset(&event, 0, event);
if (IVYIO_RESULT_OK == IVYIO_GetEvent(handle, &event))
{
if (2063 == event.id)
{
// event.data is json data for prgress, you can parse it.
}
}
#endif
7.6 取消回放录像下载(IVY设备)
- 描述
取消录像下载,如果下载录像进度已经到达100%,不需要调用此接口。如果没有达到,调用此接口后,部分下载的录像也可以播放。
IVYIO_RESULT IVYIO_API IVYIO_DownLoadCancel(IVYIO_HANDLE handle)
- 参数
handle | SDK句柄 |
---|
- 返回值
操作结果
- 备注
此接口只支持IVY设备和FoscamNVR设备,其他设备不支持。
对于IVY设备,取消录像下载SDK没有向设备发送任何命令,只是断开下载连接。当再次调用下载接口时SDK内部会再次去连接下载通道。
- 调用示例
// You can see the chapter 7.5
7.7 开始回放录像下载(FosamIPC)
- 描述
下载 FoscamIPC SD卡录像
注意:打开回放和录像下载不能同时进行
IVYIO_RESULT IVYIO_API IVYIO_DownLoadFosIPCRecord(IVYIO_HANDLE handle, const char *srcPath, const char *dstPath, int timeout)
- 参数
handle | SDK句柄 |
---|---|
srcPath | 录像源路径,可以通过GetPlayBackRecordList获取 |
dstPath | 要保存的路径 |
timeout | 超时时间 |
- 返回值
操作结果
- 产生事件
2063 | 录像进度事件 |
---|
- 备注
此接口只支持FoscamIPC,其他设备均不支持。保存的录像格式是MP4
可以通过事件获取下载进度,SDK每收到一个视频帧都会给出一个进度,因此进度可能会有重复,上层需要对重复进度做一些处理。(每一个视频帧都有一个进度是因为如果视频帧数很多,会有很久才会有进度的情况)
如果进度值100,不需要调用取消接口。
- 调用示例
if(IVYIO_DEV_FOS_IPC == devType || IVYIO_DEV_FOS_DOORBELL == devType)
{
// srcPath 来自 IVYIO_RECORD_LIST_ARGS_TYPE2的recordInfo或者
// IVYIO_RECORD_LIST_ARGS_TYPE4中list的fileName
char szPath[512] = {0};
strcpy(szPath, ......);
#ifdef _WIN32
IVYIO_RESULT rst = IVYIO_DownLoadFosIPCRecord(handle, szPath, "C:\\record.mp4", 1000 * 5);
#else
IVYIO_RESULT rst = IVYIO_DownLoadFosIPCRecord(handle, szPath, "/record/record.mp4", 1000 * 5);
#endif
if (IVYIO_RESULT_OK != rst)
IVYIO_DownLoadFosIPCRecordCancel();
}
// Another thread get event
IVYIO_EVENT event;
memset(&event, 0, event);
if (IVYIO_RESULT_OK == IVYIO_GetEvent(handle, &event))
{
if (2063 == event.id)
{
// event.data is json data for prgress, you can parse it.
}
}
#endif
7.8 取消回放录像下载(FosamIPC)
- 描述
取消 FoscamIPC SD卡录像
IVYIO_RESULT IVYIO_API IVYIO_DownLoadFosIPCRecordCancel(IVYIO_HANDLE handle, int timeout)
- 参数
handle | SDK句柄 |
---|---|
timeout | 超时时间 |
- 返回值
操作结果
- 备注
此接口只支持FoscamIPC,其他设备均不支持。
如果录像没有下载完成,已经下载的部分有合法的视频数据,调用此接口后文件可以正常播放。
- 调用示例
// You can see the chapter 7.7
7.9 开始回放录像下载(FosamNVR)
- 描述
下载FoscamNVR硬盘录像
注意:打开回放和录像下载不能同时进行
IVYIO_RESULT IVYIO_API IVYIO_DownLoadFosNVRRecord(IVYIO_HANDLE handle, IVYIO_RECORD_INFO *record, const char *dstPath, int count)
- 参数
handle | SDK句柄 |
---|---|
record | IVYIO_RECORD_INFO 结构体指针, 结构体内所有数据均来自IVYIO_GetPlaybackRecordList结果中的 IVYIO_RECORD_LIST_ARGS_TYPE3 |
dstPath | 要保存的路径,只要路径,不要文件名,会自动生成文件名字 |
count | 下载文件个数,也表明record指针对象个数 |
typedef struct _IVYIO_RECORD_INFO_
{
unsigned int indexNO;
char channel;
unsigned int fileSize;
unsigned int tmStart;
unsigned int tmEnd;
char recordType;
}ATTRIBUTE_PACKED IVYIO_RECORD_INFO, *PIVYIO_RECORD_INFO;
- 返回值
操作结果
- 产生事件
2063 | 录像进度事件 |
---|
- 备注
无论一次下载多个文件还是一个文件,进度值都表示本次调用下载接口后的整体进度。
- 调用示例
if(IVYIO_DEV_FOS_NVR == devType)
{
IVYIO_RECORD_LIST_ARGS_TYPE3 list;
// Get recording list
......
// Download 10 recordings
for (int i = 0; i < 10; i++)
{
record[i].indexNO = list.recordInfo[i].indexNo;
record[i].channel = list.recordInfo[i].channel;
record[i].fileSize = list.recordInfo[i].fileSize;
record[i].tmStart = list.recordInfo[i].tmStart;
record[i].tmEnd = list.recordInfo[i].tmEnd;
record[i].recordType = list.recordInfo[i].recordType;
}
#ifdef _WIN32
IVYIO_RESULT rst = IVYIO_DownLoadFosNVRRecord(handle, record, "C:\\record", 10);
#else
IVYIO_RESULT rst = IVYIO_DownLoadFosNVRRecord(handle, record, "/record/", 10);
#endif
if (IVYIO_RESULT_OK != rst)
IVYIO_DownloadFosNVRCancel(handle);
}
// Another thread get event
IVYIO_EVENT event;
memset(&event, 0, event);
if (IVYIO_RESULT_OK == IVYIO_GetEvent(handle, &event))
{
if (2063 == event.id)
{
// event.data is json data for prgress, you can parse it.
}
}
#endif
7.10 取消回放录像下载(FosamNVR)
- 描述
取消 FoscamIPC SD卡录像
IVYIO_RESULT IVYIO_API IVYIO_DownloadFosNVRCancel(IVYIO_HANDLE handle)
- 参数
handle | SDK句柄 |
---|
- 返回值
操作结果
- 备注
此接口只支持FoscamNVR,其他设备均不支持。
- 调用示例
// You can see the chapter 7.9
8. 获取直播/回放视频音频数据
8.1 获取直播已经解码后的数据
- 描述
获取直播已经解码后的数据
IVYIO_RESULT IVYIO_API IVYIO_GetStreamData(IVYIO_HANDLE handle, IVYIO_STREAM_TYPE stream, unsigned char **data, int *iOutLen, int *iSpeed, int iDecodeFmt, int iChannel)
- 参数
handle | SDK句柄 |
---|---|
stream | 码流类型 0:视频码流 1:音频码流 |
data | 指向存放媒体数据帧结构 IVYIO_FRAME 指针的指针 |
iOutLen | 获取到数据大小,这个大小包括帧头 |
iSpeed | 媒体流速度 |
iDecodeFmt | 媒体数据解码类型 IVYIO_DECODE_FMT ,如果获取的是音频,忽略此参数 |
iChannel | 通道0-31,一次只能获取一个通道 |
- 返回值
操作结果
- 备注
获取到的媒体数据所需的内存是在SDK内部维护,不需要调用者申请。但是如果调用了关闭视频,媒体数据的内存会被释放,所以如果调用关闭视频,一定要保证此 IVYIO_FRAME 指针不再使用,否则会引起崩溃。(对于调用者来说,最常见的情况就是调用关闭视频之前保证播放媒体数据的线程退出)
iChannel:OpenVideo的iChannel第几位置成1,就填几,比如:OpenVideo的iChannel为2,表示第1个Bit置为1,那么该函数的iChannel就应该填1。
- 引用
typedef struct _IVYIO_MEDIA_DATA_
{
unsigned int channel;
unsigned int index;
unsigned int iKey;
unsigned int iFrameTag;
unsigned long long pts;
IVYIO_STREAM_TYPE type;
IVYIO_STREAM_FMT fmt;
union
{
IVYIO_VIDEO_INFO video;
IVYIO_AUDIO_INFO audio;
} media;
unsigned int len;
unsigned char data[0];
}ATTRIBUTE_PACKED IVYIO_FRAME, *PIVYIO_FRAME;
typedef enum
{
IVYIO_DEC_TYPE_VIDEORAW,
IVYIO_DEC_TYPE_ARGB32, //packed ARGB 8:8:8:8, 32bpp, ARGBARGB...
IVYIO_DEC_TYPE_RGBA32, //packed RGBA 8:8:8:8, 32bpp, RGBARGBA...
IVYIO_DEC_TYPE_ABGR32, //packed ABGR 8:8:8:8, 32bpp, ABGRABGR...
IVYIO_DEC_TYPE_BGRA32, //packed BGRA 8:8:8:8, 32bpp, BGRABGRA...
IVYIO_DEC_TYPE_RGB24, //packed RGB 8:8:8, 24bpp, RGBRGB...
IVYIO_DEC_TYPE_BGR24, //packed RGB 8:8:8, 24bpp, BGRBGR...
IVYIO_DEC_TYPE_RGB565BE, //packed RGB 5:6:5, 16bpp, (msb) 5R 6G 5B(lsb), big-endian
IVYIO_DEC_TYPE_RGB565LE, //packed RGB 5:6:5, 16bpp, (msb) 5R 6G 5B(lsb), little-endian
IVYIO_DEC_TYPE_BGR565BE, //packed BGR 5:6:5, 16bpp, (msb) 5B 6G 5R(lsb), big-endian
IVYIO_DEC_TYPE_BGR565LE, //packed BGR 5:6:5, 16bpp, (msb) 5B 6G 5R(lsb), little-endian
IVYIO_DEC_TYPE_YUV420,
IVYIO_DEC_TYPE_YUYV422,
IVYIO_DEC_TYPE_UYVY422,
IVYIO_DEC_TYPE_H264,
IVYIO_DEC_TYPE_MJPEG,
IVYIO_DEC_TYPE_MJPEG_BASE64,
IVYIO_DEC_TYPE_H264_BASE64,
IVYIO_DEC_TYPE_AUDIORAW,
IVYIO_DEC_TYPE_G726,
IVYIO_DEC_TYPE_G711U,
IVYIO_DEC_TYPE_PCM,
IVYIO_DEC_TYPE_ADPCM,
IVYIO_DEC_TYPE_G711A,
IVYIO_DEC_TYPE_AAC,
IVYIO_DEC_TYPE_HEVC
}IVYIO_DECODE_FMT;
- 调用示例
if (IVYIO_DEV_FOS_IPC == devType || IVYIO_DEV_IPC == devType || IVYIO_DEV_FOS_DOORBELL == devType)
{
// Get video in a thread
while (bGetVideoRunning)
{
IVYIO_FRAME *frame = NULL;
int outLen = 0;
int speed = 0;
IVYIO_RESULT rst = IVYIO_GetStreamData(handle, IVYIO_STREAM_VIDEO, (unsigned char **)&frame, &outLen, &speed, IVYIO_DEC_TYPE_YUV420, 0);
if (IVYIO_RESULT_OK == rst && frame->len > 0)
{
// Display frame->data
}
else
{
sleep(10); // Sleep 10ms
}
}
......
// Get audio in another thread
while (bGetAudioRunning)
{
IVYIO_FRAME *frame = NULL;
int outLen = 0;
int speed = 0;
IVYIO_RESULT rst = IVYIO_GetStreamData(handle, IVYIO_STREAM_AUDIO, (unsigned char **)&frame, &outLen, &speed, IVYIO_DEC_TYPE_PCM, 0);
if (IVYIO_RESULT_OK == rst && frame->len > 0)
{
// Display frame->data
}
else
{
sleep(10); // Sleep 10ms
}
}
}
else if (IVYIO_DEV_FOS_NVR == devType || IVYIO_DEV_NVR == devType)
{
// Get channel 2 video in a thread
while (bGetVideoRunning)
{
IVYIO_FRAME *frame = NULL;
int outLen = 0;
int speed = 0;
IVYIO_RESULT rst = IVYIO_GetStreamData(handle, IVYIO_STREAM_VIDEO, (unsigned char **)&frame, &outLen, &speed, IVYIO_DEC_TYPE_YUV420, 2);
if (IVYIO_RESULT_OK == rst && frame->len > 0)
{
// Display frame->data
}
else
{
sleep(10); // Sleep 10ms
}
}
......
// Get channel 2 audio in another thread
while (bGetAudioRunning)
{
IVYIO_FRAME *frame = NULL;
int outLen = 0;
int speed = 0;
IVYIO_RESULT rst = IVYIO_GetStreamData(handle, IVYIO_STREAM_AUDIO, (unsigned char **)&frame, &outLen, &speed, IVYIO_DEC_TYPE_PCM, 2);
if (IVYIO_RESULT_OK == rst && frame->len > 0)
{
// Display frame->data
}
else
{
sleep(10); // Sleep 10ms
}
}
}
8.2 获取直播原始音视频数据
- 描述
获取直播中原始音视频数据
IVYIO_RESULT IVYIO_API IVYIO_GetRawStreamData(IVYIO_HANDLE handle,IVYIO_STREAM_TYPE stream,unsigned char **data,int *iOutLen,int *iSpeed,int iChannel)
- 参数
handle | SDK句柄 |
---|---|
stream | 码流类型 0:视频码流 1:音频码流 |
data | 指向存放媒体数据帧结构 IVYIO_FRAME 指针的指针 |
iOutLen | 获取到数据大小,这个大小包括帧头 |
iSpeed | 媒体流速度 |
iChannel | 通道0-31,一次只能获取一个通道 |
- 返回值
操作结果
- 备注
此接口获取到的数据是没有经过解码的,是原始的H264数据或者H265数据;音频数据都是PCM,如果只是获取音频此接口和 IVYIO_GetStreamData 一样。数据使用的注意事项和 IVYIO_GetStreamData 一样
- 调用示例
if (IVYIO_DEV_FOS_IPC == devType || IVYIO_DEV_IPC == devType || IVYIO_DEV_FOS_DOORBELL == devType)
{
// Get video in a thread
while (bGetVideoRunning)
{
IVYIO_FRAME *frame = NULL;
int outLen = 0;
int speed = 0;
IVYIO_RESULT rst = IVYIO_GetRawStreamData(handle, IVYIO_STREAM_VIDEO, (unsigned char **)&frame, &outLen, &speed, 0);
if (IVYIO_RESULT_OK == rst && frame->len > 0)
{
// Decode and display frame->data
}
else
{
sleep(10); // Sleep 10ms
}
}
......
// Get audio in another thread
while (bGetAudioRunning)
{
IVYIO_FRAME *frame = NULL;
int outLen = 0;
int speed = 0;
IVYIO_RESULT rst = IVYIO_GetRawStreamData(handle, IVYIO_STREAM_AUDIO, (unsigned char **)&frame, &outLen, &speed, 0);
if (IVYIO_RESULT_OK == rst && frame->len > 0)
{
// Decode and display frame->data
}
else
{
sleep(10); // Sleep 10ms
}
}
}
else if (IVYIO_DEV_FOS_NVR == devType || IVYIO_DEV_NVR == devType)
{
// Get channel 2 video in a thread
while (bGetVideoRunning)
{
IVYIO_FRAME *frame = NULL;
int outLen = 0;
int speed = 0;
IVYIO_RESULT rst = IVYIO_GetRawStreamData(handle, IVYIO_STREAM_VIDEO, (unsigned char **)&frame, &outLen, &speed, 2);
if (IVYIO_RESULT_OK == rst && frame->len > 0)
{
// Decode and display frame->data
}
else
{
sleep(10); // Sleep 10ms
}
}
......
// Get channel 2 audio in another thread
while (bGetAudioRunning)
{
IVYIO_FRAME *frame = NULL;
int outLen = 0;
int speed = 0;
IVYIO_RESULT rst = IVYIO_GetRawStreamData(handle, IVYIO_STREAM_AUDIO, (unsigned char **)&frame, &outLen, &speed, 2);
if (IVYIO_RESULT_OK == rst && frame->len > 0)
{
// Decode and display frame->data
}
else
{
sleep(10); // Sleep 10ms
}
}
}
8.3 获取回放已解码音视频数据
- 描述
获取回放媒体数据
IVYIO_RESULT IVYIO_API IVYIO_GetPlaybackStreamData(IVYIO_HANDLE handle, IVYIO_STREAM_TYPE stream, unsigned char **data, int *iOutLen, int *iSpeed, int iDecodeFmt, int iChannel)
- 参数
handle | SDK句柄 |
---|---|
stream | 码流类型 0:视频码流 1:音频码流 |
data | 指向存放媒体数据帧结构 IVYIO_FRAME 指针的指针 |
iOutLen | 获取到数据大小,这个大小包括帧头 |
iSpeed | 媒体流速度 |
iDecodeFmt | 媒体数据解码类型 IVYIO_DECODE_FMT ,如果获取的是音频,忽略此参数 |
iChannel | 通道0-31,一次只能获取一个通道 |
- 返回值
操作结果
- 备注
注意事项同 IVYIO_GetStreamData。如果当前设备是NVR,回放的时候你可能需要知道帧的更详细信息,你可以从IVYIO_FRAME中的iFrameTag获取。FRAME_TAG_PLAYBACK_E_FRAME可以帮助你知道是否当前录像已经播完,如果发现一帧的iFrameTag为此类型,表示为当前录像最后一帧,数据可以忽略。
- 引用
// 普通直播视频或者音频帧
#define FRAME_TAG_LIVE_FRAME 0x4556494c
// 普通回放视频或者音频帧
#define FRAME_TAG_PLAYBACK_FRAME 0x4b424c50
// 一段录像的最后一帧
#define FRAME_TAG_PLAYBACK_E_FRAME 0x46454250
- 调用示例
if (IVYIO_DEV_FOS_IPC == devType || IVYIO_DEV_IPC == devType || IVYIO_DEV_FOS_DOORBELL == devType)
{
// Get video in a thread
while (bGetVideoRunning)
{
IVYIO_FRAME *frame = NULL;
int outLen = 0;
int speed = 0;
IVYIO_RESULT rst = IVYIO_GetPlaybackStreamData(handle, IVYIO_STREAM_VIDEO, (unsigned char **)&frame, &outLen, &speed, IVYIO_DEC_TYPE_YUV420, 0);
if (IVYIO_RESULT_OK == rst && frame->len > 0)
{
// Display frame->data
}
else
{
sleep(10); // Sleep 10ms
}
}
......
// Get audio in another thread
while (bGetAudioRunning)
{
IVYIO_FRAME *frame = NULL;
int outLen = 0;
int speed = 0;
IVYIO_RESULT rst = IVYIO_GetPlaybackStreamData(handle, IVYIO_STREAM_AUDIO, (unsigned char **)&frame, &outLen, &speed, IVYIO_DEC_TYPE_PCM, 0);
if (IVYIO_RESULT_OK == rst && frame->len > 0)
{
// Display frame->data
}
else
{
sleep(10); // Sleep 10ms
}
}
}
else if (IVYIO_DEV_FOS_NVR == devType || IVYIO_DEV_NVR == devType)
{
// Get channel 2 video in a thread
while (bGetVideoRunning)
{
IVYIO_FRAME *frame = NULL;
int outLen = 0;
int speed = 0;
IVYIO_RESULT rst = IVYIO_GetPlaybackStreamData(handle, IVYIO_STREAM_VIDEO, (unsigned char **)&frame, &outLen, &speed, IVYIO_DEC_TYPE_YUV420, 2);
if (IVYIO_RESULT_OK == rst && frame->len > 0)
{
// Display frame->data
}
else
{
sleep(10); // Sleep 10ms
}
}
......
// Get channel 2 audio in another thread
while (bGetAudioRunning)
{
IVYIO_FRAME *frame = NULL;
int outLen = 0;
int speed = 0;
IVYIO_RESULT rst = IVYIO_GetPlaybackStreamData(handle, IVYIO_STREAM_AUDIO, (unsigned char **)&frame, &outLen, &speed, IVYIO_DEC_TYPE_PCM, 2);
if (IVYIO_RESULT_OK == rst && frame->len > 0)
{
// Display frame->data
}
else
{
sleep(10); // Sleep 10ms
}
}
}
8.4 获取回放原始音视频数据
- 描述
获取回放原始媒体数据
IVYIO_RESULT IVYIO_API IVYIO_GetPlaybackRawStreamData(IVYIO_HANDLE handle,IVYIO_STREAM_TYPE stream,unsigned char **data,int *iOutLen,int *iSpeed, int iChannel)
- 参数
handle | SDK句柄 |
---|---|
stream | 码流类型 0:视频码流 1:音频码流 |
data | 指向存放媒体数据帧结构 IVYIO_FRAME 指针的指针 |
iOutLen | 获取到数据大小,这个大小包括帧头 |
iSpeed | 媒体流速度 |
iChannel | 通道0-31,一次只能获取一个通道 |
- 返回值
操作结果
- 备注
注意事项同 IVYIO_GetRawStreamData。IVYIO_FRAME中的iFrameTag作用以及定义可以参考 IVYIO_GetPlaybackStreamData
- 调用示例
if (IVYIO_DEV_FOS_IPC == devType || IVYIO_DEV_IPC == devType || IVYIO_DEV_FOS_DOORBELL == devType)
{
// Get video in a thread
while (bGetVideoRunning)
{
IVYIO_FRAME *frame = NULL;
int outLen = 0;
int speed = 0;
IVYIO_RESULT rst = IVYIO_GetPlaybackRawStreamData(handle, IVYIO_STREAM_VIDEO, (unsigned char **)&frame, &outLen, &speed, 0);
if (IVYIO_RESULT_OK == rst && frame->len > 0)
{
// Decode and display frame->data
}
else
{
sleep(10); // Sleep 10ms
}
}
......
// Get audio in another thread
while (bGetAudioRunning)
{
IVYIO_FRAME *frame = NULL;
int outLen = 0;
int speed = 0;
IVYIO_RESULT rst = IVYIO_GetPlaybackRawStreamData(handle, IVYIO_STREAM_AUDIO, (unsigned char **)&frame, &outLen, &speed, 0);
if (IVYIO_RESULT_OK == rst && frame->len > 0)
{
// Decode and display frame->data
}
else
{
sleep(10); // Sleep 10ms
}
}
}
else if (IVYIO_DEV_FOS_NVR == devType || IVYIO_DEV_NVR == devType)
{
// Get channel 2 video in a thread
while (bGetVideoRunning)
{
IVYIO_FRAME *frame = NULL;
int outLen = 0;
int speed = 0;
IVYIO_RESULT rst = IVYIO_GetPlaybackRawStreamData(handle, IVYIO_STREAM_VIDEO, (unsigned char **)&frame, &outLen, &speed, 2);
if (IVYIO_RESULT_OK == rst && frame->len > 0)
{
// Decode and display frame->data
}
else
{
sleep(10); // Sleep 10ms
}
}
......
// Get channel 2 audio in another thread
while (bGetAudioRunning)
{
IVYIO_FRAME *frame = NULL;
int outLen = 0;
int speed = 0;
IVYIO_RESULT rst = IVYIO_GetPlaybackRawStreamData(handle, IVYIO_STREAM_AUDIO, (unsigned char **)&frame, &outLen, &speed, 2);
if (IVYIO_RESULT_OK == rst && frame->len > 0)
{
// Decode and display frame->data
}
else
{
sleep(10); // Sleep 10ms
}
}
}
8.5 解码回放视频数据
- 描述
解码回放视频数据
IVYIO_RESULT IVYIO_API IVYIO_DecodePlaybackVideo(IVYIO_HANDLE handle, unsigned char *srcFrame, unsigned char **dstFrame, int *dstFrameSize, int dstDecodeFmt, int channel)
- 参数
handle | SDK句柄 |
---|---|
srcFrame | 回放数据 IVYIO_FRAME 结构指针 |
dstFrame | 指向存放解码后数据帧结构 IVYIO_FRAME 指针的指针 |
dstFrameSize | 解码后数据的大小,包含 IVYIO_FRAME 头大小 |
dstDecodeFmt | 解码格式 |
channel | 通道0-31 |
- 返回值
操作结果
- 备注
注释使用之前必须调用 IVYIO_OpenPlayback,因为此接口内部还是和回放相关,不是一个独立的接口。
不支持Foscam设备
- 调用示例
if (IVYIO_DEV_IPC == devType || IVYIO_DEV_NVR == devType)
{
// Get channel 2 video in a thread
while (bGetVideoRunning)
{
IVY_FRAME *srcFrame = NULL;
// from api 'IVYIO_GetPlaybackRawStreamData'
......
IVYIO_FRAME *dstFrame = NULL;
int outLen = 0;
IVYIO_RESULT rst = IVYIO_DecodePlaybackVideo(handle, (unsigned char *)srcFrame, (unsigned char **)&dstFrame, &outLen, IVYIO_DECODE_YUV420, 2);
if (IVYIO_RESULT_OK == rst && dstFrame->len > 0)
{
// Decode and display dstFrame->data
}
else
{
sleep(5); // Sleep 10ms
}
}
......
}
9. 发送命令
9.1 发送命令(推荐使用)
- 描述
发送命令,可以对设备进行设置或者获取设备各种信息或者状态
IVYIO_RESULT IVYIO_API IVYIO_SendCommand(IVYIO_HANDLE handle, unsigned int cmd, unsigned char *cmdData, int iSizeOfCmdData, unsigned char *response, int *iSizeOfResponse, int iTimeout)
- 参数
handle | SDK句柄 |
---|---|
cmd | 命令ID |
cmdData | 命令数据buffer |
iSizeOfCmdData | 命令数据buffer大小 |
response | 响应数据buffer |
iSizeOfResponse | 返回的响应数据实际大小 |
iTimeout | 超时,单位ms |
- 返回值
操作结果
- 备注
cmd参数的范围应为 22019-42018,这个范围内的ID命令用途由开发者确定,SDK只是负责传输数据,具体命令的解析由上层应用和下层嵌入式决定;因此,cmdData和response的格式应由开发者定义。
如果应用不是Android需要注意iSizeOfResponse的值,因为数据传输已经加密,如果返回都是Json字符串,不要使用iSizeOfResponse,要自己strlen(response),这样可以获取到真正的字符串长度,iSizeOfResponse后边会包含若干个’\0’,Android应用没有此问题。如果返回是二进制数据,直接使用iSizeOfResponse就可以。
- 调用示例
// Get device information
memset(szResponse, 0, sizeof(szResponse));
lenOfResponse = sizeof(szResponse);
IVYIO_RESULT rst = IVYIO_SendCommand(handle, 22025, "", (unsigned char *)szResponse, &lenOfResponse, 1000 * 5);
if (IVYIO_RESULT_OK == rst)
{
// The 'ret' field in 'szResponse' is 0,mean success
// Your wil get response text like this:
//{
// "devName" : "RG9vckJlbGw=",
// "devType" : 1000,
// "firmwareVersion" : "2.134.2.19",
// "hardwareVersion" : "1.17.2.5",
// "language" : 2,
// "mac" : "A0E9DA067AEA",
// "model" : 10001,
// "oemCode" : 3000,
// "platType" : 4,
// "productName" : "MBS4010",
// "ret" : 0,
// "sensorType" : 28,
// "serialNo" : "0000000000000001",
// "uid" : "GKBGTPY7BX98TH5BZZZZ7Y8M",
// "wifiType" : 9
//}
}
else
{
// failed!
}
9.2 发送CGI
- 描述
向FoscamIPC发送CGI命令并且获取到结果, 其他设备不支持
IVYIO_RESULT IVYIO_API IVYIO_DoCGI(IVYIO_HANDLE handle, const char *szCGI, char *szXmlResp, int *iSizeOfResp, int iTimeout)
- 参数
handle | SDK句柄 |
---|---|
szCGI | CGI命令 |
szXmlResp | CGI结果,XML结构 |
iSizeOfResp | 作为输入是szXmlResp的大小,作为输出是实际返回的响应结果长度 |
iTimeout | 超时时间 |
- 返回值
操作结果
- 备注
此接口只支持FoscamIPC,其他设备均不支持。
- 调用示例
char szCGI[512] = "cmd=getDevInfo";
char szXML[1024] = {0};
int lenOfXML = sizeof(szXML);
IVYIO_RESULT rst = IVYIO_DoCGI(handle, szCGI, szXML, &lenOfXML, 1000 * 5);
// The szXML data like this:
// <CGI_Result>
// <result>0</result>
// <productName>MBS4010</productName>
// <serialNo>0000000000000001</serialNo>
// <devName>DoorBell</devName>
// <mac>A0E9DA067AEA</mac>
// <year>2021</year>
// <mon>4</mon>
// <day>28</day>
// <hour>13</hour>
// <min>13</min>
// <sec>33</sec>
// <timeZone>0</timeZone>
// <firmwareVer>2.134.2.19</firmwareVer>
// <hardwareVer>1.17.2.5</hardwareVer>
// <pkgTime>2021-04-09_16%3A40%3A00</pkgTime>
// </CGI_Result>
10. 辅助接口
10.1 获取事件
- 描述
获取事件,当设备状态发生改变,设备或者SDK会发送一个事件通知应用,应用应该根据事件做响应的处理
IVYIO_RESULT IVYIO_API IVYIO_GetEvent(IVYIO_HANDLE handle, IVYIO_EVENT *event)
- 参数
handle | SDK句柄 |
---|---|
event | 指向事件结构体 IVYIO_EVENT 的指针 |
- 返回值
操作结果
- 备注
通常情况下,事件ID的范围是 42019-65535,这个范围内的事件由开发者定义,和发送命令IVYIO_SendCommand类似,对于事件SDK也只是负责数据传输,不解析任何数据,命令ID用途和结构都有上层应用和下层嵌入式决定。注意,有一些事件是由SDK内部发出的,不属于 42019-65535 这个范围内
此接口只能处理事件数据大小小于4K的事件。
- 调用示例
// Get event in a thread
while (bRunning)
{
IVYIO_EVENT event;
memset(&event, 0, sizeof(event));
if (IVYIO_GetEvent(handle, &event) == IVYIO_RESULT_OK)
{
switch (event.id)
{
case IVY_CTRL_MSG_DAY_NIGHT_MODE_CHG:
// Parse event.data
break;
case IVY_CTRL_MSG_PRESET_CHG:
// Parse event.data
break;
......
default:
break;
}
}
}
10.1.1 获取事件2
- 描述
获取事件,当设备状态发生改变,设备或者SDK会发送一个事件通知应用,应用应该根据事件做响应的处理。此接口可以处理任意大小的事件,只要调用者给出足够的空间。
IVYIO_RESULT IVYIO_API IVYIO_GetEvent2(IVYIO_HANDLE handle, IVYIO_EVENT2 *event)
- 参数
handle | SDK句柄 |
---|---|
event | 指向事件结构体 IVYIO_EVENT2 的指针 |
- 返回值
操作结果
- 备注
通常情况下,事件ID的范围是 42019-65535,这个范围内的事件由开发者定义,和发送命令IVYIO_SendCommand类似,对于事件SDK也只是负责数据传输,不解析任何数据,命令ID用途和结构都有上层应用和下层嵌入式决定。注意,有一些事件是由SDK内部发出的,不属于 42019-65535 这个范围内
event->iLenOfData 作为输入表示 event->data 大小,如果实际的事件数据大于输入buffer大小,接口返回 IVYIO_RESULT_ARGS_ERR错误,否则 event->iLenOfData 被修改为实际数据大小。
- 调用示例
// Get event in a thread
const int bufSize = 16 * 1024;
char *eventBuff = new char[bufSize];
memset(eventBuff, 0, bufSize);
IVYIO_EVENT2 event;
memset(&event, 0, sizeof(event));
event->data = eventBuff;
while (bRunning)
{
memset(eventBuff, 0, bufSize);
event->iLenOfData = bufSize;
if (IVYIO_GetEvent2(handle, &event) == IVYIO_RESULT_OK)
{
switch (event.id)
{
case IVY_CTRL_MSG_DAY_NIGHT_MODE_CHG:
// Parse event.data
break;
case IVY_CTRL_MSG_PRESET_CHG:
// Parse event.data
break;
......
default:
break;
}
}
}
delete[] eventBuff;
eventBuff = NULL;
10.2 将关键帧转成一张图片
- 描述
将一个关键帧转换成一张图片
IVYIO_RESULT IVYIO_API IVYIO_KeyFrame2Picture(IVYIO_HANDLE handle, char *inData, int iLenOfInData, char *outData, int *iLenOfOutData, int channel);
- 参数
handle | SDK句柄 |
---|---|
inData | 指向输入数据buffer的指针 |
iLenOfInData | 输入数据buffer大小 |
outData | 指向输出数据buffer的大小 |
iLenOfOutData | 指向输出buffer大小的指针 |
channel | 通道号 |
- 返回值
操作结果
- 备注
iLenOfOutData既是输入参数也是输出参数,作为输入参数表示outData buffer大小,作为输出表示实际输出buffer的大小;如果作为输入参数大小小于实际需要的buffer大小,函数会返回错误,但是作为输出iLenOfOutData会告知实际需要的buffer大小。
- 调用示例
IVYIO_FRAME *frame = NULL;
// Get a video frame,
......
if (frame->iKey)
{
char *picture = new char[1024 * 1024 * 10];
int pictureLen = 1024 * 1024 * 10;
if (IVYIO_DEV_FOS_IPC == devType || IVYIO_DEV_IPC == devType || IVYIO_DEV_FOS_DOORBELL == devType)
{
IVYIO_RESULT rst = IVYIO_KeyFrame2Picture(handle, frame->data, frame->len, picture, &pictureLen, 0);
}
else if (IVYIO_DEV_FOS_NVR == devType || IVYIO_DEV_NVR == devType)
{
// Key frame on channel 5 to picture
IVYIO_RESULT rst = IVYIO_KeyFrame2Picture(handle, frame->data, frame->len, picture, &pictureLen, 5);
}
// You can save it to local as a picture.
......
delete[] picture;
picture = NULL;
}
10.3 查询SDK接口调用状态
- 描述
查询接口调用状态,是否超过一定时间没有调用接口,此接口只有在IVYIO_Create_1的最后一个参数为1的情况下才生效。
IVYIO_RESULT IVYIO_API IVYIO_ApiCallTimeIsUp(IVYIO_HANDLE handle, int *state);
- 参数
handle | SDK句柄 |
---|---|
state | 状态 1:已经超过一定时间没有调用SDK接口 0:接口调用正常 |
- 返回值
操作结果
- 备注
此接口只有在IVYIO_Create_1的最后一个参数为1的情况下才生效
- 调用示例
while (1)
{
int state = -1;
if (IVYIO_RESULT_OK == IVYIO_ApiCallTimeIsUp(handle, &state))
{
if (1 == state)
{
// do someting
}
}
}
11. 门铃接听接口
接口适用范围
此章节接口适用于门铃接听场景。
门铃接听场景:当门铃被按下,应用接到门铃被按下的消息,在界面上显示以便用户选择是否接听,如果选择接听,应用显示视频和音频,并且可以发送对讲和进行录像。
11.1 创建门铃设备句柄并登录
- 描述
创建SDK实例句柄,虽然此接口适用于门铃,但也同样适用于其他设备(如果不是门铃我们推荐适用其他接口创建句柄)。如果当前设备类型为门铃,此接口会自动去登录设备,但是不会返回是否登录成功。
IVYIO_HANDLE IVYIO_API IVYIO_CreateEx_2(IVYIO_URL *url, char *szUid, char *szMac, char *szUser, char *szPassword, IVYIO_P2P_MODE mode, IVYIO_P2P_MODE doorbellMode, int devType, int streamType)
- 参数
url | 结构体,存放目标设备的连接地址和端口;地址可以是DDNS或者IP |
---|---|
szUid | 目标设备的UID,可以为空 |
szUser | 目标设备的用户名,不能为空 |
szPassword | 目标设备的密码,不能为空 |
mode | P2P连接模式 0:UDP方式 1:TCP方式 2:自动 |
doorbellMode | 门铃P2P连接模式 3:音频TCP视频UDP 4:音频视频都是TCP |
devType | 设备类型 |
streamType | IPC码流类型,如果是门铃设备可以忽略 |
相同的参数可以参照 IVYIO_CreateEx_1 / IVYIO_CreateEx 的描述。
- 返回值
SDK句柄,返回句柄时递增的,释放过后在创建也会递增
- 备注
mode只能使用值FOS_P2P_MODE_UDP/FOS_P2P_MODE_TCP/FOS_P2P_MODE_AUTO
doorbell只能使用 IVYIO_P2P_MODE_A_TCP_V_UDP / IVYIO_P2P_MODE_A_V_TCP
如果devType是门铃设备,门铃部分创建的时候就会去连接设备,IPC部分用法还和之前一致。
- 引用
typedef struct _IVYIO_URL_
{
char szUrl[256]; // ip or ddns
unsigned short usPort; // port
}ATTRIBUTE_PACKED IVYIO_URL, *PIVYIO_URL;
typedef enum
{
IVYIO_P2P_MODE_UDP = 0,
IVYIO_P2P_MODE_TCP = 1,
IVYIO_P2P_MODE_AUTO = 2,
IVYIO_P2P_MODE_A_TCP_V_UDP = 3,
IVYIO_P2P_MODE_A_V_TCP = 4
}IVYIO_P2P_MODE;
- 调用示例
// Create doorbell
IVYIO_URL url;
memset(&url, 0, sizeof(url));
strcpy(url.szUrl, "192.168.1.1");
url.usPort = 88;
IVYIO_HANDLE doorBellHandle = IVYIO_CreateEx_2(&url, "ABCDABCDABCDABCDABCD2222", "", "admin", "", IVYIO_P2P_MODE_UDP, IVYIO_P2P_MODE_A_TCP_V_UDP, IVYIO_DEV_FOS_DOORBELL, IVYIO_MAIN_VIDEO_STREAM);
11.2 打开门铃视频
- 描述
打开门铃视频
IVYIO_RESULT IVYIO_API IVYIO_DoorBell_OpenVideo(IVYIO_HANDLE handle, int iTimeout)
- 参数
handle | SDK句柄 |
---|---|
timeout | 超时时间 |
- 返回值
操作结果
- 备注
如果要使用门铃接口,需要使用IVYIO_CreateEx_2创建句柄,并且设备类型为
IVYIO_DEV_FOS_DOORBELL,创建函数会立即创建2个P2P去连接设备,一个P2P用于音频,一个P2P用于视频。无需调用登陆接口,直接可以打开视频,如果需要调用门铃以外的其他接口,这个句柄是有效的,无需重新创建句柄。如果创建句柄接口设备类型不是门铃,门铃接口函数无法使用。
- 调用示例
// Create doorbell
IVYIO_URL url;
memset(&url, 0, sizeof(url));
strcpy(url.szUrl, "192.168.1.1");
url.usPort = 88;
IVYIO_HANDLE doorBellHandle = IVYIO_CreateEx_2(&url, "ABCDABCDABCDABCDABCDZZZZ", "", "admin", "", IVYIO_P2P_MODE_UDP, IVYIO_P2P_MODE_A_TCP_V_UDP, IVYIO_DEV_FOS_DOORBELL, IVYIO_MAIN_VIDEO_STREAM);
// You can open video after create handle
IVYIO_RESULT rst = IVYIO_DoorBell_OpenVideo(doorBellHandle, 1000 * 5);
11.3 关闭门铃视频
- 描述
关闭门铃视频
IVYIO_RESULT IVYIO_API IVYIO_DoorBell_CloseVideo(IVYIO_HANDLE handle, int iTimeout)
- 参数
handle | SDK句柄 |
---|---|
timeout | 超时时间 |
- 返回值
操作结果
- 调用示例
IVYIO_RESULT rst = IVYIO_DoorBell_CloseVideo(doorBellHandle, 1000 * 5);
11.4 打开门铃音频
- 描述
打开门铃音频
IVYIO_RESULT IVYIO_API IVYIO_DoorBell_OpenAudio(IVYIO_HANDLE handle, int iTimeout)
- 参数
handle | SDK句柄 |
---|---|
timeout | 超时时间 |
- 返回值
操作结果
- 调用示例
IVYIO_RESULT rst = IVYIO_DoorBell_OpenVideo(doorBellHandle, 1000 * 5);
if (IVYIO_RESULT_OK == rst)
rst = IVYIO_DoorBell_OpenAudio(doorBellHandle, 1000 * 5); // Or open audio in another thread
11.5 关闭门铃音频
- 描述
关闭门铃音频
IVYIO_RESULT IVYIO_API IVYIO_DoorBell_CloseAudio(IVYIO_HANDLE handle, int iTimeout)
- 参数
handle | SDK句柄 |
---|---|
timeout | 超时时间 |
- 返回值
操作结果
- 调用示例
IVYIO_DoorBell_CloseAudio(doorBellHandle, 1000 * 5);
11.6 打开门铃对讲
- 描述
打开门铃对讲
IVYIO_RESULT IVYIO_API IVYIO_DoorBell_OpenTalk(IVYIO_HANDLE handle, int iTimeout)
- 参数
handle | SDK句柄 |
---|---|
timeout | 超时时间 |
- 返回值
操作结果
- 备注
需要先调用打开音频接口
- 调用示例
IVYIO_RESULT rst = IVYIO_DoorBell_OpenTalk(doorBellHandle, 1000 * 5);
11.7 关闭门铃对讲
- 描述
关闭门铃对讲
IVYIO_RESULT IVYIO_API IVYIO_DoorBell_CloseTalk(IVYIO_HANDLE handle, int iTimeout)
- 参数
handle | SDK句柄 |
---|---|
timeout | 超时时间 |
- 返回值
操作结果
- 调用示例
IVYIO_RESULT rst = IVYIO_DoorBell_CloseTalk(doorBellHandle, 1000 * 5);
11.8 发送对讲数据给门铃
- 描述
发送门铃对讲数据
IVYIO_RESULT IVYIO_API IVYIO_DoorBell_SendTalkData(IVYIO_HANDLE handle, char *data, int dataLen)
- 参数
handle | SDK句柄 |
---|---|
data | 对讲数据 |
dataLen | 对讲数据长度 |
- 返回值
操作结果
- 备注
数据采样率为8000,一般是960个字节大小.
- 调用示例
while (bGetData)
{
// Get talk data into talkData buffer.
IVYIO_DoorBell_SendTalkData(doorBellHandle, talkData, 960);
}
11.9 获取门铃数据(已解码)
- 描述
获取门铃解码的音视频数据
IVYIO_RESULT IVYIO_API IVYIO_DoorBell_GetStreamData(IVYIO_HANDLE handle,
IVYIO_STREAM_TYPE stream,
unsigned char **data,
int *iOutLen,
int *iSpeed,
int iDecodeFmt)
- 参数
handle | SDK句柄 |
---|---|
stream | 码流类型 0:视频码流 1:音频码流 |
data | 指向存放媒体数据帧结构 IVYIO_FRAME 指针的指针 |
iOutLen | 返回数据的长度 |
iSpeed | 数据流量 |
iDecodeFmt | 媒体数据解码类型 IVYIO_DECODE_FMT ,如果获取的是音频,忽略此参数 |
- 返回值
操作结果
- 备注
注意事项和IVYIO_GetStreamData一样,可以参考其API说明
- 调用示例
if (IVYIO_DEV_FOS_DOORBELL == devType)
{
// Get video in a thread
while (bGetVideoRunning)
{
IVYIO_FRAME *frame = NULL;
int outLen = 0;
int speed = 0;
IVYIO_RESULT rst = IVYIO_DoorBell_GetStreamData(handle, IVYIO_STREAM_VIDEO, (unsigned char **)&frame, &outLen, &speed, IVYIO_DEC_TYPE_YUV420);
if (IVYIO_RESULT_OK == rst && frame->len > 0)
{
// Display frame->data
}
else
{
sleep(10); // Sleep 10ms
}
}
// Get audio in another thread
while (bGetAudioRunning)
{
IVYIO_FRAME *frame = NULL;
int outLen = 0;
int speed = 0;
IVYIO_RESULT rst = IVYIO_DoorBell_GetStreamData(handle, IVYIO_STREAM_AUDIO, (unsigned char **)&frame, &outLen, &speed, IVYIO_DEC_TYPE_PCM);
if (IVYIO_RESULT_OK == rst && frame->len > 0)
{
// Display frame->data
}
else
{
sleep(10); // Sleep 10ms
}
}
}
11.10 获取门铃数据(未解码)
- 描述
获取门铃原始的音视频数据
IVYIO_RESULT IVYIO_API IVYIO_DoorBell_GetRawStreamData(IVYIO_HANDLE handle,
IVYIO_STREAM_TYPE stream,
unsigned char **data,
int *iOutLen,
int *iSpeed)
- 参数
handle | SDK句柄 |
---|---|
stream | 码流类型 0:视频码流 1:音频码流 |
data | 指向存放媒体数据帧结构 IVYIO_FRAME 指针的指针 |
iOutLen | 返回数据的长度 |
iSpeed | 数据流量 |
- 返回值
操作结果
- 备注
注意事项和IVYIO_GetRawStreamData一样
- 调用示例
if (IVYIO_DEV_FOS_DOORBELL == devType)
{
// Get video in a thread
while (bGetVideoRunning)
{
IVYIO_FRAME *frame = NULL;
int outLen = 0;
int speed = 0;
IVYIO_RESULT rst = IVYIO_DoorBell_GetRawStreamData(handle, IVYIO_STREAM_VIDEO, (unsigned char **)&frame, &outLen, &speed);
if (IVYIO_RESULT_OK == rst && frame->len > 0)
{
// Display frame->data
}
else
{
sleep(10); // Sleep 10ms
}
}
// Get audio in another thread
while (bGetAudioRunning)
{
IVYIO_FRAME *frame = NULL;
int outLen = 0;
int speed = 0;
IVYIO_RESULT rst = IVYIO_DoorBell_GetRawStreamData(handle, IVYIO_STREAM_AUDIO, (unsigned char **)&frame, &outLen, &speed);
if (IVYIO_RESULT_OK == rst && frame->len > 0)
{
// Display frame->data
}
else
{
sleep(10); // Sleep 10ms
}
}
}
11.11 门铃本地录像开始
- 描述
门铃本地录像开始
IVYIO_RESULT IVYIO_API IVYIO_DoorBell_StartRecord(IVYIO_HANDLE handle, IVYIO_RECORD_TYPE type, const char *szFileName)
- 参数
handle | SDK句柄 |
---|---|
type | 录像类型 1:MP4 |
szFileName | 保存文件完整的路径名称 |
- 返回值
操作结果
- 调用示例
if (IVYIO_DEV_FOS_DOORBELL == devType)
{
#ifdef _WIN32
IVYIO_DoorBell_StartRecord(doorBellHandle, IVYIO_RECORD_MP4, "c:\\record.mp4");
#else
IVYIO_DoorBell_StartRecord(doorBellHandle, IVYIO_RECORD_MP4, "/mydir/ecord.mp4");
#endif
}
11.12 门铃本地录像结束
- 描述
门铃本地录像结束
IVYIO_RESULT IVYIO_API IVYIO_DoorBell_StopRecord(IVYIO_HANDLE handle)
- 参数
handle | SDK句柄 |
---|
- 返回值
操作结果
- 调用示例
if (IVYIO_DEV_FOS_DOORBELL == devType)
{
IVYIO_DoorBell_StopRecord(doorBellHandle);
}
11.13 检测门铃句柄状态
- 描述
检测门铃句柄状态,如果门铃涉及到套接字或者通道任何一个发生改变,都有会事件生成。
IVYIO_HANDLE_STATE IVYIO_API IVYIO_DoorBell_CheckHandle(IVYIO_HANDLE handle)
- 参数
handle | SDK句柄 |
---|
返回值
门铃句柄状态调用示例
if (IVYIO_DEV_FOS_DOORBELL == devType)
{
while (bChecking)
{
IVYIO_HANDLE_STATE state = IVYIO_DoorBell_CheckHandle(doorBellHandle);
// handle state
.....
}
}
11.14 获取门铃事件
- 描述
获取门铃事件
IVYIO_RESULT IVYIO_API IVYIO_DoorBell_GetEvent(IVYIO_HANDLE handle, IVYIO_EVENT *event)
- 参数
handle | SDK句柄 |
---|---|
event | 事件 |
- 返回值
操作结果
- 调用示例
if (IVYIO_DEV_FOS_DOORBELL == devType)
{
while (bChecking)
{
IVYIO_EVENT event;
memset(&event, 0, sizeof(event));
if (IVYIO_RESULT_OK == IVYIO_DoorBell_GetEvent(doorBellHandle))
{
switch (event.id)
{
case NET_STATE_DISCONNECT:
// Handle function
break;
case ......
break;
......
default:
break;
}
}
}
}
11.15 设置OpenTalk对讲标志(仅在iOS平台下适用)
- 描述
设置OpenTalk对讲标志,设置完成后设备播放声音的时候会有一些特殊处理,目前该接口只是给iOS用。
void IVYIO_API IVYIO_SetOpenTalkFlag(IVYIO_HANDLE handle, int flag)
- 参数
handle | SDK句柄 |
---|---|
flag | 0 / 1 |
- 返回值
操作结果
- 备注
iOS的回音消除问题,经过iOS消除过的声音到了IPC后会变的比较小,设置此表之后,设备会根据这个表示知道当前是iOS,会加大播放音量。此命令只对Foscam设备有效。
- 调用示例
if (IVYIO_DEV_FOS_DOORBELL == devType)
{
IVYIO_SetOpenTalkFlag(doorBellHandle, 1);
}
11.16 门铃接听状态查询
- 描述
获取门铃接听状态,是否已经别另外一个设备接听
IVYIO_RESULT IVYIO_API IVYIO_DoorBell_QueryAnswerState(IVYIO_HANDLE handle, int *state, int iTimeout)
- 参数
handle | SDK句柄 |
---|---|
state | 状态,2:没有被接听 0:已经被接听 3:当前通话被app拒接 4:ipc主动取消呼叫 5:ipc主动挂断 -1:如果当前APP已经接听了设备,设备会返回这个值 |
iTimeout | 超时时间 |
- 返回值
操作结果
- 备注
只支持门铃设备,必须要调用IVYIO_DoorBell_OpenVideo成功之后再调用此接口,否则无法正确查到状态。
因为只有当IVYIO_DoorBell_OpenVideo成功后,设备才会鉴权,才会有密码,这样SDK才能正确取到数据,后续设备可能会更新固件解决必须在IVYIO_DoorBell_OpenVideo后调用的问题。
- 调用示例
if (IVYIO_DEV_FOS_DOORBELL == devType)
{
while(bChecking)
{
int state = -1;
if (IVYIO_RESULT_OK == IVYIO_DoorBell_QueryAnswerState(doorBellHandle, &state, 1000 * 5))
{
if (0 == state)
......
else if (1 == state)
......
else
......
}
}
}
12 获取图片接口(仅支持IVY设备)
12.1 获取图片列表
- 描述
获取图片列表
图片信息支持多种数据结构,根据能力集区分,val6中的bit4,如果该位为1,表示支持 direction / weight,可以参考 ‘调用示例2’,该位为0,’参考示例1’
IVYIO_RESULT IVYIO_API IVYIO_GetPictureList(IVYIO_HANDLE handle, void *args, void *list, int iTimeout, int iChannel)
- 参数
handle | SDK句柄 |
---|---|
args | 指向 IVYIO_PICTURE_SEARCH 结构的指针 |
list | 指向 IVYIO_PICTURE_LIST 或者 IVYIO_PICTURE_LIST_EX 结构的指针 |
iTimeout | 超时时间 |
iChannel | 通道号,同打开视频 |
- 返回值
操作结果
- 引用
// Picture download
typedef struct _IVYIO_PICTURE_SEARCH_
{
int sln; // must be 0 or 1
unsigned long long sTime; // start timestamp, unit second
unsigned long long eTime; // end timestamp, unit second
int type; // type, same as "IVYIO_GetPlaybackRecordList" record type
unsigned int startNo; // Start NO
int count; // Count of search, max 20
}ATTRIBUTE_PACKED IVYIO_PICTURE_SEARCH, *PIVYIO_PICTURE_SEARCH;
typedef struct _IVYIO_PICTURE_INFO_
{
int format; // Picture format, only support JPEG,value is 200
unsigned long long time; // Timestamp
unsigned int type; // Picture type same as "IVYIO_GetPlaybackRecordList" record type
}ATTRIBUTE_PACKED IVYIO_PICTURE_INFO, *PIVYIO_PICTURE_INFO;
typedef struct _IVYIO_PICTURE_LIST_
{
int channel; // channel
unsigned int totalCount; // Total count
unsigned int curCount; // Current search count
IVYIO_PICTURE_INFO list[20];
}ATTRIBUTE_PACKED IVYIO_PICTURE_LIST, *PIVYIO_PICTURE_LIST;
typedef struct _IVYIO_PICTURE_INFO_EX_
{
int direction;
int weight;
}ATTRIBUTE_PACKED IVYIO_PICTURE_INFO_EX, *PIVYIO_PICTURE_INFO_EX;
typedef struct _IVYIO_PICTURE_LIST_EX_
{
int channel;
unsigned int totalCount;
unsigned int curCount;
IVYIO_PICTURE_INFO list[20];
IVYIO_PICTURE_INFO listEx[20];
}ATTRIBUTE_PACKED IVYIO_PICTURE_LIST_EX, *PIVYIO_PICTURE_LIST_EX;
- 备注
iChanel目前请传0或者1。
- 调用示例 1
// sln = 0
if (IVYIO_DEV_IPC == devType)
{
IVYIO_PICTURE_SEARCH ips;
memset(&ips, 0, sizeof(IVYIO_PICTURE_SEARCH));
ips.sTime = 1620316800; // 2021-05-07 00:00:00 (beijing)
ips.eTime = 1620403199; // 2021-05-07 23:59:59 (beijing)
ips.sln = 0;
ips.count = 20;
ips.startNo = startNo;
IVYIO_PICTURE_LIST ipl;
memset(&ipl, 0, sizeof(IVYIO_PICTURE_LIST));
int size = sizeof(IVYIO_PICTURE_LIST);
rst = IVYIO_GetPictureList(m_handle, (void *)&ips, (void *)&ipl, 1000 * 10, 0);
if (rst != IVYIO_RESULT_OK)
{
return;
}
}
- 调用示例 2
// sln = 1
// support direction / weight
if (IVYIO_DEV_IPC == devType)
{
IVYIO_PICTURE_SEARCH ips;
memset(&ips, 0, sizeof(IVYIO_PICTURE_SEARCH));
ips.sTime = 1620316800; // 2021-05-07 00:00:00 (beijing)
ips.eTime = 1620403199; // 2021-05-07 23:59:59 (beijing)
ips.sln = 1;
ips.count = 20;
ips.startNo = startNo;
IVYIO_PICTURE_LIST_EX ipl;
memset(&ipl, 0, sizeof(IVYIO_PICTURE_LIST_EX));
int size = sizeof(IVYIO_PICTURE_LIST_EX);
rst = IVYIO_GetPictureList(m_handle, (void *)&ips, (void *)&ipl, 1000 * 10, 0);
if (rst != IVYIO_RESULT_OK)
{
return;
}
}
12.2 获取图片数据
- 描述
获取图片数据
如果能力集中val6中的bit4,如果该位为1,需要使用IVYIO_GET_MULTI_PICTURE_EX结构去请求图片,参考 ‘调用示例1’,如果该位为0,使用IVYIO_GET_MULTI_PICTURE结构, 参考’调用示例2’
IVYIO_RESULT IVYIO_API IVYIO_GetPicture(IVYIO_HANDLE handle, void *args, void *files[20], int *fileCount, int iTimeout, int iChannel)
- 参数
handle | SDK句柄 |
---|---|
args | 指向 IVYIO_GET_MULTI_PICTURE 或者 IVYIO_GET_MULTI_PICTURE_EX 结构的指针 |
files | 指针数组,最多存放20个图片信息,指针结构为 IVYIO_PICTURE_FILE |
fileCount | 实际下载的图片数量 |
iTimeout | 超时时间 |
iChannel | 通道号,0-31,每次只能获取一个通道的图片,目前只支持0通道 |
- 返回值
操作结果
- 引用
// Picture information
typedef struct _IVYIO_GET_PICTURE_
{
int format; // picture format, value is 200, JPEG format
int type; // picture type, same as type in IVYIO_PICTURE_INFO structure
unsigned long long time; // picture timestamp.
}ATTRIBUTE_PACKED IVYIO_GET_PICTURE, *PIVYIO_GET_PICTURE;
typedef struct _IVYIO_GET_MULTI_PICTURE_EX_
{
int sln; // must be 1
int countOfUsed; // Can be used picture array count
IVYIO_PICTURE_INFO picture[20]; // max size 20
IVYIO_PICTURE_INFO_EX pictureEx[20]; // max size 20
}ATTRIBUTE_PACKED IVYIO_GET_MULTI_PICTURE_EX, *PIVYIO_GET_MULTI_PICTURE_EX;
// Multi-picture information to request
typedef struct _IVYIO_GET_MULTI_PICTURE_
{
int sln; // must be 0
int countOfUsed; // Can be used picture array count
IVYIO_GET_PICTURE picture[20]; // max size 20
}ATTRIBUTE_PACKED IVYIO_GET_MULTI_PICTURE, *PIVYIO_GET_MULTI_PICTURE;
// Picture data
typedef struct _IVYIO_PICTURE_FILE_
{
int channel; // Channel
int format; // Picture format, same as type in IVYIO_GET_PICTURE structure
int type; // Picture type, same as type in IVYIO_GET_PICTURE structure
unsigned long long time; // Timestamp
unsigned int size; // Picture data size
char data[0]; // Picture data
}ATTRIBUTE_PACKED IVYIO_PICTURE_FILE, *PIVYIO_PICTURE_FILE;
- 备注
iChanel目前请传0;files是一个指针数组,为每个元素申请一块内存,然后用 IVYIO_PICTURE_FILE 结构指针分别访问每个内存即可。
- 调用示例 1
if (IVYIO_DEV_IPC == devType)
{
IVYIO_PICTURE_LIST ipl;
memset(&ipl, 0, sizeof(IVYIO_PICTURE_LIST));
// Get picture list
......
IVYIO_GET_MULTI_PICTURE *request = new IVYIO_GET_MULTI_PICTURE();
request->sln = 0;
request->countOfUsed = 2;
request->picture[0].time = ipl.list[0].time;
request->picture[0].type = ipl.list[0].type;
request->picture[0].format = ipl.list[0].format;
request->picture[1].time = ipl.list[1].time;
request->picture[1].type = ipl.list[1].type;
request->picture[1].format = ipl.list[1].format;
// Pictures memory
void *buffer[20];
for (int i = 0; i < 20; i++)
{
buffer[i] = new char[1024 * 1024];
memset(buffer[i], 0, 1024 * 1024);
}
int pictureCount = 0;
IVYIO_RESULT rst = IVYIO_GetPicture(handle, (void *)request, buffer, &pictureCount, 1000 * 10, 0);
if (IVYIO_RESULT_OK == rst)
{
int len = 0;
char szText[1024] = {0};
for (int i = 0; i < pictureCount; i++)
{
IVYIO_PICTURE_FILE *pictureFile = (IVYIO_PICTURE_FILE *)buffer[i];
if (pictureFile->size > 0)
{
// Picture data in pictureFile->data
}
}
}
}
- 调用示例 2
if (IVYIO_DEV_IPC == devType)
{
IVYIO_PICTURE_LIST_EX ipl;
memset(&ipl, 0, sizeof(IVYIO_PICTURE_LIST_EX));
// Get picture listex
......
IVYIO_GET_MULTI_PICTURE_EX *request = new IVYIO_GET_MULTI_PICTURE_EX();
request->sln = 1;
request->countOfUsed = 2;
request->picture[0].time = ipl.list[0].time;
request->picture[0].type = ipl.list[0].type;
request->picture[0].format = ipl.list[0].format;
request->picture[1].time = ipl.list[1].time;
request->picture[1].type = ipl.list[1].type;
request->picture[1].format = ipl.list[1].format;
request->pictureEx[0].direction = ipl.list[0].direction;
request->pictureEx[0].weight = ipl.list[0].weight;
request->pictureEx[1].direction = ipl.list[1].direction;
request->pictureEx[1].weight = ipl.list[1].weight;
// Pictures memory
void *buffer[20];
for (int i = 0; i < 20; i++)
{
buffer[i] = new char[1024 * 1024];
memset(buffer[i], 0, 1024 * 1024);
}
int pictureCount = 0;
IVYIO_RESULT rst = IVYIO_GetPicture(handle, (void *)request, buffer, &pictureCount, 1000 * 10, 0);
if (IVYIO_RESULT_OK == rst)
{
int len = 0;
char szText[1024] = {0};
for (int i = 0; i < pictureCount; i++)
{
IVYIO_PICTURE_FILE *pictureFile = (IVYIO_PICTURE_FILE *)buffer[i];
if (pictureFile->size > 0)
{
// Picture data in pictureFile->data
}
}
}
}
13. RTSP API (非线程安全)
13.1 打开RTSP
- 描述
根据URL打开一个RTSP实例
void * IVYIO_RTSP_Open(const char *url)
- 参数
url | url地址 |
---|
- 返回值
void 指针,实际是一个RTSP的实例地址。
如果打开RTSP失败,返回NULL.
- 备注
海康设备URL地址为rtsp://admin:123456@192.168.1.68:554/Streaming/Channels
- 调用示例
void *rtsp = IVYIO_RTSP_Open("rtsp://admin:123456@192.168.1.68:554/Streaming/Channels");
13.2 关闭RTSP
- 描述
关闭RTSP
int IVYIO_RTSP_Close(void *inst);
- 参数
inst | 实例地址 |
---|
- 返回值
0 为成功,其他值为失败
- 调用示例
void *rtsp = IVYIO_RTSP_Open("rtsp://admin:123456@192.168.1.68:554/Streaming/Channels");
...
IVYIO_RTSP_Close(rtsp);
13.3 获取RTSP流(原始视频+PCM音频)
- 描述
获取RTSP流(包含视频音频,视频为原始视频,音频为解码后的PCM)
int IVYIO_RTSP_GetRawFrameAndPCM(void *inst, unsigned char **frame, int *frameSize, IVYIO_RTSP_VIDEO_INFO *videoinfo, IVYIO_RTSP_AUDIO_INFO *audioInfo, int *audioOrVideo);
- 参数
inst | 实例地址 |
---|---|
frame | 指向流数据指针的指针 |
frameSize | 流的数据大小 |
videoinfo | 当前视频流信息,参考 IVYIO_RTSP_VIDEO_INFO |
audioInfo | 当前音频流信息,参考 IVYIO_RTSP_AUDIO_INFO |
audioOrVideo | 视频音频标志,参考 IVYIO_RTSP_FRAME_TYPE |
- 返回值
0 为成功,其他值为失败
- 调用示例
unsigned char *frame = NULL;
int size = 0;
int frameType = 0;
IVYIO_RTSP_VIDEO_INFO v;
IVYIO_RTSP_AUDIO_INFO a;
memset(&v, 0, sizeof(v));
memset(&a, 0, sizeof(a));
if (0 == IVYIO_RTSP_GetRawFrameAndPCM(rtsp, &frame, &size, &v, &a, &frameType))
{
// get data ok!
}
- 引用
typedef struct _IVYIO_RTSP_VIDEO_INFO_
{
int w;
int h;
int key;
int fmt; // see IVYIO_RTSP_CODEC_ID
}ATTRIBUTE_PACKED IVYIO_RTSP_VIDEO_INFO, *PIVYIO_RTSP_VIDEO_INFO;
typedef struct _IVYIO_RTSP_AUDIO_INFO_
{
int codecId;
int sampleRate;
int sampleFmt; // see IVYIO_RTSP_SAMPLE_FMT
int channels;
int channelLayout;
}ATTRIBUTE_PACKED IVYIO_RTSP_AUDIO_INFO, *PIVYIO_RTSP_AUDIO_INFO;
typedef enum
{
IVYIO_RTSP_CODEC_ID_UNKNOWN = -1,
IVYIO_RTSP_CODEC_ID_H264 = 0,
IVYIO_RTSP_CODEC_ID_HEVC = 1,
IVYIO_RTSP_CODEC_ID_AAC = 2,
IVYIO_RTSP_CODEC_ID_PCM = 3,
IVYIO_RTSP_CODEC_ID_PCM_MULOW = 4,
IVYIO_RTSP_CODEC_ID_PCM_ALOW = 5
} IVYIO_RTSP_CODEC_ID;
typedef enum
{
IVYIO_RTSP_SAMPLE_FMT_UNKNOWN = -1,
IVYIO_RTSP_SAMPLE_FMT_S16 = 1
} IVYIO_RTSP_SAMPLE_FMT;
typedef enum
{
IVYIO_RTSP_FRAME_VIDEO = 0,
IVYIO_RTSP_FRAME_AUDIO = 1
} IVYIO_RTSP_FRAME_TYPE;
13.4 获取RTSP流(解码视频+PCM音频)
- 描述
获取RTSP流(包含视频音频,视频为解码后的视频,音频为解码后的PCM)
int IVYIO_RTSP_GetFrame(void *inst, unsigned char **frame, int *frameSize, IVYIO_RTSP_VIDEO_INFO *videoinfo, IVYIO_RTSP_AUDIO_INFO *audioInfo, int *audioOrVideo, int videoDecodeFmt);
- 参数
inst | 实例地址 |
---|---|
frame | 指向流数据指针的指针 |
frameSize | 流的数据大小 |
videoinfo | 当前视频流信息,参考 IVYIO_RTSP_VIDEO_INFO |
audioInfo | 当前音频流信息,参考 IVYIO_RTSP_AUDIO_INFO |
audioOrVideo | 视频音频标志,参考 IVYIO_RTSP_FRAME_TYPE |
videoDecodeFmt | 视频解码格式,参考 IVYIO_DECODE_FORMAT |
- 返回值
0 为成功,其他值为失败
- 调用示例
unsigned char *frame = NULL;
int size = 0;
int frameType = 0;
IVYIO_RTSP_VIDEO_INFO v;
IVYIO_RTSP_AUDIO_INFO a;
memset(&v, 0, sizeof(v));
memset(&a, 0, sizeof(a));
if (0 == IVYIO_RTSP_GetFrame(rtsp, &frame, &size, &v, &a, &frameType, IVYIO_DEC_TYPE_UYVY422))
{
// get data ok!
}
- 引用
typedef struct _IVYIO_RTSP_VIDEO_INFO_
{
int w;
int h;
int key;
int fmt; // see IVYIO_RTSP_CODEC_ID
}ATTRIBUTE_PACKED IVYIO_RTSP_VIDEO_INFO, *PIVYIO_RTSP_VIDEO_INFO;
typedef struct _IVYIO_RTSP_AUDIO_INFO_
{
int codecId;
int sampleRate;
int sampleFmt; // see IVYIO_RTSP_SAMPLE_FMT
int channels;
int channelLayout;
}ATTRIBUTE_PACKED IVYIO_RTSP_AUDIO_INFO, *PIVYIO_RTSP_AUDIO_INFO;
typedef enum
{
IVYIO_RTSP_CODEC_ID_UNKNOWN = -1,
IVYIO_RTSP_CODEC_ID_H264 = 0,
IVYIO_RTSP_CODEC_ID_HEVC = 1,
IVYIO_RTSP_CODEC_ID_AAC = 2,
IVYIO_RTSP_CODEC_ID_PCM = 3,
IVYIO_RTSP_CODEC_ID_PCM_MULOW = 4,
IVYIO_RTSP_CODEC_ID_PCM_ALOW = 5
} IVYIO_RTSP_CODEC_ID;
typedef enum
{
IVYIO_RTSP_SAMPLE_FMT_UNKNOWN = -1,
IVYIO_RTSP_SAMPLE_FMT_S16 = 1
} IVYIO_RTSP_SAMPLE_FMT;
typedef enum
{
IVYIO_RTSP_FRAME_VIDEO = 0,
IVYIO_RTSP_FRAME_AUDIO = 1
} IVYIO_RTSP_FRAME_TYPE;
typedef enum
{
IVYIO_DECODE_VIDEORAW,
IVYIO_DECODE_ARGB32, //packed ARGB 8:8:8:8, 32bpp, ARGBARGB...
IVYIO_DECODE_RGBA32, //packed RGBA 8:8:8:8, 32bpp, RGBARGBA...
IVYIO_DECODE_ABGR32, //packed ABGR 8:8:8:8, 32bpp, ABGRABGR...
IVYIO_DECODE_BGRA32, //packed BGRA 8:8:8:8, 32bpp, BGRABGRA...
IVYIO_DECODE_RGB24, //packed RGB 8:8:8, 24bpp, RGBRGB...
IVYIO_DECODE_BGR24, //packed RGB 8:8:8, 24bpp, BGRBGR...
IVYIO_DECODE_RGB565BE, //packed RGB 5:6:5, 16bpp, (msb) 5R 6G 5B(lsb), big-endian
IVYIO_DECODE_RGB565LE, //packed RGB 5:6:5, 16bpp, (msb) 5R 6G 5B(lsb), little-endian
IVYIO_DECODE_BGR565BE, //packed BGR 5:6:5, 16bpp, (msb) 5B 6G 5R(lsb), big-endian
IVYIO_DECODE_BGR565LE, //packed BGR 5:6:5, 16bpp, (msb) 5B 6G 5R(lsb), little-endian
IVYIO_DECODE_YUV420,
IVYIO_DECODE_YUYV422,
IVYIO_DECODE_UYVY422,
IVYIO_DECODE_H264,
IVYIO_DECODE_MJPEG,
IVYIO_DECODE_MJPEG_BASE64,
IVYIO_DECODE_H264_BASE64,
IVYIO_DECODE_AUDIORAW,
IVYIO_DECODE_G726,
IVYIO_DECODE_G711U,
IVYIO_DECODE_PCM,
IVYIO_DECODE_ADPCM,
IVYIO_DECODE_G711A,
IVYIO_DECODE_AAC,
IVYIO_DECODE_HEVC
} IVYIO_DECODE_FORMAT;
14. 双向视频
14.1 打开双向视频
- 描述
打开双向视频,告诉设备将要发音频视频数据给它
IVYIO_RESULT IVYIO_API IVYIO_OpenSendLive(IVYIO_HANDLE handle, int op, int timeout);
- 参数
handle | SDK句柄 |
---|---|
op | 将要发送的媒体类型。按位表示 bit0:video bit1:audio |
timeout | 超时,单位ms |
- 返回值
参考 IVYIO_RESULT
- 备注
- 调用示例
// Create SDK handle for IVY two-way-video IPC with main stream video
IVYIO_URL url;
memset(&url, 0, sizeof(url));
strcpy(url.szUrl, "192.168.1.1");
url.usPort = 88;
IVYIO_HANDLE handle = IVYIO_CreateEx_1(&url, "ABCDABCDABCDABCDABCD2222", "", "admin", "", IVYIO_P2P_MODE_UDP, IVYIO_DEV_TWO_WAY_VIDEO_CAMERA, IVYIO_MAIN_VIDEO_STREAM);
IVYIO_RESULT rst = IVYIO_OpenSendLive(handle, IVYIO_LIVE_CALL_VIDEO | IVYIO_LIVE_CALL_AUDIO, 1000 * 20);
14.2 关闭双向视频
- 描述
关闭双向视频,告诉设备将要关闭发音频视频数据
IVYIO_RESULT IVYIO_API IVYIO_CloseSendLive(IVYIO_HANDLE handle, int op, int timeout);
- 参数
handle | SDK句柄 |
---|---|
op | 将要发送的媒体类型。按位表示 bit0:video bit1:audio |
timeout | 超时,单位ms |
- 返回值
参考 IVYIO_RESULT
- 调用示例
// ......
IVYIO_RESULT rst = IVYIO_CloseSendLive(handle, IVYIO_LIVE_CALL_VIDEO | IVYIO_LIVE_CALL_AUDIO, 1000 * 20);
// ......
14.3 发送视频
- 描述
发送视频,将视频放到SDK缓冲区内,SDK会自动发送
IVYIO_RESULT IVYIO_API IVYIO_SendVideo(IVYIO_HANDLE handle, char *frame, int len);
- 参数
handle | SDK句柄 |
---|---|
frame | 存放 IVYIO_FRAME 结构的内存 |
len | 存放 IVYIO_FRAME 结构的内存的大小 |
- 返回值
参考 IVYIO_RESULT
- 备注
如果缓冲区放不下视频数据,SDK会丢弃视频。缓冲区大小为 3M
- 调用示例
// videodata is one h264 frame
// videodataSize is frame len
char *buffer = new char[1024 * 1024];
IVYIO_FRAME *videoFrame = (IVYIO_FRAME *)buffer;
videoFrame->channel = 0;
videoFrame->iKey = 1;
videoFrame->index = index++;
videoFrame->len = videodataSize;
videoFrame->pts = index;
videoFrame->media.video.w = 1280;
videoFrame->media.video.h = 960;
videoFrame->media.video.bitRate = 26000;
videoFrame->media.video.frameRate = 25;
videoFrame->fmt = IVYIO_STREAM_H264;
videoFrame->type = IVYIO_STREAM_VIDEO;
memcpy(videoFrame->data, videodata, videodataSize);
rst = IVYIO_SendVideo(handle, buffer, videoFrame->len + sizeof(IVYIO_FRAME));
14.4 发送音频
- 描述
发送音频,将音频放到SDK缓冲区内,SDK会自动发送
IVYIO_RESULT IVYIO_API IVYIO_SendAudio(IVYIO_HANDLE handle, char *frame, int len);
- 参数
handle | SDK句柄 |
---|---|
frame | 存放 IVYIO_FRAME 结构的内存 |
len | 存放 IVYIO_FRAME 结构的内存的大小 |
- 返回值
参考 IVYIO_RESULT
- 备注
如果缓冲区放不下音频数据,SDK会丢弃音频。缓冲区大小为 128KB
- 调用示例
// audiodata is one package
char *buffer = new char[1024 * 1024];
IVYIO_FRAME *audioFrame = (IVYIO_FRAME *)buffer;
audioFrame->channel = 0;
audioFrame->iKey = 1;
audioFrame->index = index++;
audioFrame->len = 960;
audioFrame->pts = index;
audioFrame->media.audio.bitsPerSample = 16;
audioFrame->media.audio.channels = 2;
audioFrame->media.audio.sample = 8000;
audioFrame->fmt = IVYIO_STREAM_PCM;
audioFrame->type = IVYIO_STREAM_AUDIO;
memcpy(audioFrame->data, audiodata, 960);
rst = IVYIO_SendVideo(handle, buffer, audioFrame->len + sizeof(IVYIO_FRAME));
14.5 拒绝视频
- 描述
告诉IPC,当前APP拒绝视频
IVYIO_RESULT IVYIO_API IVYIO_RejectVideoCall(IVYIO_HANDLE handle, int timeout);
- 参数
handle | SDK句柄 |
---|---|
timeout | 超时,单位ms |
- 返回值
参考 IVYIO_RESULT
- 调用示例
// ......
IVYIO_RESULT rst = IVYIO_RejectVideoCall(handle, 1000 * 20);
// ......
14.6 获取双向视频状态
- 描述
获取双向视频状态
IVYIO_RESULT IVYIO_API IVYIO_GetVideoCallState(IVYIO_HANDLE handle, int *state, int timeout);
- 参数
handle | SDK句柄 |
---|---|
state | (通话状态:0-空闲,1-呼叫中,2-通话中 |
timeout | 超时,单位ms |
- 返回值
参考 IVYIO_RESULT
- 调用示例
// ......
int state = -1;
IVYIO_RESULT rst = IVYIO_GetVideoCallState(handle, &state, 1000 * 20);
// ......