- Java 接口文档,适用于 Android
- 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句柄(1.1)(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.4.1 暂停
- 7.4.2 恢复
- 7.4.3 SEEK
- 7.4.4 暂停ex
- 7.4.5 恢复ex
- 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 获取更多模式直播已经解码后的数据
- 8.6 获取更多模式回放已经解码后的数据
- 8.7 解码回放视频数据
- 9. 发送命令
- 9.1 发送命令(推荐使用)
- 9.2 发送CGI
- 10. 辅助接口
- 10.1 获取事件
- 10.1.1 获取事件2
- 10.2 将关键帧转成一张图片
- 10.3 查询SDK接口的调用状态
- 10.4 清除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.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 获取摄像机双向视频状态
Java 接口文档,适用于 Android
1. 初始化
1.1 初始化设备
- 描述
初始化SDK,使用SDK前必须调用且调用一次即可。
void init()
- 备注
初始化时SDK内部会启动搜索线程,初始化P2P,启动内部时钟线程。
- 调用示例
IvyIoSdkJni.init();
2. SDK版本号和日志系统
2.1 SDK版本号
- 描述
获取SDK版本号
String version()
- 返回值
String类型,版本号
- 调用示例
String strVersion = IvyIoSdkJni.version();
2.2 设置日志级别和路径
- 描述
设置日志打印和日志级别
void setLog(int level, String path, int maxSize)
- 参数
level | 日志级别 |
---|---|
path | 保存文件路径 |
maxSize | 日志文件最大值,单位为M |
- level级别
package com.ivyio.sdk;
public class LogLevel {
public static final int NO = 0;
public static final int ERR = 1;
public static final int DBG = 2;
public static final int ALL = 3;
}
- 备注
SDK默认日志级别是全部输出,如果szPath为NULL或者长度为0,不会有日志写到指定路径;iMaxSize可以为0,表示使用默认大小5M
- 调用示例
String path = "/my/log/sdklog.log";
IvyIoSdkJni.setLog(LogLevel.ALL, path, 0);
3. 设备搜索
3.1 搜索局域网内设备
- *描述
搜索局域网内设备
int discovery(DiscoveryNode[] nodes, int countOfNode)
- 参数
nodes | 存放设备节点的DiscoveryNode类型数组 |
---|---|
countOfNode | 设备节点数量,nodes数组元素数量 |
- 返回值
实际搜索到的数量
- 调用示例
DiscoveryNode[] nodes = new DiscoveryNode[16];
int count = IvyIoSdkJni.discovery(nodes, 16);
if (count > 0)
{
......
}
3.2 重新启动设备搜索
- 描述
重新启动设备搜索
void restartDiscovery()
- 调用示例
IvyIoSdkJni.restartDiscovery();
3.3 停止搜索设备
- 描述
停止设备搜索
void stopDiscovery()
- 备注
停止搜索后,SDK将会使用P2P进行连接。
- 调用示例
IvyIoSdkJni.stopDiscovery();
3.3 获取当前搜索状态
- 描述
获取当前设备搜索的状态
int getDiscoveryState()
- 返回值
SDK当前设备搜索状态
0 | 设备搜索运行中 |
---|---|
1 | 设备搜索已经停止 |
- 备注
无
- 调用示例
int state = IvyIoSdkJni.getDiscoveryState();
if (0 == state)
{
......
}
else if (1 == state)
{
......
}
else
{
......
}
4. 登录设备
4.1 创建SDK句柄(1)(IVY设备建议使用此接口)
- 描述
创建SDK实例句柄
int create(Url url, String uid, String mac, String user, String password, int mode)
- 参数
url | Url对象,存放目标设备的连接地址和端口;地址可以是DDNS或者IP |
---|---|
uid | 目标设备的UID,可以为空 |
mac | 目标设备的MAC,可以为空 |
user | 目标设备的用户名,不能为空 |
password | 目标设备的密码,不能为空 |
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去连接。
- 调用示例
Url myUrl = new Url();
myUrl.url = "192.168.1.102";
myUrl.port = 8888;
int handle = IvyIoSdkJni.create(url, "ABCDABCDABCDABCDABCD2222", "", username", "password", P2PMode.P2P_MODE_UDP);
4.1.1 创建SDK句柄(1.1)(IVY低功耗设备必须使用此接口)
- 描述
创建SDK实例句柄
int create1(Url url, String uid, String mac, String user, String password, int mode, int lowPower)
- 参数
url | Url对象,存放目标设备的连接地址和端口;地址可以是DDNS或者IP |
---|---|
uid | 目标设备的UID,可以为空 |
mac | 目标设备的MAC,可以为空 |
user | 目标设备的用户名,不能为空 |
password | 目标设备的密码,不能为空 |
mode | P2P连接模式 0:UDP方式 1:TCP方式 2:自动 |
lowPower | 是否是低功耗设备 0:和Create(4.1章节)行为一样 1:表明当前设备是低功耗设备,SDK内部会启动接口调用计时器,超过指定时间没有调用SDK接口,SDK可以告诉应用,应用可以通过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去连接。
- 调用示例
Url myUrl = new Url();
myUrl.url = "192.168.1.102";
myUrl.port = 8888;
int handle = IvyIoSdkJni.create1(url, "ABCDABCDABCDABCDABCD2222", "", username", "password", P2PMode.P2P_MODE_UDP, 1);
4.2 创建SDK句柄(2)(Foscam设备建议使用此接口)
int createEx1(Url url, String uid, String mac, String user, String password, int mode, int fosDevType, int streamType)
- 描述
此接口功能和 create 一致,相同参数具有相同的意义和功能(参考 create),所有描述均适用于此接口,下面主要描述不同的参数含义。
- 参数
url | 同 create |
---|---|
uid | 同 create |
mac | 目标设备的MAC,可以为空 |
user | 同 create |
password | 同 create |
mode | 同 create |
fosDevType | 设备类型, 参见 DevType 定义,设备类型也可以从 discovery 中获取 |
streamType | 打开设备的码流类型,主码流或者子码流,参见 VideoStreamType 定义 |
- 调用示例
// Create SDK handle for Foscam IPC with main stream video
Url myUrl = new Url();
myUrl.url = "192.168.1.102";
myUrl.port = 8888;
int handle = IvyIoSdkJni.createEx1(url, "ABCDABCDABCDABCDABCDZZZZ", "", username", "password", P2PMode.P2P_MODE_UDP, DevType.FOS_IPC, VideoStreamType.MAIN_VIDEO_STREAM);
- 备注
何如用UID区分Foscam设备还是IVY设备,如果UID的21位(从0开始)是‘2’或者‘4’,表示此设备是IVY设备,其他情况说明设备是Foscam设备
4.3 销毁SDK句柄
- 描述
销毁SDK句柄并且释放资源
void destroy(int handle)
- 参数
handle | SDK句柄 |
---|
- 备注
调用此接口后,handle对应的SDK实例占用内存全部被释放。
请不要在不同线程销毁相同句柄,SDK无法处理这种操作,会引起Crash。
因为SDK为了让多个销毁操作可以同时进行,无法保证同一个句柄销毁的问题;如果SDK保证了同一句柄在不同线程销毁,那么当遇到多个句柄同时销毁的情况,运行速度会变的很慢,因为SDK必须使用同步保证句柄逐个销毁。
- 调用示例
IvyIoSdkJni.destroy(handle);
4.4 检测当前句柄对应设备的状态
- 描述
检测当前设备状态,是在线还是离线
int checkHandle(int handle)
- 参数
handle | SDK句柄 |
---|
- 返回值
设备状态,参见定义 HandleState
0 | 初始化状态 |
---|---|
1 | 正在连接 |
2 | 设备在线 |
3 | 设备离线 |
4 | 达到最大用户数 |
5 | 设备被锁 |
6 | 用户名或者密码错误 |
7 | 拒绝访问 |
8 | 未知 |
9 | 非法句柄 |
10 | 用户取消操作 |
- 引用
public class HandleState {
public static final int HANDLE_STATE_INIT = 0;
public static final int HANDLE_STATE_CONNECTTING = 1;
public static final int HANDLE_STATE_ONLINE = 2;
public static final int HANDLE_STATE_OFFLINE = 3;
public static final int HANDLE_STATE_MAX_USERS = 4;
public static final int HANDLE_STATE_LOCK = 5;
public static final int HANDLE_STATE_USR_OR_PWD_ERR = 6;
public static final int HANDLE_STATE_DENY = 7;
public static final int HANDLE_STATE_UNKNOWN = 8;
public static final int HANDLE_STATE_INVALID_HANDLE = 9;
public static final int HANDLE_STATE_CANCEL_BY_USR = 10;
public static final int HANDLE_STATE_ON_RESET = 11;
}
- 备注
有些状态只是一瞬间存在,可能无法获取到, 比如 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)
{
int state = IvyIoSdkJni.checkHandle(handle);
switch (state)
{
case HandleState.HANDLE_STATE_INIT:
case HandleState.HANDLE_STATE_CONNECTTING:
// SDK is connectting device
break;
case HandleState.HANDLE_STATE_ONLINE:
// SDK connected already.
break;
case HandleState.HANDLE_STATE_INVALID_HANDLE:
// Handle error
break;
case HandleState.HANDLE_STATE_OFFLINE:
// SDK disconnected
break;
default:
// Other state can ignore
break;
}
}
4.5 登录设备
- 描述
登陆设备
int login(int handle, int timeout)
- 参数
handle | SDK句柄 |
---|---|
iTimeout | 超时时间,单位ms |
- 返回值
操作结果
0 | 成功 |
---|---|
1 | 失败 |
2 | 句柄错误 |
3 | 用户名和密码错误 |
4 | 参数错误 |
5 | API运行时错误 |
6 | 拒绝访问 |
7 | 设备已经锁住 |
8 | 达到最大用户数 |
9 | 对讲被占用 |
10 | 用户已经取消操作 |
11 | 超时 |
12 | 不支持的操作 |
13 | 未知 |
14 | 不在线 |
- 引用
package com.ivyio.sdk;
public class Result {
public static final int OK = 0;
public static final int FAIL = 1;
public static final int HANDLE_ERR = 2;
public static final int USR_OR_PWD_ERR = 3;
public static final int ARGS_ERR = 4;
public static final int APITIME_ERR = 5;
public static final int DENY = 6;
public static final int LOCKED = 7;
public static final int MAX_USER = 8;
public static final int TALK_OPENED_BY_OTHERS = 9;
public static final int CANCEL_BY_USER = 10;
public static final int TIMEOUT = 11;
public static final int UNSUPPORT = 12;
public static final int UNKNOWN = 13;
public static final int OFFLINE = 14;
public static final int OK_ON_RESET_STATE = 15;
public static final int NO_PERMISSION = 16;
public static final int DOWNLOADING = 17;
public static final int RECORD_NOT_EXIST = 18;
public static final int RECORD_OPEN_FAIL = 19;
}
- 调用示例
// Login in 5s
int rst = IvyIoSdkJni.login(handle, 1000 * 5);
4.6 登出设备
- 描述
登出设备
void logout(int handle)
- 参数
handle | SDK句柄 |
---|
- 备注
登出操作只是断开所有与设备的连接,不会释放资源。
对于IVY设备,连接断开后,SDK内部不会进行重连,需要再次调用IVYIO_Login才会进行再一次连接。
对于Foscam设备,连接断开后,SDK内部还会自动进行重连,所以,如果不想要Foscam设备去自动重连,可以调用IVYIO_Destroy去销毁句柄。
如果发现无法连接上设备,IVYIO_Destroy后再次创建句柄去登录可能更有效。
- 调用示例
IvyIoSdkJni.logout(handle);
4.7 获取登录成功后P2P连接的TURN服务器信息
- 描述
获取登录成功后P2P连接的TURN服务器信息
void getCurTurnServer(int handle, TurnServerInfo turn)
- 参数
handle | SDK句柄 |
---|---|
TurnServerInfo | turn服务器信息 |
- 备注
请保证在登录(login api)成功后调用该接口,如果是局域网,turn信息不会被填充。
请注意TurnServerInfo.ip中可能含有’\n’字符,并且后边会有字符(打印出这个字符串可能会出现2行),这个是p2p返回的信息,不要漏掉,所以,请保证这个TurnServerInfo.ip字符串按照以’\0’结尾来处理。
‘\n’后边的字符是p2p库处理ipv4/ipv6的标志。
如果将IVYIO_TURN_INFO->ip保存在文件中,可能出现ip占用两行的情况。
比如:获取的ip为 28.32.3.42,实际内存中的值为 “28.32.3.42\n2”,请一定注意“\n”
- 引用
public class TurnServerInfo {
public int port;
public String ip;
}
- 调用示例
TurnServerInfo turn = new TurnServerInfo;
IvyIoSdkJni.getCurTurnServer(handle, turn);
4.8 指定P2P的turn服务器
- 描述
使用指定P2P的Turn服务器,使用后SDK直接调过请求分派服务器,直接连接turn开始打洞
int useTurnServer(int handle, TurnServerInfo turn)
- 参数
handle | SDK句柄 |
---|---|
TurnServerInfo | turn服务器信息 |
- 备注
设置turn后,SDK不会再去请求分派服务器,而是直接使用设置turn服务器去进行P2P连接,这样可以节省请求分派服务器的时间。
如果turn为空,或者turn不合法,如,ip长度为0,port为0,SDK会自动去请求分派服务器,保证p2p可以正常运行。
- 请在create之后login之前使用该接口
- 如果想要改变turn服务器,请destory之后create再调用该接口。
- 引用
public class TurnServerInfo {
public int port;
public String ip;
}
- 调用示例
TurnServerInfo turn = new TurnServerInfo();
// read turn info from file
XXXX_Read(turn);
TurnServerInfo(handle, turn);
4.9 指定FoscamP2P连接分派服务器区域
- 描述
当设备是IVY设备,并且UID[22]对应的字符是“GHIJ”中的一个,客户端需要指定SDK连接的分派服务器区域;如果不指定,SDK将会连接所有的分派服务器。
int setDispatchLocationType(int handle, int location)
- 参数
handle | SDK句柄 |
---|---|
location | 区域 0:国内 1:国外 |
- 备注
此接口支持IVY设备,在login之前,一定要调用此接口,否则SDK内部默认连接的将会是所有分派服务器;
如果location的值非法,SDK也将会连接所有分派服务器。
- 调用示例
int handle = IvyIoSdkJni.createXXX(......);
// indicate china
IvyIoSdkJni.setDispatchLocationType(handle, 0);
IvyIoSdkJni.login(handle);
...
5. 设备直播
5.1 打开直播视频
- 描述
打开视频
int openVideo(int handle, OpenVideoArgs args, int timeout, int channel)
- 参数
handle | SDK句柄 |
---|---|
args | 打开视频参数, 不同设备有不同的参数 |
timeout | 超时,单位ms |
channel | 通道号,可以一次打开多个设备,按位表示(bit0-bit31表示0-31通道),比如0x06,表示打开通道1和通道2 |
- 返回值
操作结果
- 备注
由于此接口支持多种设备打开视频,所以不同设备args参数会有不同的输入。当调用此接口打开视频的时候,SDK会在此时申请直播需要的内存(视频缓冲区,音频缓冲区)和解码器,当你调用关闭视频的时候,SDK会释放所申请的内存的解码器。同时媒体通道也是在这个时候连接上的,但是关闭的时候连接不会断开。
Foscam IPC / IVY IPC | args参数为指向 OpenVideoArgsType0 对象的指针; iChannel为0) |
---|---|
IVY NVR | args参数为指向 OpenVideoArgsType0 对象的指针; iChannel按位表示,bit0 - bit31 表示通道1-通道32,可同时指定多个通道) |
Foscam NVR | args参数位指向 OpenVideoArgsType1 对象的指针; iChannel按位表示,bit0 - bit31 表示通道1-通道32,可同时指定多个通道 |
- 注意
请一定保持 openVideo / closeVideo / openPlaybackEx / openPlayback / closePlayback 之间串行调用,不可并行调用,否则可能会出现获取不到直播或者回放视频流的情况,主要因为这几个接口有状态的维护。
- 引用
public class OpenVideoArgsType0 extends OpenVideoArgs{
public OpenVideoArgsType0() {
argsType = 0;
}
public int streamType;
}
public class OpenVideoArgsType1 extends OpenVideoArgs {
public OpenVideoArgsType1() {
argsType = 1;
}
public int streamType;
public int videoMode;
public int qcMode;
public int chMode;
public int reDecChs;
}
- 调用示例
if (DevType.IVY_IPC == devType || DevType.FOS_IPC == devType || DevType.FOS_DOORBELL == devType)
{
// Foscam IPC / IVY IPC open video with main stream
OpenVideoArgsType0 open = new OpenVideoArgsType0();
open.streamType = 0;
int rst = IvyIoSdkJni.openVideo(handle, open, 1000 * 5, 0);
}
else if (DevType.IVY_NVR == devType)
{
// IVY NVR open video with main stream in channel 1 and channel 3
OpenVideoArgsType0 open = new OpenVideoArgsType0();
open.streamType = 0;
int rst = IvyIoSdkJni.openVideo(handle, open, 1000 * 5, 0x05);
}
else if (DevType.FOS_NVR == devType)
{
// Foscam NVR open video with main stream in channel 1 and channel 2
OpenVideoArgsType1 open;
open.streamType = 0;
open.videoMode = 0;
open.qcMode = 0;
open.chMode = 0;
open.reDecChs = 0;
int rst = IvyIoSdkJni.openVideo(handle, open, 1000 * 5, 0x03);
}
5.2 关闭直播视频
- 描述
关闭视频
int closeVideo(int handle, int timeout, int channel)
- 参数
handle | SDK句柄 |
---|---|
timeout | 超时,单位ms |
channel | 通道号,Foscam IPC / IVY IPC 通道值为0, Foscam NVR / IVY NVR 按位指定关闭通道 |
- 返回值
操作结果
- 备注
关闭操作会将对应的视频内存释放,所以,在关闭视频之前不要再获取视频数据或者已经拿到的数据不要再使用(除非数据已经拷贝到你自己的内存中),否则会引起Crash。
- 注意
请一定保持 openVideo / closeVideo / openPlaybackEx / openPlayback / closePlayback 之间串行调用,不可并行调用,否则可能会出现获取不到直播或者回放视频流的情况,主要因为这几个接口有状态的维护。
- 调用示例
if (DevType.IVY_IPC == devType || DevType.FOS_IPC == devType || DevType.FOS_DOORBELL == devType)
{
// Foscam IPC / IVY IPC close video
int rst = IvyIoSdkJni.closeVideo(handle, 1000 * 5, 0);
}
else if (DevType.IVY_NVR == devType || DevType.FOS_NVR == devType)
{
// IVY NVR / Foscam NVR close video channel 4 and channel 5
int rst = IvyIoSdkJni.closeVideo(handle, 1000 * 5, 0x18);
}
5.3 打开直播音频
- 描述
打开音频
int openAudio(int handle, int audioStreamtype, int timeout, int channel)
- 参数
handle | SDK句柄 |
---|---|
audioStreamtype | 音频码流类型,0:主码流 1:子码流 |
timeout | 超时,单位ms |
channel | 通道号,同打开视频 |
- 返回值
操作结果
- 备注
打开音频之前,必须要打开视频,因为只有在打开视频的时候才会有媒体通道和设备建立连接,同理,如果关闭了视频,也无法打开音频,因为关闭视频的时候虽然媒体通道没有关闭,但是音频缓冲区已经被释放掉了。
- 调用示例
if (DevType.IVY_IPC == devType || DevType.FOS_IPC == devType || DevType.FOS_DOORBELL == devType)
{
// Foscam IPC / IVY IPC open audio with main stream
int rst = IvyIoSdkJni.openAudio(handle, 0, 1000 * 5, 0);
}
else if (DevType.IVY_NVR == devType)
{
// IVY NVR open audio with main stream in channel 1 and channel 3
int rst = IvyIoSdkJni.openAudio(handle, 0, 1000 * 5, 0x05);
}
else if (DevType.FOS_NVR == devType)
{
// We don't need to call this api, because Foscam NVR opened audio already when call open video api.
}
5.4 关闭直播音频
- 描述
关闭音频
int closeAudio(int handle, int timeout, int channel)
- 参数
handle | SDK句柄 |
---|---|
timeout | 超时,单位ms |
channel | 通道号,同打开视频 |
- 返回值
操作结果
- 调用示例
if (DevType.IVY_IPC == devType || DevType.FOS_IPC == devType || DevType.FOS_DOORBELL == devType)
{
// Foscam IPC / IVY IPC close video
int rst = IvyIoSdkJni.closeAudio(handle, 1000 * 5, 0);
}
else if (DevType.IVY_NVR == devType)
{
// IVY NVR / Foscam NVR close video channel 4 and channel 5
int rst = IvyIoSdkJni.closeAudio(handle, 1000 * 5, 0x18);
}
else if ( DevType.FOS_NVR == devType)
{
// We don't need to call this api, because Foscam NVR closed audio already when call close video api.
}
5.5 开始直播录像
- 描述
开始录像
int startRecord(int handle, int recordType, String fileName, int maxSize, int channel)
- 参数
handle | SDK句柄 |
---|---|
recordType | 录像类型 0:AVI 1:MP4 |
fileName | 录像完整路径名字 |
maxSize | 录像文件最大值,0表示使用默认值256M,单位为M |
channel | 通道0-31,一次只能使用一个通道 |
- 返回值
操作结果
- 备注
如果录像达到最大值,会产生录像达到最大值事件,如果分辨率有改变,也会产生分辨率改变的事件。
- 录像过程中可能会产生的事件
事件ID | 含义 | 处理方式 |
---|---|---|
2052 | 没有足够的空间 | 停止录像 |
2053 | 文件达到最大值 | 停止录像,重新录像 |
2054 | 分辨率改变 | 停止录像,重新录像 |
2055 | 路径不存在 | 停止录像 |
2056 | 未知录像错误 | 停止录像 |
- 调用示例
if (DevType.FOS_IPC == devType || DevType.IVY_IPC == devType || DevType.FOS_DOORBELL == devType)
{
int rst = IvyIoSdkJni.startRecord(handle, RecordType.MP4, "/record/record.mp4", 0, 0);
}
else if (DevType.FOS_NVR == devType || DevType.IVY_NVR == devType)
{
// Start record on channel 5
int rst = IvyIoSdkJni.startRecord(handle, RecordType.MP4, "/record/record.mp4", 0, 5);
}
5.6 停止直播录像
- 描述
停止录像
int stopRecord(int handle, int channel)
- 参数
handle | SDK句柄 |
---|---|
iChannel | 通道0-31,一次只能使用一个通道 |
- 返回值
操作结果
- 调用示例
if (DevType.FOS_IPC == devType || DevType.IVY_IPC == devType || DevType.FOS_DOORBELL == devType)
{
int rst = IvyIoSdkJni.stopRecord(handle, 0);
}
else if (DevType.FOS_NVR == devType || DevType.IVY_NVR == devType)
{
// Start record on channel 5
int rst = IvyIoSdkJni.stopRecord(handle, 5);
}
6. 对讲
6.1 打开对讲
- 描述
打开对讲
int openTalk(int handle, int timeout, int channel)
- 参数
handle | SDK句柄 |
---|---|
timeout | 超时,单位ms |
channel | 通道号0-31,一次只能打开一个通道,如果要打开通道0,iChannel为0,如果要打开通道1,iChannel为1 |
- 返回值
操作结果
- 调用示例
if (DevType.IVY_IPC == devType || DevType.FOS_IPC == devType || DevType.FOS_DOORBELL == devType)
{
int rst = IvyIoSdkJni.openTalk(handle, 1000 * 5, 0);
}
else if (DevType.IVY_NVR == devType || DevType.FOS_NVR == devType)
{
// Open talk channel 2
int rst = IvyIoSdkJni.openTalk(handle, 1000 * 5, 2);
}
6.2 关闭对讲
- 描述
关闭对讲
int closeTalk(int handle, int timeout, int channel)
- 参数
handle | SDK句柄 |
---|---|
timeout | 超时,单位ms |
channel | 同打开对讲 |
- 返回值
操作结果
- 调用示例
if (DevType.IVY_IPC == devType || DevType.FOS_IPC == devType || DevType.FOS_DOORBELL == devType)
{
int rst = IvyIoSdkJni.closeTalk(handle, 1000 * 5, 0);
}
else if (DevType.IVY_NVR == devType || DevType.FOS_NVR == devType)
{
// Close talk channel 2
int rst = IvyIoSdkJni.closeTalk(handle, 1000 * 5, 2);
}
6.3 发送对讲数据
- 描述
发送对讲数据
int sendTalkData(int handle, byte[] data, int sizeOfData, int channel)
- 参数
handle | SDK句柄 |
---|---|
data | 对讲数据buffer |
sizeOfData | 对讲数据大小 |
channel | 同打开对讲 |
- 返回值
操作结果
- 调用示例
byte[] talkFrame = new byte[960];
// Get talk data to talkData
// Talk data sample is 8000, data size is 960 bytes
......
if (DevType.IVY_IPC == devType || DevType.FOS_IPC == devType || DevType.FOS_DOORBELL == devType)
{
int rst = IvyIoSdk.sendTalkData(handle, talkData, 960, 0);
}
else if (DevType.IVY_NVR == devType || DevType.FOS_NVR == devType)
{
// Send talk to channel 2
int rst = IvyIoSdk.sendTalkData(handle, talkData, 960, 2);
}
7. 设备回放
7.1 获取设备的录像列表
- 描述
获取回放列表
int getPlaybackRecordList(int handle, GetPlaybackListArgs args, PlaybackRecordListArgs list, int timeout, int channel)
- 参数
handle | SDK句柄 |
---|---|
args | 指向请求录像列表对象 |
list | 指向回放列表对象 |
timeout | 超时,单位ms |
channel | 通道号,同打开视频 |
- 返回值
操作结果
- 备注
录像的搜索时间不能跨天,最多就是一天的开始到结束,0:00 - 23:59:59; 通常应用都是搜索某一天的录像
- 不同设备类型对应的args和list
设备类型 | args | list |
---|---|---|
IVY IPC | GetPlaybackListArgsType0 | PlaybackRecordListArgsArrayType0 |
IVY NVR | GetPlaybackListArgsType0 | PlaybackRecordListArgsArrayType0 |
Foscam IPC | GetPlaybackListArgsType2 | PlaybackRecordListArgsType2 |
Foscam IPC (如果能力集val12中bit5支持) | GetPlaybackListArgsType4 | PlaybackRecordListArgsType4 |
Foscam NVR | GetPlaybackListArgsType3 | PlaybackRecordListArgsType3 |
- GetPlaybackListArgsType0中type定义
录像类型 | 值 |
---|---|
手动录像 | 1 |
计划录像 | 2 |
移动报警录像 | 4 |
声音报警录像 | 8 |
IO报警录像 | 16 |
温度报警录像 | 32 |
湿度报警录像 | 64 |
人形侦测报警录像 | 128 |
一键报警录像 | 256 |
录像类型是按位表示的,如果要搜索多种类型的录像,请将 GetPlaybackListArgsType0 对象的type按位设置
public class GetPlaybackListArgsType0 extends GetPlaybackListArgs {
public GetPlaybackListArgsType0() {
argsType = 0;
}
public long sTime; // start time, timestamp, unit second
public long eTime; // end time, timestamp, unit second
public int type; // record type
public int startNo; // Start index for search recording
public int cnt; // Search count, max 40
}
public class PlaybackRecordListArgsArrayType0 extends PlaybackRecordListArgs {
public PlaybackRecordListArgsArrayType0() {
playbackListArgsType = 0;
}
public PlaybackRecordListArgsType0[] list;
}
public class PlaybackRecordListArgsType0 {
public int totalCnt;
public int curCnt;
public PlaybackRecordListInfoArgsType0[] list;
}
public class PlaybackRecordListInfoArgsType0 {
public int channel;
public long sTime;
public long eTime;
public int recordType;
}
- GetPlaybackListArgsType2中recordType定义
录像类型 | 值 |
---|---|
计划录像 | 0 |
报警录像 | 1 |
全部录像 | 2 |
public class GetPlaybackListArgsType2 extends GetPlaybackListArgs {
public GetPlaybackListArgsType2() {
argsType = 2;
}
public String recordPath;
public int startTime; // start timestamp
public int endTime; // start timestamp
public int recordType;
public int startNo;
}
public class PlaybackRecordListArgsType2 extends PlaybackRecordListArgs {
public PlaybackRecordListArgsType2() {
playbackListArgsType = 2;
}
public int totalCnt;
public int curCnt;
public String[] recordInfo;
}
- GetPlaybackListArgsType4中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 |
车辆报警录像 | 0x00000001 << 15 |
public class FoscamRecordTypeV3 {
public static final int SCHEDULE = 1; // 计划
public static final int MANUAL = 2; // 手动
public static final int MDALARM = 4; // 移动报警
public static final int SDALARM = 8; // 声音报警
public static final int IOALARM = 16; // IO报警
public static final int TDALARM = 32; // 温度
public static final int HDALARM = 64; // 湿度
public static final int HMALARM = 128; // 人形报警
public static final int LIVERCD = 256;
public static final int TMALARM = 512;
public static final int BKALARM = 1024; // 按键
public static final int CLALARM = 2048; // 越线
public static final int LMALARM = 4096; // 留言
public static final int FDALARM = 8192; // 人脸
}
public class GetPlaybackListArgsType4 extends GetPlaybackListArgs {
public GetPlaybackListArgsType4() {
argsType = 4;
}
public long startTime; // start timestamp
public long endTime; // end timestamp
public int recordType; // see FoscamRecordTypeV3
public int startNo;
public int cnt;
public int recordPath; // Must be 0, SD card
}
public class PlaybackRecordListArgsType4 extends PlaybackRecordListArgs {
public int totalCnt;
public int curCnt;
public PlaybackRecordInfoType4 list[];
}
public class PlaybackRecordInfoType4 {
public long startTime;
public long endTime;
public int recordType;
public String fileName;
}
- GetPlaybackListArgsType3中recordType定义
注意:1. Foscam NVR搜索的通道号按位表示,不要多个通道分开搜索,否则获取的数据只有最后一次搜索通道的内容;2. 为了优化搜索录像速度,只有当startNO为0的时候,SDK才会去搜索录像(FoscamNVR搜索录像接口会一次搜索出所有录像),如果不是0,只是单纯的去内存拿数据
录像类型 | 值 |
---|---|
计划录像 | 1 |
手动录像 | 2 |
移动报警录像 | 4 |
io报警录像 | 8 |
按位表示每一种录像,可同时搜索多种录像。
public class GetPlaybackListArgsType3 extends GetPlaybackListArgs {
public GetPlaybackListArgsType3() {
argsType = 3;
}
public long startTime;
public long endTime;
public int recordType; // 1:schedule 2:manual 4:motion 8:ioalarm 1|2|4|8:all
public int startNo;
}
public class PlaybackRecordListArgsType3 extends PlaybackRecordListArgs {
public PlaybackRecordListArgsType3() {
playbackListArgsType = 3;
}
public int totalCnt;
public int curCnt;
public FosNvrRecordInfo[] recordInfo;
}
public class FosNvrRecordInfo {
public int indexNO;
public int channel;
public int fileSize;
public int startTime;
public int endTime;
public int recordType;
}
- 调用示例
if (DevType.IVY_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 (beijing)
long startUTCTime = 1619539200; // A day start
long endUTCTime = 1619539200 + 24 * 60 * 60 - 1; // A day end
GetPlaybackListArgsType0 get = new GetPlaybackListArgsType0();
get.sTime = startUTCTime;
get.eTime = endUTCTime;
get.startNo = 0;
get.cnt = 40;
get.type = 1 | 2 | 4 | 8;
PlaybackRecordListArgsArrayType0 list = new PlaybackRecordListArgsArrayType0();
int rst = IvyIoSdkJni.getPlaybackRecordList(handle, get, list, 1000 * 10, 0);
}
else if (DevType.IVY_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 (beijing) at channel0/1/2
long startUTCTime = 1619539200; // A day start
long endUTCTime = 1619539200 + 24 * 60 * 60; // A day end
GetPlaybackListArgsType0 get = new GetPlaybackListArgsType0();
get.sTime = startUTCTime;
get.eTime = endUTCTime;
get.startNo = 0;
get.cnt = 40;
get.type = 1 | 2 | 4 | 8;
PlaybackRecordListArgsArrayType0 list = new PlaybackRecordListArgsArrayType0();
int rst = IvyIoSdkJni.getPlaybackRecordList(handle, get, list, 1000 * 10, 0x07);
}
else if (DevType.FOS_IPC == devType)
{
// Foscam IPC
if (Ability_val12_bit5_support())
{
GetPlaybackListArgsType4 get = new GetPlaybackListArgsType4();
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 = FoscamRecordTypeV3.SCHEDULE | FoscamRecordTypeV3.MANUAL | FoscamRecordTypeV3.MDALARM | FoscamRecordTypeV3.SDALARM;
get.startNo = 10; // From index 10
get.cnt = 50;
PlaybackRecordListArgsType4 list = new PlaybackRecordListArgsType4();
int rst = IvyIoSdkJni.getPlaybackRecordList(handle, get, list, 1000 * 10, 0);
}
else
{
// All Foscam IPC support
GetPlaybackListArgsType2 get = new GetPlaybackListArgsType2();
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
PlaybackRecordListArgsType2 list = new PlaybackRecordListArgsType2();
int rst = IvyIoSdkJni.getPlaybackRecordList(handle, get, list, 1000 * 10, 0);
}
}
else if (DevType.FOS_NVR == devType)
{
// Foscam NVR
// Get all type of recordings on channel0/1/2
GetPlaybackListArgsType3 get = new GetPlaybackListArgsType3();
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;
PlaybackRecordListArgsType3 list = new PlaybackRecordListArgsType3();
int rst = IvyIoSdkJni.getPlaybackRecordList(handle, get, list, 1000 * 10, 0x07);
}
7.2 打开回放
- 描述
打开录像,不同的设备类型,有不同的参数
int openPlayback(int handle, OpenPlaybackArgs args, int timeout, int channel)
- 参数
handle | SDK句柄 |
---|---|
args | 打开回放参数对象 |
timeout | 超时,单位ms |
channel | 通道号,同打开视频 |
- 返回值
操作结果
- 备注
- 打开回放和打开直播采用同样的方式,关于回放的音视频缓冲区和解码器都是在打开的时候申请的,在关闭的时候释放掉。
- Foscam NVR 使用 OpenPlaybackArgsType2 的sTime和eTime表示要打开录像时间范围,offsetTime是范围中的一个时间,表示从这个时间开始播放。一般其实时间都是某一天的开始和结束时间。
- 如果是FoscamNVR,我们建议打开一整天的录像,这样数据流就会将一整天的数据给过来,很方便。
- 注意
请一定保持 openVideo / closeVideo / openPlaybackEx / openPlayback / closePlayback 之间串行调用,不可并行调用,否则可能会出现获取不到直播或者回放视频流的情况,主要因为这几个接口有状态的维护。
- args对应的对象类型
设备类型 | args |
---|---|
Foscam IPC | OpenPlaybackArgsType3 |
Foscam Doorbell | OpenPlaybackArgsType3 |
Foscam NVR | OpenPlaybackArgsType2 |
IVY IPC | OpenPlaybackArgsType0 |
IVY NVR | OpenPlaybackArgsType0 |
如果当前设备是IPC,iChannel值的设置请参考OpenVideo
- 对象定义
public class OpenPlaybackArgsType0 extends OpenPlaybackArgs {
public OpenPlaybackArgsType0(){
argsType = 0;
}
public long sTime;
public long eTime;
public int streamType;
}
public class OpenPlaybackArgsType2 extends OpenPlaybackArgs {
public OpenPlaybackArgsType2() {
argsType = 2;
}
public int sTime;
public int eTime;
public int offsetTime;
public int videoMode;
}
public class OpenPlaybackArgsType3 extends OpenPlaybackArgs {
public OpenPlaybackArgsType3() {
argsType = 3;
}
public String filePath;
}
- 调用示例
if (DevType.FOS_IPC == devType || DevType.FOS_DOORBELL == devType)
{
// Foscam IPC
if (Ability_val12_bit5_support())
{
GetPlaybackListArgsType4 get = new GetPlaybackListArgsType4();
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;
PlaybackRecordListArgsType4 list = new PlaybackRecordListArgsType4();
if (Result.OK == IvyIoSdkJni.getPlaybackRecordList(handle, get, list, 1000 * 10, 0))
{
OpenPlaybackArgsType3 open = new OpenPlaybackArgsType3();
open.filePath = list.list[0].fileName;
rst = IvyIoSdkJni.openPlayback(handle, open, 1000 * 5, 0);
}
}
else
{
// All Foscam IPC support
GetPlaybackListArgsType2 get = new GetPlaybackListArgsType2();
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
PlaybackRecordListArgsType2 list = new PlaybackRecordListArgsType2();
if (Result.OK == IvyIoSdkJni.getPlaybackRecordList(handle, get, list, 1000 * 10, 0))
{
OpenPlaybackArgsType3 open = new OpenPlaybackArgsType3();
open.filePath = list.recordInfo[0]
rst = IvyIoSdkJni.openPlayback(handle, open, 1000 * 5, 0);
}
}
}
else if (DevType.FOS_NVR == devType)
{
GetPlaybackListArgsType3 get = new GetPlaybackListArgsType3();
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
PlaybackRecordListArgsType3 list = new PlaybackRecordListArgsType3();
if (Result.OK == IvyIoSdkJni.getPlaybackRecordList(handle, get, list, 1000 * 10, 0x07))
{
// Open channel 0 and channel 1
OpenPlaybackArgsType2 open = new OpenPlaybackArgsType2();
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 = IvyIoSdkJni.openPlayback(handle, open, 1000 * 5, 0x07);
}
#else
// Open one recording
PlaybackRecordListArgsType3 list = new PlaybackRecordListArgsType3();
if (RESULT.OK == IvyIoSdkJni.getPlaybackRecordList(handle, get, list, 1000 * 10, 0x07))
{
// Open channel 0 and channel 1
OpenPlaybackArgsType2 open = new OpenPlaybackArgsType2();
open.sTime = list.recordInfo[0].startTime;
open.eTime = list.recordInfo[0].endTime;
open.offsetTime = 0;
open.videoMode = 0;
rst = IvyIoSdkJni.openPlayback(handle, &open, 1000 * 5, 0x07);
}
#endif
}
else if (DevType.IVY_IPC == devType)
{
GetPlaybackListArgsType0 get = new GetPlaybackListArgsType0();
get.sTime = 1619539200;
get.eTime = 1619539200 + 24 * 60 * 60 - 1;
get.startNo = 0;
get.cnt = 40;
get.type = 1 | 2 | 4 | 8;
PlaybackRecordListArgsType0 list = new PlaybackRecordListArgsType0();
if (RESULT.OK == IvyIoSdkJni.getPlaybackRecordList(handle, get, list, 1000 * 10, 0))
{
OpenPlaybackArgsType0 open = new OpenPlaybackArgsType0();
open.sTime = list.list[0].sTime;
open.eTime = list.list[0].eTime;
open.streamType = 0; // main stream
rst = IvyIoSdkJni.openPlayback(handle, open, 1000 * 5, 0);
}
}
else if (DevType.IVY_NVR == devType)
{
GetPlaybackListArgsType0 get = new GetPlaybackListArgsType0();
get.sTime = 1619539200;
get.eTime = 1619539200 + 24 * 60 * 60 - 1;
get.startNo = 0;
get.cnt = 40;
get.type = 1 | 2 | 4 | 8;
PlaybackRecordListArgsType0 list = new PlaybackRecordListArgsType0();
if (RESULT.OK == IvyIoSdkJni.getPlaybackRecordList(handle, get, list, 1000 * 10, 0x07))
{
OpenPlaybackArgsType0 open = new OpenPlaybackArgsType0();
open.sTime = list.list[0].sTime;
open.eTime = list.list[0].eTime;
open.streamType = 0; // main stream
rst = IvyIoSdkJni.openPlayback(handle, open, 1000 * 5, 0x07);
}
}
7.3 关闭回放
- 关闭回放
int closePlayback(int handle, ClosePlaybackArgs args, int timeout, int channel)
- 参数
handle | SDK句柄 |
---|---|
args | 指向关闭回放结构体指针 |
timeout | 超时,单位ms |
channel | 通道号 |
- 返回值
操作结果
- args参数结构体如下
设备类型 | args |
---|---|
Foscam IPC | ClosePlaybackArgsType0 |
Foscam NVR | ClosePlaybackArgsType0 |
Foscam DoorBell | ClosePlaybackArgsType0 |
IVY IPC | ClosePlaybackArgsType0 |
IVY NVR | ClosePlaybackArgsType0 |
如果是IPC设备,无论是Foscam还是IVY,iChannel的值要和OpenPlayback一致
- 注意
请一定保持 openVideo / closeVideo / openPlaybackEx / openPlayback / closePlayback 之间串行调用,不可并行调用,否则可能会出现获取不到直播或者回放视频流的情况,主要因为这几个接口有状态的维护。
- 调用示例
ClosePlaybackArgsType0 close;
int rst = IvyIoSdkJni.closePlayback(handle, close, 1000 * 5, 0);
7.4 回放控制
7.4.1 暂停
- 描述
暂停
int playbackPause(int handle, PlaybackPauseArgs args, int timeout)
- 参数
handle | SDK句柄 |
---|---|
args | PlaybackPauseArgs对象 |
timeout | 超时,单位ms |
- 返回值
操作结果
- 调用示例
PlaybackPauseArgsType0 pause = new PlaybackPauseArgsType0();
int rst = IvyIoSdkJni.playbackPause(handle, pause, 1000 * 5);
7.4.2 恢复
- 描述
恢复
int playbackResume(int handle, PlaybackResumeArgs args, int timeout)
- 参数
handle | SDK句柄 |
---|---|
args | PlaybackResumeArgs对象 |
timeout | 超时,单位ms |
- 返回值
操作结果
- 调用示例
PlaybackResumeArgs resume = new PlaybackResumeArgs();
int rst = IvyIoSdkJni.playbackResume(handle, resume, 1000 * 5);
7.4.3 SEEK
- 描述
跳转到指定位置播放(IVY设备:IPC:毫秒 NVR:秒)
int playbackSeekEx(int handle, PlaybackSeekArgs args, IvyIoInteger acturalTime, int timeout, int channel)
- 参数
handle | SDK句柄 |
---|---|
args | PlaybackResumeArgs对象 |
acturalTime | PlaybackSeekArgsType0 对象 |
timeout | 超时,单位ms |
channel | 超时,单位ms, Foscam设备可以忽略通道号,IVY设备按位表示通道上的设备 |
- 返回值
操作结果
- 调用示例
// 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
PlaybackSeekArgsType0 seek = new PlaybackSeekArgsType0();
seek.seekTime = 1619631000;
IvyIoInteger actualTime = new IvyIoInteger();
if (DevType.FOS_IPC == devType || DevType.FOS_NVR == devType || DevType.FOS_DOORBELL == devType || DevType.IVY_IPC == devType)
{
int rst = IvyIoSdkJni.playbackSeekEx(handle, seek, actualTime, 1000 * 5, 0);
}
else
{
// Seek on channel 0 / 1 / 2
int rst = IvyIoSdkJni.playbackSeekEx(handle, seek, actualTime, 1000 * 5, 0x07);
}
7.4.4 暂停ex
- 描述
暂停
int playbackPauseEx(int handle, PlaybackPauseArgs args, int timeout, int channel)
channel: 0-31,其他同 7.4.1
7.4.5 恢复ex
- 描述
恢复
int playbackResumeEx(int handle, PlaybackResumeArgs args, int timeout, int channel)
channel: 0-31,其他同 7.4.2
7.5 开始回放录像下载(IVY设备)
- 描述
下载录像,该API只能下载IVY IPC 和 IVY NVR录像。
注意:打开回放和录像下载不能同时进行
int downloadRecord(int handle, DownloadRecord record, String dstPath, int timeout)
- 参数
handle | SDK句柄 |
---|---|
record | DownloadRecord对象。所需参数可以从搜索录像的接口中获取 |
dstPath | 目的路经,不需要包含文件名,SDK内部会自动生成文件名 |
timeout | 超时 |
public class DownloadRecord {
public int channel;
public int startTime;
public int endTime;
public int recordType;
}
- 返回值
操作结果
- 产生事件
2063 | 录像进度事件 |
---|
- 备注
此接口只支持IVY设备和FoscamNVR设备,其他设备不支持。
对于IV设备,一次只能下载一个录像,不能并行下载,如果当前录像没有下载完成,接口返回
IVYIO_RESULT_DOWNLOADING(17),下载进度事件 IVY_CTRL_MSG_RECORD_DOWNLOAD_PROGRESS(2063)。设备每发送完一个录像数据,会断开下载连接,所以每个一个录像都需要调用一次下载接口。因为每次调用时SDK会去进行连接。
如果录像下载进度达到100%,不要调用IVYIO_DownLoadCannel。反之,如果录像下载没有达到100%,可以调用,并且下载的部分录像是可以播放的。
- 调用示例
DownloadRecord record = new DownloadRecord();
if(DevType.IVY_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 (DevType.IVY_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
}
int rst = IvyIoSdkJni.downLoadRecord(handle, record, "/record/record.mp4", 1000 * 5);
if (Result.OK != rst)
IvyIoSdkJni.downLoadCannel();
......
// Another thread get event
Event event = new Event();
if (Result.OK == IvyIoSdkJni.getEvent(handle, event))
{
if (2063 == event.id)
{
// event.data is json data for prgress, you can parse it.
}
}
7.6 取消回放录像下载(IVY设备)
- 描述
取消录像下载,如果下载录像进度已经到达100%,不需要调用此接口。如果没有达到,调用此接口后,部分下载的录像也可以播放。
void downloadRecordCancel(int handle)
- 参数
handle | SDK句柄 |
---|
- 返回值
操作结果
- 备注
此接口只支持IVY设备和FoscamNVR设备,其他设备不支持。
对于IVY设备,取消录像下载SDK没有向设备发送任何命令,只是断开下载连接。当再次调用下载接口时SDK内部会再次去连接下载通道。
- 调用示例
// You can see the chapter 7.5
7.7 开始回放录像下载(FosamIPC)
- 描述
下载 FoscamIPC SD卡录像
注意:打开回放和录像下载不能同时进行
int startDownLoadFosIPCRecord(int handle, String srcPath, String dstPath, int timeout)
- 参数
handle | SDK句柄 |
---|---|
srcPath | 录像源路径,可以通过getPlayBackRecordList获取 |
dstPath | 要保存的路径 |
timeout | 超时时间 |
- 返回值
操作结果
- 产生事件
2063 | 录像进度事件 |
---|
- 备注
此接口只支持FoscamIPC,其他设备均不支持。保存的录像格式是MP4
可以通过事件获取下载进度,SDK每收到一个视频帧都会给出一个进度,因此进度可能会有重复,上层需要对重复进度做一些处理。(每一个视频帧都有一个进度是因为如果视频帧数很多,会有很久才会有进度的情况)
如果进度值100,不需要调用取消接口。
- 调用示例
if(DevType.FOS_IPC == devType || DevType.FOS_DOORBELL == devType)
{
// srcPath come from IVYIO_RECORD_LIST_ARGS_TYPE2的recordInfo or
// IVYIO_RECORD_LIST_ARGS_TYPE4.list.fileName
String path = ......;
int rst = IvyIoSdkJni.startDownLoadFosIPCRecord(handle, path, "/record/record.mp4", 1000 * 5);
if (Result.OK != rst)
IvyIoSdkJni.stopDownLoadFosIPCRecord();
}
// Another thread get event
Event event;
if (Result.OK == IvyIoSdkJni.getEvent(handle, event))
{
if (2063 == event.id)
{
// event.data is json data for prgress, you can parse it.
}
}
#endif
7.8 取消回放录像下载(FosamIPC)
- 描述
取消 FoscamIPC SD卡录像
int stopDownLoadFosIPCRecord(int handle, int timeout)
- 参数
handle | SDK句柄 |
---|---|
timeout | 超时时间 |
- 返回值
操作结果
- 备注
此接口只支持FoscamIPC,其他设备均不支持。
如果录像没有下载完成,已经下载的部分有合法的视频数据,调用此接口后文件可以正常播放。
- 调用示例
// You can see the chapter 7.7
7.9 开始回放录像下载(FosamNVR)
- 描述
下载FoscamNVR硬盘录像
注意:打开回放和录像下载不能同时进行
int startDownloadFosNVRRecord(int handle, FosNvrRecordInfoArray recordInfo, String dstPath, int count)
- 参数
handle | SDK句柄 |
---|---|
recordInfo | FosNvrRecordInfoArray类型对象 |
dstPath | 要保存的路径,只要路径,不要文件名,会自动生成文件名字 |
count | 下载文件个数,也表明record指针对象个数 |
public class FosNvrRecordInfoArray {
public FosNvrRecordInfo[] records;
}
public class FosNvrRecordInfo {
public int indexNO;
public int channel;
public int fileSize;
public int startTime;
public int endTime;
public int recordType;
}
- 返回值
操作结果
- 产生事件
2063 | 录像进度事件 |
---|
- 备注
无论一次下载多个文件还是一个文件,进度值都表示本次调用下载接口后的整体进度。
- 调用示例
if(DevType.FOS_NVR == devType)
{
PlaybackRecordListArgsType3 list = new PlaybackRecordListArgsType3();
// 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].startTime = list.recordInfo[i].startTime;
record[i].endTime = list.recordInfo[i].endTime;
record[i].recordType = list.recordInfo[i].recordType;
}
int rst = IvyIoSdkJni.startDownloadFosNVRRecord(handle, record, "/record/", 10);
if (Result.OK != rst)
IvyIoSdkJni.stopDownloadFosNVRRecord(handle);
}
// Another thread get event
Event event = new Event();
if (Result.OK == IvyIoSdkJni.getEvent(handle, &event))
{
if (2063 == event.id)
{
// event.data is json data for prgress, you can parse it.
}
}
#endif
7.10 取消回放录像下载(FosamNVR)
- 描述
取消 FoscamIPC SD卡录像
int stopDownloadFosNVRRecord(int handle)
- 参数
handle | SDK句柄 |
---|
- 返回值
操作结果
- 备注
此接口只支持FoscamNVR,其他设备均不支持。
- 调用示例
// You can see the chapter 7.9
8. 获取直播/回放视频音频数据
8.1 获取直播已经解码后的数据
- 描述
获取直播已经解码后的数据
int getStreamData(int handle, int streamType, FrameData data, IvyIoInteger speed, int decodeFormat, int channel)
- 参数
handle | SDK句柄 |
---|---|
streamType | 码流类型 0:视频码流 1:音频码流 2: 视频码流将图像上下平分,然后左右重新组合。如果是IVY设备,支持 0/1/2,如果是Foscam设备,只支持 0/1 |
data | FrameData对象,存放解码后的音视频数据 |
speed | 媒体流速度 |
decodeFormat | 媒体数据解码类型 IVYIO_DECODE_FMT ,如果获取的是音频,忽略此参数 |
channel | 通道0-31,一次只能获取一个通道 |
- 返回值
操作结果
- 备注
获取到的媒体数据所需的内存是在SDK内部维护,不需要调用者申请。但是如果调用了关闭视频,媒体数据的内存会被释放,所以如果调用关闭视频,一定要保证此 FrameData 指针不再使用,否则会引起崩溃。(对于调用者来说,最常见的情况就是调用关闭视频之前保证播放媒体数据的线程退出)
- 引用
package com.ivyio.sdk;
public class FrameData {
public int channel;
public int index;
public int key;
public int frameTag;
public long pts;
public int type;
public int fmt;
public int video_w;
public int video_h;
public int video_frameRate;
public int video_bitRate;
public int audio_bitPerSample;
public int audio_channels;
public int audio_samples;
public int dataLen;
public byte[] data;
}
public class DecodeFormat {
public static final int VIDEORAW = 0;
public static final int ARGB32 = 1; //packed ARGB 8:8:8:8, 32bpp, ARGBARGB...
public static final int RGBA32 = 2; //packed RGBA 8:8:8:8, 32bpp, RGBARGBA...
public static final int ABGR32 = 3; //packed ABGR 8:8:8:8, 32bpp, ABGRABGR...
public static final int BGRA32 = 4; //packed BGRA 8:8:8:8, 32bpp, BGRABGRA...
public static final int RGB24 = 5; //packed RGB 8:8:8, 24bpp, RGBRGB...
public static final int BGR24 = 6; //packed RGB 8:8:8, 24bpp, BGRBGR...
public static final int RGB565BE = 7; //packed RGB 5:6:5, 16bpp, (msb) 5R 6G 5B(lsb), big-endian
public static final int RGB565LE = 8; //packed RGB 5:6:5, 16bpp, (msb) 5R 6G 5B(lsb), little-endian
public static final int BGR565BE = 9; //packed BGR 5:6:5, 16bpp, (msb) 5B 6G 5R(lsb), big-endian
public static final int BGR565LE = 10; //packed BGR 5:6:5, 16bpp, (msb) 5B 6G 5R(lsb), little-endian
public static final int YUV420 = 11;
public static final int YUYV422 = 12;
public static final int UYVY422 = 13;
public static final int H264 = 14;
public static final int MJPEG = 15;
public static final int MJPEG_BASE64 = 16;
public static final int H264_BASE64 = 17;
public static final int AUDIORAW = 18;
public static final int G726 = 19;
public static final int G711U = 20;
public static final int PCM = 21;
public static final int ADPCM = 22;
public static final int G711A = 23;
public static final int AAC = 24;
public static final int HEVC = 25;
}
- 调用示例
if (DevType.FOS_IPC == devType || DevType.IVY_IPC == devType || DevType.FOS_DOORBELL == devType)
{
// Get video in a thread
FrameData videoFrame = new FrameData();
while (bGetVideoRunning)
{
IvyIoInteger speed = new IvyIoInteger();
int rst = IvyIoSdkJni.getStreamData(handle, StreamType.STREAM_VIDEO, videoFrame, speed, DecodeFormat.RGBA32, 0);
if (Result.OK == rst && videoFrame.dataLen > 0)
{
// Display videoFrame.data
}
else
{
SystemClock.sleep(5); // Sleep 10ms
}
}
......
// Get audio in another thread
FrameData audioFrame = new FrameData();
while (bGetAudioRunning)
{
IvyIoInteger speed = new IvyIoInteger();
// If it's audio, no matter decode format you specify, it will be decoded to PCM,
// so you can ignore 'decodeFormat'.
int rst = IvyIoSdkJni.getStreamData(handle, StreamType.STREAM_AUDIO, audioFrame, speed, DecodeFormat.PCM, 0);
if (Result.OK == rst && audioFrame.dataLen > 0)
{
// Display audioFrame.data
}
else
{
SystemClock.sleep(5); // Sleep 10ms
}
}
}
else if (DevType.FOS_NVR == devType || DevType.IVY_NVR == devType)
{
// Get channel 2 video in a thread
FrameData videoFrameNVR = new FrameData();
while (bGetVideoRunning)
{
IvyIoInteger speed = new IvyIoInteger();
int rst = IvyIoSdkJni.getStreamData(handle, StreamType.STREAM_VIDEO, videoFrameNVR, speed, DecodeFormat.RGBA32, 2);
if (Result.OK == rst && videoFrameNVR.dataLen > 0)
{
// Display videoFrameNVR.data
}
else
{
SystemClock.sleep(10); // Sleep 10ms
}
}
......
// Get channel 2 audio in another thread
FrameData audioFrameNVR = new FrameData();
while (bGetAudioRunning)
{
IvyIoInteger speed = new IvyIoInteger();
int rst = IvyIoSdkJni.getStreamData(handle, StreamType.STREAM_AUDIO, audioFrameNVR, speed, DecodeFormat.PCM, 2);
if (Result.OK == rst && audioFrameNVR.dataLen > 0)
{
// Display audioFrameNVR.data
}
else
{
SystemClock.sleep(10); // Sleep 10ms
}
}
}
8.2 获取直播原始音视频数据
- 描述
获取直播中原始音视频数据
int getRawStreamData(int handle, int streamType, FrameData data, IvyIoInteger speed, int channel)
- 参数
handle | SDK句柄 |
---|---|
streamType | 码流类型 0:视频码流 1:音频码流 |
data | FrameData对象,存放音视频数据 |
speed | 媒体流速度 |
iChannel | 通道0-31,一次只能获取一个通道 |
- 返回值
操作结果
- 备注
此接口获取到的数据是没有经过解码的,是原始的H264数据或者H265数据;音频数据都是PCM,如果只是获取音频此接口和 getStreamData 一样。数据使用的注意事项和 getStreamData 一样
- 调用示例
if (DevType.FOS_IPC == devType || DevType.IVY_IPC == devType || DevType.FOS_DOORBELL == devType)
{
// Get video in a thread
FrameData videoFrame = new FrameData();
while (bGetVideoRunning)
{
IvyIoInteger speed = new IvyIoInteger();
int rst = IvyIoSdkJni.getRawStreamData(handle, StreamType.STREAM_VIDEO, videoFrame, speed, 0);
if (Result.OK == rst && videoFrame.dataLen > 0)
{
// Decode and display videoFrame.data
}
else
{
SystemClock.sleep(10); // Sleep 10ms
}
}
......
// Get audio in another thread
FrameData audioFrame = new FrameData();
while (bGetAudioRunning)
{
IvyIoInteger speed = new IvyIoInteger();
int rst = IvyIoSdkJni.getRawStreamData(handle, StreamType.STREAM_AUDIO, audioFrame, speed, 0);
if (Result.OK == rst && audioFrame.dataLen > 0)
{
// Decode and display audioFrame.data
}
else
{
SystemClock.sleep(10); // Sleep 10ms
}
}
}
else if (DevType.FOS_NVR == devType || DevType.IVY_NVR == devType)
{
// Get channel 2 video in a thread
FrameData videoFrameNVR = new FrameData();
while (bGetVideoRunning)
{
IvyIoInteger speed = new IvyIoInteger();
int rst = IvyIoSdkJni.getRawStreamData(handle, StreamType.STREAM_VIDEO, videoFrameNVR, speed, 2);
if (Result.OK == rst && videoFrameNVR.dataLen > 0)
{
// Decode and display videoFrameNVR.data
}
else
{
SystemClock.sleep(10); // Sleep 10ms
}
}
......
// Get channel 2 audio in another thread
FrameData audioFrameNVR = new FrameData();
while (bGetAudioRunning)
{
IvyIoInteger speed = new IvyIoInteger();
int rst = IvyIoSdkJni.getRawStreamData(handle, StreamType.STREAM_AUDIO, audioFrameNVR, speed, 2);
if (Result.OK == rst && audioFrameNVR.dataLen > 0)
{
// Decode and display audioFrameNVR.data
}
else
{
SystemClock.sleep(10); // Sleep 10ms
}
}
}
8.3 获取回放已解码音视频数据
- 描述
获取回放媒体数据
int getPlaybackStreamData(int handle, int streamType, FrameData data, IvyIoInteger speed, int decodeFormat, int channel)
- 参数
handle | SDK句柄 |
---|---|
streamType | 码流类型 0:视频码流 1:音频码流 |
data | FrameData对象,存放解码后的音视频数据 |
speed | 媒体流速度 |
decodeFormat | 媒体数据解码类型 DecodeFormat ,如果获取的是音频,忽略此参数,因为SDK只会将音频解码成PCM |
channel | 通道0-31,一次只能获取一个通道 |
- 返回值
操作结果
- 备注
注意事项同 getStreamData。如果当前设备是NVR,回放的时候你可能需要知道帧的更详细信息,你可以从FrameData中的frameTag获取。FrameTag.PLAYBACK_E_FRAME可以帮助你知道是否当前录像已经播完,如果发现一帧的frameTag为此类型,表示为当前录像最后一帧,数据可以忽略。
- 引用
public class FrameTag {
public static final int LIVE_FRAME = 0x4556494c;
public static final int PLAYBACK_FRAME = 0x4b424c50;
public static final int PLAYBACK_E_FRAME = 0x46454250;
public static final int PLAYBACK_S_FRAME = 0x46534250;
}
- 调用示例
if (DevType.FOS_IPC == devType || DevType.IVY_IPC == devType || DevType.FOS_DOORBELL == devType)
{
// Get video in a thread
FrameData videoFrame = new FrameData();
while (bGetVideoRunning)
{
IvyIoInteger speed = new IvyIoInteger();
int rst = IvyIoSdkJni.getPlaybackStreamData(handle, StreamType.STREAM_VIDEO, videoFrame, speed, DecodeFormat.RGBA32, 0);
if (Result.OK == rst && videoFrame.dataLen > 0)
{
// Display videoFrame.data
}
else
{
SystemClock.sleep(10); // Sleep 10ms
}
}
......
// Get audio in another thread
FrameData audioFrame = new FrameData();
while (bGetAudioRunning)
{
IvyIoInteger speed = new IvyIoInteger();
int rst = IvyIoSdkJni.getPlaybackStreamData(handle, StreamType.STREAM_AUDIO, audioFrame, speed, DecodeFormat.PCM, 0);
if (Result.OK == rst && audioFrame.dataLen > 0)
{
// Display audioFrame.data
}
else
{
SystemClock.sleep(10); // Sleep 10ms
}
}
}
else if (DevType.FOS_NVR == devType || DevType.IVY_NVR == devType)
{
// Get channel 2 video in a thread
FrameData videoFrameNVR = new FrameData();
while (bGetVideoRunning)
{
IvyIoInteger speed = new IvyIoInteger();
int rst = IvyIoSdkJni.getPlaybackStreamData(handle, StreamType.STREAM_VIDEO, videoFrameNVR, speed, DecodeFormat.RGBA32, 2);
if (Result.OK == rst && videoFrameNVR.dataLen > 0)
{
// Display frame->data
}
else
{
SystemClock.sleep(10); // Sleep 10ms
}
}
......
// Get channel 2 audio in another thread
FrameData audioFrameNVR = new FrameData();
while (bGetAudioRunning)
{
IvyIoInteger speed = new IvyIoInteger();
int rst = IvyIoSdkJni.getPlaybackStreamData(handle, StreamType.STREAM_AUDIO, audioFrameNVR, speed, DecodeFormat.PCM, 2);
if (Result.OK == rst && audioFrameNVR.dataLen > 0)
{
// Display audioFrameNVR.data
}
else
{
SystemClock.sleep(10); // Sleep 10ms
}
}
}
8.4 获取回放原始音视频数据
- 描述
获取回放原始媒体数据
int getPlaybackRawStreamData(int handle ,int streamType, FrameData data, IvyIoInteger speed, int channel)
- 参数
handle | SDK句柄 |
---|---|
streamType | 码流类型 0:视频码流 1:音频码流 |
data | FrameData结构,存放音视频数据 |
speed | 媒体流速度 |
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 获取更多模式直播已经解码后的数据
- 描述
获取更多模式直播已经解码后的数据
int getStreamDataEx(int handle, int streamType, FrameData data1, FrameData data1, IvyIoInteger speed, int decodeFormat, int channel)
- 参数
handle | SDK句柄 |
---|---|
streamType | 码流类型 0:视频码流 1:音频码流 2: 视频码流将图像上下平分,然后左右重新组合 3: 将视频码流上下拆分2个单独的图像;仅支持 IVY 设备 |
data1 | FrameData对象,存放解码后的音视频数据;如果 streamType 是 0/1/2, 数据在存放在 data1,如果 streamType 是 3,存放拆分数据 |
data2 | FrameData对象,存放解码后的音视频数据;如果 streamType 是 3, 存放拆分数据 |
speed | 媒体流速度 |
decodeFormat | 媒体数据解码类型 IVYIO_DECODE_FMT ,如果获取的是音频,忽略此参数 |
channel | 通道0-31,一次只能获取一个通道 |
- 返回值
操作结果
- 备注
获取到的媒体数据所需的内存是在SDK内部维护,不需要调用者申请。但是如果调用了关闭视频,媒体数据的内存会被释放,所以如果调用关闭视频,一定要保证此 FrameData 指针不再使用,否则会引起崩溃。(对于调用者来说,最常见的情况就是调用关闭视频之前保证播放媒体数据的线程退出)
streamType 是 0 / 1,支持 IVY 和 Foscam 设备。
streamType 是 2 / 3,仅支持 IVY 设备
- 调用示例
参考 8.1
8.6 获取更多模式回放已经解码后的数据
- 描述
获取更多模式回放已经解码后的数据
int getPlaybackStreamDataEx(int handle, int streamType, FrameData data1, FrameData data1, IvyIoInteger speed, int decodeFormat, int channel)
- 参数
handle | SDK句柄 |
---|---|
streamType | 码流类型 0:视频码流 1:音频码流 2: 视频码流将图像上下平分,然后左右重新组合 3: 将视频码流上下拆分2个单独的图像;仅支持 IVY 设备 |
data1 | FrameData对象,存放解码后的音视频数据;如果 streamType 是 0/1/2, 数据在存放在 data1,如果 streamType 是 3,存放拆分数据 |
data2 | FrameData对象,存放解码后的音视频数据;如果 streamType 是 3, 存放拆分数据 |
speed | 媒体流速度 |
decodeFormat | 媒体数据解码类型 IVYIO_DECODE_FMT ,如果获取的是音频,忽略此参数 |
channel | 通道0-31,一次只能获取一个通道 |
- 返回值
操作结果
- 备注
获取到的媒体数据所需的内存是在SDK内部维护,不需要调用者申请。但是如果调用了关闭视频,媒体数据的内存会被释放,所以如果调用关闭视频,一定要保证此 FrameData 指针不再使用,否则会引起崩溃。(对于调用者来说,最常见的情况就是调用关闭视频之前保证播放媒体数据的线程退出)
streamType 是 0 / 1,支持 IVY 和 Foscam 设备。
streamType 是 2 / 3,仅支持 IVY 设备
- 调用示例
参考 8.3
8.7 解码回放视频数据
- 描述
解码回放视频数据
int decodePlaybackVideo(int handle, FrameData srcFrame, FrameData dstFrame, int dstDecodeFormat, int channel)
- 参数
handle | SDK句柄 |
---|---|
srcFrame | 回放数据对象 |
dstFrame | 解码后的回放数据对象 |
dstDecodeFormat | 解码格式 |
channel | 通道0-31 |
- 返回值
操作结果
- 备注
使用之前必须调用 IVYIO_OpenPlayback,因为此接口内部还是和回放相关,不是一个独立的接口
- 调用示例
if (IVYIO_DEV_IPC == devType || IVYIO_DEV_NVR == devType)
{
// Get channel 2 video in a thread
while (bGetVideoRunning)
{
FrameData srcFrame = new FrameData;
// srcFrame from api IVYIO_GetPlaybackRawStreamData
......
FrameData dstFrame = new FrameData;
int rst = IvyIoSdkJni.getPlaybackRawStreamData(handle, srcFrame, dstFrame, DecodeFormat.RGB24, 2);
if (Result.OK == rst && dstFrame.len > 0)
{
// Decode and display dstFrame.data
}
else
{
sleep(5); // Sleep 10ms
}
}
......
}
9. 发送命令
9.1 发送命令(推荐使用)
- 描述
发送命令,可以对设备进行设置或者获取设备各种信息或者状态
int sendCommand(int handle, int cmd, String cmdData, Response respone, int timeout)
- 参数
handle | SDK句柄 |
---|---|
cmd | 命令ID |
cmdData | 命令数据,目前数据均为Json字符串 |
response | 响应数据对象,对象内数为Json字符串 |
timeout | 超时,单位ms |
- 返回值
操作结果
- 备注
cmd参数的范围应为 22019-42018,这个范围内的ID命令用途由开发者确定,SDK只是负责传输数据,具体命令的解析由上层应用和下层嵌入式决定;因此,cmdData和response的格式应由开发者定义。
如果应用不是Android需要注意iSizeOfResponse的值,因为数据传输已经加密,如果返回都是Json字符串,不要使用iSizeOfResponse,要自己strlen(response),这样可以获取到真正的字符串长度,iSizeOfResponse后边会包含若干个’\0’,Android应用没有此问题。如果返回是二进制数据,直接使用iSizeOfResponse就可以。
- 调用示例
// Get device information
Response resp = new Response();
int rst = IvyIoSdkJni.sendCommand(handle, 22025, "", resp, 1000 * 5);
if (IVYIO_RESULT_OK == rst)
{
// The 'ret' field in 'resp.resp' 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命令并且获取到结果, 其他设备不支持
int doCGI(int handle, String cgi, Response xmlResp, int timeout)
- 参数
handle | SDK句柄 |
---|---|
cgi | CGI字符串 |
xmlResp | CGI结果 |
timeout | 超时时间 |
- 返回值
操作结果
- 备注
此接口只支持FoscamIPC,其他设备均不支持。
- 调用示例
String strCGI = "cmd=getDevInfo";
Response resp = new Response();
int rst = IvyIoSdkJni.doCgi(handle, strCGI, resp, 1000 * 5);
// The string in resp is 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会发送一个事件通知应用,应用应该根据事件做响应的处理
int getEvent(int handle, Event event)
- 参数
handle | SDK句柄 |
---|---|
event | Event 对象 |
- 返回值
操作结果
- 备注
通常情况下,事件ID的范围是 42019-65535,这个范围内的事件由开发者定义,和发送命令IVYIO_SendCommand类似,对于事件SDK也只是负责数据传输,不解析任何数据,命令ID用途和结构都有上层应用和下层嵌入式决定。注意,有一些事件是由SDK内部发出的,不属于 42019-65535 这个范围内
此接口只能处理数据大小小于4K的事件。
- 调用示例
// Get event in a thread
Event event = new Event();
while (bRunning)
{
if (IvyIoSdkJni.getEvent(handle, event) == 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会发送一个事件通知应用,应用应该根据事件做响应的处理
int getEvent2(int handle, Event event)
- 参数
handle | SDK句柄 |
---|---|
event | Event 对象 |
- 返回值
操作结果
- 备注
通常情况下,事件ID的范围是 42019-65535,这个范围内的事件由开发者定义,和发送命令IVYIO_SendCommand类似,对于事件SDK也只是负责数据传输,不解析任何数据,命令ID用途和结构都有上层应用和下层嵌入式决定。注意,有一些事件是由SDK内部发出的,不属于 42019-65535 这个范围内
此接口可以处理16K大小的事件。
- 调用示例
// Get event in a thread
Event event = new Event();
while (bRunning)
{
if (IvyIoSdkJni.getEvent2(handle, event) == 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.2 将关键帧转成一张图片
- 描述
将一个关键帧转换成一张图片
int keyFrame2Picture(int handle, byte[] inData, byte[] outData, IvyIoInteger lenOfOutData, int channel)
- 参数
handle | SDK句柄 |
---|---|
inData | 输入数据buffer |
outData | 输出数据buffer |
iLenOfOutData | 输出数据大小 |
channel | 通道号 |
- 返回值
操作结果
- 备注
iLenOfOutData既是输入参数也是输出参数,作为输入参数表示outData buffer大小,作为输出表示实际输出buffer的大小;如果作为输入参数大小小于实际需要的buffer大小,函数会返回错误,但是作为输出iLenOfOutData会告知实际需要的buffer大小。
- 调用示例
FrameData frame = new FrameData();
// Get a video frame,
......
if (frame.key)
{
byte[] outBuffer = new byte[1024 * 1024 * 10];
IvyIoInteger pictureSize = new IvyIoInteger(0);
if (DevType.FOS_IPC == devType || DevType.IVY_IPC == devType || DevType.FOS_DOORBELL == devType)
{
int rst = IvyIoSdkJni.keyFrame2Picture(handle, frame.data, outBuffer, pictureSize, 0);
}
else if (DevType.FOS_NVR == devType || DevType.IVY_NVR == devType)
{
// Key frame on channel 5 to picture
rst = IvyIoSdkJni.keyFrame2Picture(handle, frame.data, outBuffer, pictureSize, 5);
}
// You can save it to local as a picture.
......
}
10.3 查询SDK接口的调用状态
- 描述
当设备是IVY低功耗设备的时候,如果接口create1的最后一个参数是1,SDK内部会启用一个接口调用计时器,在一定时间范围内如果调用者不调用SDK接口,SDK会触发“API在一定时间内未被调用”的状态,这个状态可以从该接口获取。如果有任意API(操作设备的API)被调用,计时器重新计时。
int apiCallTimeIsUp(int handle, IvyIoInteger state)
- 参数
handle | SDK句柄 |
---|---|
state | 状态 1:SDK API在一定时间内未被调用 0:SDK API调用正常 |
- 返回值
操作结果
- 备注
如果create1接口lowPower不为1,或者使用其他接口创建句柄,该接口不起作用。
- 调用示例
while(true) {
IvyIoInteger state = new IvyIoInteger(0);
int rst = IvyIoSdkJni.apiCallTimeIsUp(handle, state);
if (Result.OK == rst) {
if (1 == state) {
// time is up, do something.
}
}
}
10.4 清除SDK内部直播缓冲区
- 描述
Foscam设备暂时不支持。
可以清除SDK内部直播缓冲器,清除后,应用可以拿到最新的音视频数据。
int cleanLiveBufer(int handle, int channel)
- 参数
handle | SDK句柄 |
---|---|
channel | 通道号,按位表示,bit0-31表示channel0-31,可以多个通道一起清除 |
- 返回值
操作结果
- 备注
Foscam设备暂时不支持。
- 调用示例
...
// clean channel0-2
int channel = 7;
IvyIoSdkJni.cleanLiveBufer(handle, channel);
...
11. 门铃接听接口
接口适用范围
此章节接口适用于门铃接听场景。
门铃接听场景:当门铃被按下,应用接到门铃被按下的消息,在界面上显示以便用户选择是否接听,如果选择接听,应用显示视频和音频,并且可以发送对讲和进行录像。
11.1 创建门铃设备句柄并登录
- 描述
创建SDK实例句柄,虽然此接口适用于门铃,但也同样适用于其他设备(如果不是门铃我们推荐适用其他接口创建句柄)。如果当前设备类型为门铃,此接口会自动去登录设备,但是不会返回是否登录成功。
int createEx2(Url url, String uid, String mac, String user, String password, int mode, int doorbellMode, int fosDevType, int streamType)
- 参数
url | Url对象,存放目标设备的连接地址和端口;地址可以是DDNS或者IP |
---|---|
uid | 目标设备的UID |
mac | 目标设备的mac |
user | 目标设备的用户名 |
password | 目标设备的密码 |
mode | P2P连接模式 0:UDP方式 1:TCP方式 2:自动 |
doorbellMode | 门铃P2P连接模式 3:音频TCP视频UDP 4:音频视频都是TCP |
fosDevType | 设备类型 |
streamType | IPC码流类型,如果是门铃设备可以忽略 |
相同的参数可以参照 createEx1 / createEx 的描述。
- 返回值
SDK句柄,返回句柄时递增的,释放过后在创建也会递增
- 备注
mode只能使用值P2PMode.P2P_MODE_UDP/P2PMode.P2P_MODE_TCP/P2PMode.P2P_MODE_AUTO
doorbell只能使用 P2PMode.P2P_MODE_A_TCP_V_UDP / P2PMode.P2P_MODE_A_V_TCP
如果devType是门铃设备,门铃部分创建的时候就会去连接设备,IPC部分用法还和之前一致。
- 引用
public class Url {
public String url;
public int port;
}
public class P2PMode {
public static final int P2P_MODE_UDP = 0;
public static final int P2P_MODE_TCP = 1;
public static final int P2P_MODE_AUTO = 2;
public static final int P2P_MODE_A_TCP_V_UDP = 3;
public static final int P2P_MODE_A_V_TCP = 4;
}
- 调用示例
// Create doorbell
Url url = new Url();
url.url = "192.168.1.1";
url.port = 88;
int doorBellHandle = IvyIoSdkJni.createEx2(url, "ABCDABCDABCDABCDABCD2222", "", "admin", "", P2PMode.P2P_MODE_UDP, P2PMode.P2P_MODE_A_TCP_V_UDP, DevType.FOS_DOORBELL, VideoStreamType.MAIN_VIDEO_STREAM);
11.2 打开门铃视频
- 描述
打开门铃视频
int doorBellOpenVideo(int handle, int iTimeout)
- 参数
handle | SDK句柄 |
---|---|
timeout | 超时时间 |
- 返回值
操作结果
- 备注
如果要使用门铃接口,需要使用createEx2创建句柄,并且设备类型为
DevType.FOS_DOORBELL,创建函数会立即创建2个P2P去连接设备,一个P2P用于音频,一个P2P用于视频。无需调用登陆接口,直接可以打开视频,如果需要调用门铃以外的其他接口,这个句柄是有效的,无需重新创建句柄。如果创建句柄接口设备类型不是门铃,门铃接口函数无法使用。
- 调用示例
// Create doorbell
Url url = new Url();
url.url = "192.168.1.1";
url.port = 88;
int doorBellHandle = IvyIoSdkJni.createEx2(url, "ABCDABCDABCDABCDABCDZZZZ", "", "admin", "", P2PMode.P2P_MODE_UDP, P2PMode.P2P_MODE_A_TCP_V_UDP, DevType._FOS_DOORBELL, VideoStreamType.MAIN_VIDEO_STREAM);
// You can open video after create handle
int rst = IvyIoSdkJni.doorBellOpenVideo(doorBellHandle, 1000 * 5);
11.3 关闭门铃视频
- 描述
关闭门铃视频
int doorBellCloseVideo(int handle, int iTimeout)
- 参数
handle | SDK句柄 |
---|---|
iTimeout | 超时时间 |
- 返回值
操作结果
- 调用示例
int rst = IvyIoSdkJni.doorBellCloseVideo(doorBellHandle, 1000 * 5);
11.4 打开门铃音频
- 描述
打开门铃音频
int doorBellOpenAudio(int handle, int iTimeout)
- 参数
handle | SDK句柄 |
---|---|
iTimeout | 超时时间 |
- 返回值
操作结果
- 调用示例
int rst = IvyIoSdkJni.doorBellOpenVideo(doorBellHandle, 1000 * 5);
if (Result.OK == rst)
rst = IvyIoSdkJni.doorBellOpenAudio(doorBellHandle, 1000 * 5); // Or open audio in another thread
11.5 关闭门铃音频
- 描述
关闭门铃音频
int doorBellCloseAudio(int handle, int iTimeout)
- 参数
handle | SDK句柄 |
---|---|
iTimeout | 超时时间 |
- 返回值
操作结果
- 调用示例
IvyIoSdkJni.doorBellCloseAudio(doorBellHandle, 1000 * 5);
11.6 打开门铃对讲
- 描述
打开门铃对讲
int doorBellOpenTalk(int handle, int iTimeout)
- 参数
handle | SDK句柄 |
---|---|
iTimeout | 超时时间 |
- 返回值
操作结果
- 备注
需要先调用打开音频接口
- 调用示例
int rst = IvyIoSdkJni.doorBellOpenTalk(doorBellHandle, 1000 * 5);
11.7 关闭门铃对讲
- 描述
关闭门铃对讲
int doorBellCloseTalk(int handle, int iTimeout)
- 参数
handle | SDK句柄 |
---|---|
iTimeout | 超时时间 |
- 返回值
操作结果
- 调用示例
int rst = IvyIoSdkJni.doorBellCloseTalk(doorBellHandle, 1000 * 5);
11.8 发送对讲数据给门铃
- 描述
发送门铃对讲数据
int doorBellSendTalkData(int handle, byte[] data, int dataLen)
- 参数
handle | SDK句柄 |
---|---|
data | 对讲数据 |
dataLen | 对讲数据长度 |
- 返回值
操作结果
- 备注
数据采样率为8000,一般是960个字节大小.
- 调用示例
while (bGetData)
{
// Get talk data into talkData buffer.
IvyIoSdkJni.doorBellSendTalkData(doorBellHandle, talkData, 960);
}
11.9 获取门铃数据(已解码)
- 描述
获取门铃解码的音视频数据
int doorBellGetStreamData(int handle, int streamType, FrameData data, IvyIoInteger speed, int decodeFormat)
- 参数
handle | SDK句柄 |
---|---|
streamType | 码流类型 0:视频码流 1:音频码流 |
data | 指向存放媒体数据帧结构 IVYIO_FRAME 指针的指针 |
speed | 数据流量 |
decodeFormat | 媒体数据解码对象DecodeFormat,如果获取的是音频,忽略此参数 |
- 返回值
操作结果
- 备注
注意事项和getStreamData一样,可以参考其API说明
- 调用示例
if (DevType.FOS_DOORBELL == devType)
{
// Get video in a thread
FrameData frame = new FrameData();
IvyIoInteger speed = new IvyIoInteger(0);
while (bGetVideoRunning)
{
int rst = IvyIoSdkJni.doorBellGetStreamData(handle, StreamType.STREAM_VIDEO, frame, speed, DecodeFormat.RGBA32);
if (Result.OK == rst && frame.dataLen > 0)
{
// Display frame->data
}
else
{
SystemClock.sleep(10); // Sleep 10ms
}
}
// Get audio in another thread
FrameData frame = new FrameData();
IvyIoInteger speed = new IvyIoInteger(0);
while (bGetAudioRunning)
{
int rst = IvyIoSdkJni.doorBellGetStreamData(handle, StreamType.STREAM_AUDIO, frame, speed, DecodeFormat.PCM);
if (Result.OK == rst && frame。dataLen > 0)
{
// Display frame->data
}
else
{
SystemClock.sleep(10); // Sleep 10ms
}
}
}
11.10 获取门铃数据(未解码)
- 描述
获取门铃原始的音视频数据
int doorBellGetRawStreamData(int handle, int streamType, FrameData data, IvyIoInteger speed)
- 参数
handle | SDK句柄 |
---|---|
streamType | 码流类型 0:视频码流 1:音频码流 |
data | 指向存放媒体数据帧结构 IVYIO_FRAME 指针的指针 |
speed | 数据流量 |
- 返回值
操作结果
- 备注
注意事项和getRawStreamData一样
- 调用示例
if (DevType.FOS_DOORBELL == devType)
{
// Get video in a thread
FrameData frame = new FrameData();
IvyIoInteger speed = new IvyIoInteger();
while (bGetVideoRunning)
{
int rst = IvyIoSdkJni.doorBellGetRawStreamData(handle, StreamType.STREAM_VIDEO, frame, speed);
if (Result.OK == rst && frame.dataLen > 0)
{
// Display frame->data
}
else
{
SystemClock.sleep(10); // Sleep 10ms
}
}
// Get audio in another thread
FrameData frame = new FrameData();
IvyIoInteger speed = new IvyIoInteger();
while (bGetAudioRunning)
{
IVYIO_FRAME *frame = NULL;
int outLen = 0;
int speed = 0;
int rst = IvyIoSdkJni.doorBellGetRawStreamData(handle, StreamType.STREAM_AUDIO, frame, speed);
if (Result.OK == rst && frame.dataLen > 0)
{
// Display frame->data
}
else
{
SystemClock.sleep(10); // Sleep 10ms
}
}
}
11.11 门铃本地录像开始
- 描述
门铃本地录像开始
int doorBellStartRecord(int handle, int recordType, String fileName);
- 参数
handle | SDK句柄 |
---|---|
recordType | 录像类型 1:MP4 |
fileName | 保存文件完整的路径名称 |
- 返回值
操作结果
- 调用示例
if (DevType.FOS_DOORBELL == devType)
{
IvyIoSdkJni.doorBellStartRecord(doorBellHandle, RecordType.MP4, "/mydir/ecord.mp4");
}
11.12 门铃本地录像结束
- 描述
门铃本地录像结束
int doorBellStopRecord(int handle)
- 参数
handle | SDK句柄 |
---|
- 返回值
操作结果
- 调用示例
if (DevType.FOS_DOORBELL == devType)
{
IvyIoSdkJni.doorBellStopRecord(doorBellHandle);
}
11.13 检测门铃句柄状态
- 描述
检测门铃句柄状态,如果门铃涉及到套接字或者通道任何一个发生改变,都有会事件生成。
int doorBellCheckHandle(int handle)
- 参数
handle | SDK句柄 |
---|
返回值
门铃句柄状态调用示例
if (DevType.FOS_DOORBELL == devType)
{
while (bChecking)
{
int state = IvyIoSdkJni.doorBellCheckHandle(doorBellHandle);
// handle state
.....
}
}
11.14 获取门铃事件
- 描述
获取门铃事件
int doorBellGetEvent(int handle, Event event)
- 参数
handle | SDK句柄 |
---|---|
event | 事件 |
- 返回值
操作结果
- 调用示例
if (DevType.FOS_DOORBELL == devType)
{
Event event = new Event();
while (bChecking)
{
if (Result.OK == IvyIoSdkJni.doorBellGetEvent(doorBellHandle))
{
switch (event.id)
{
case 88:
// Handle function
break;
case ......
break;
......
default:
break;
}
}
}
}
11.16 门铃接听状态查询
- 描述
获取门铃接听状态,是否已经别另外一个设备接听
int doorBellQueryAnswerState(int handle, IvyIoInteger state, int iTimeout)
- 参数
handle | SDK句柄 |
---|---|
state | 状态,2:没有被接听 0:已经被接听 |
iTimeout | 超时时间 |
- 返回值
操作结果
- 备注
只支持门铃设备,必须要调用IVYIO_DoorBell_OpenVideo成功之后再调用此接口,否则无法正确查到状态。
因为只有当IVYIO_DoorBell_OpenVideo成功后,设备才会鉴权,才会有密码,这样SDK才能正确取到数据,后续设备可能会更新固件解决必须在IVYIO_DoorBell_OpenVideo后调用的问题。
- 调用示例
if (DevType.FOS_DOORBELL == devType)
{
IvyIoInteger state = new IvyIoInteger();
while(bChecking)
{
if (Result.OK == IvyIoSdkJni.doorBellQueryAnswerState(doorBellHandle, state, 1000 * 5))
{
if (0 == state)
......
else if (1 == state)
......
else
......
}
}
}
12 获取图片接口(仅支持IVY设备)
12.1 获取图片列表
- 描述
获取图片列表
该接口支持多种不同的参数,根据能力集区分不同的参数,如果val6 bit4为1,使用SearchPictureType1和PictureListType1,如果为0,使用SearchPictureType0和PictureListType0
int getPictureList(int handle, SearchPicture searchInfo, PictureList list, int timeout, int channel)
- 参数
handle | SDK句柄 |
---|---|
searchInfo | SearchPictureType0 或者 SearchPictureType1 对象 |
list | PictureListType0 或者 PictureListType1 对象 |
timeout | 超时时间 |
channel | 通道号,同打开视频 |
- 返回值
操作结果
- 引用
// Picture download
public class SearchPictureType0 extends SearchPicture {
public SearchPictureType0() {
argsType = 0;
}
public long sTime;
public long eTime;
public int type;
public int startNo;
public int count;
}
public class PictureListType0 extends PictureList {
public PictureListType0() {
argsType = 0;
}
public int channel;
public int totalCount;
public int curCount;
public PictureInfo list[];
}
public class PictureInfo {
public int format; // Picture format
public long time; // Timestamp
public int type; // Picture type, manual / alarm...
}
public class SearchPictureType1 extends SearchPicture {
public SearchPictureType1() {
argsType = 1;
}
public long sTime;
public long eTime;
public int type;
public int startNo;
public int count;
}
public class PictureListType1 extends PictureList {
public PictureListType1() {
argsType = 1;
}
public int channel;
public int totalCount;
public int curCount;
public PictureInfo list[];
public PictureInfoEx listEx[];
}
public class PictureInfoEx {
public int direction;
public int weight;
}
- 备注
iChanel目前请传0或者1。
- 调用示例 1
if (DevType.IVY_IPC == devType)
{
SearchPictureType0 ips = new SearchPictureType0();
ips.sTime = 1620316800; // 2021-05-07 00:00:00 (beijing)
ips.eTime = 1620403199; // 2021-05-07 23:59:59 (beijing)
ips.count = 20;
ips.startNo = startNo;
search.type = 0;
PictureListType0 ipl = new PictureListType0();
rst = IvyIoSdkJni.getPictureList(m_handle, ips, ipl, 1000 * 10, 0);
if (rst != IVYIO_RESULT_OK)
{
return;
}
}
- 调用示例 2
if (DevType.IVY_IPC == devType)
{
SearchPictureType1 ips = new SearchPictureType1();
ips.sTime = 1620316800; // 2021-05-07 00:00:00 (beijing)
ips.eTime = 1620403199; // 2021-05-07 23:59:59 (beijing)
ips.count = 20;
ips.startNo = startNo;
search.type = 0;
PictureListType1 ipl = new PictureListType1();
rst = IvyIoSdkJni.getPictureList(m_handle, ips, ipl, 1000 * 10, 0);
if (rst != IVYIO_RESULT_OK)
{
return;
}
}
12.2 获取图片数据
- 描述
获取图片数据。如果设备能力集val6 bit4为1,information使用GetMultiPictureType1, 如果为0,使用GetMultiPictureType0
int getPicture(int handle, GetMultiPicture information, PictureFileArray files, IvyIoInteger count, int timeout, int channel)
- 参数
handle | SDK句柄 |
---|---|
information | GetMultiPictureType0 或者 GetMultiPictureType1 对象 |
files | PictureFileArrayType0 对象 |
count | 实际下载的图片数量 |
timeout | 超时时间 |
channel | 通道号,0-31,每次只能获取一个通道的图片,目前只支持0通道 |
- 返回值
操作结果
- 引用
public class GetMultiPictureType0 extends GetMultiPicture {
public GetMultiPictureType0() {
argsType = 0;
}
public int countOfUsed;
public PictureInfo pictureInfo[];
}
public class GetMultiPictureType1 extends GetMultiPicture {
public GetMultiPictureType1() {
argsType = 1;
}
public int countOfUsed;
public PictureInfo pictureInfo[];
public PictureInfoEx pictureInfoEx[];
}
public class PictureInfo {
public int format; // Picture format
public long time; // Timestamp
public int type; // Picture type, manual / alarm...
}
public class PictureFileArrayType0 extends PictureFileArray {
public PictureFileArrayType0 () {
argsType = 0;
}
public PictureFile[] files;
}
- 备注
iChanel目前请传0;files是一个指针数组,为每个元素申请一块内存,然后用 IVYIO_PICTURE_FILE 结构指针分别访问每个内存即可。
- 调用示例 1
if (DevType.DEV_IPC == devType)
{
PictureListType0 ipl = new PictureListType0();
// Get picture list
......
GetMultiPictureType0 pictureInfo = new GetMultiPictureType0();
pictureInfo.pictureInfo = new PictureInfo[2];
pictureInfo.pictureInfo[0] = new PictureInfo();
pictureInfo.pictureInfo[1] = new PictureInfo();
pictureInfo.countOfUsed = 2;
pictureInfo.pictureInfo[0].time = list.list[0].time;
pictureInfo.pictureInfo[0].type = list.list[0].type;
pictureInfo.pictureInfo[0].format = list.list[0].format;
pictureInfo.pictureInfo[1].time = list.list[1].time;
pictureInfo.pictureInfo[1].type = list.list[1].type;
pictureInfo.pictureInfo[1].format = list.list[1].format;
IvyIoInteger pictureCount = new IvyIoInteger(0);
PictureFileArrayType0 pictureArray = new PictureFileArrayType0();
rst = IvyIoSdkJni.getPicture(m_handle, pictureInfo, pictureArray, pictureCount, 1000 * 5, 0);
if (Result.OK == rst)
{
// Handle pictureArray
}
}
- 调用示例 2
if (DevType.DEV_IPC == devType)
{
PictureListType1 pictureInfo = new PictureListType1();
// Get picture list
......
pictureInfo.pictureInfo = new PictureInfo[2];
pictureInfo.pictureInfoEx = new PictureInfoEx[2];
pictureInfo.pictureInfo[0] = new PictureInfo();
pictureInfo.pictureInfo[1] = new PictureInfo();
pictureInfo.pictureInfoEx[0] = new PictureInfoEx();
pictureInfo.pictureInfoEx[1] = new PictureInfoEx();
pictureInfo.countOfUsed = 2;
pictureInfo.pictureInfo[0].time = list.list[0].time;
pictureInfo.pictureInfo[0].type = list.list[0].type;
pictureInfo.pictureInfo[0].format = list.list[0].format;
pictureInfo.pictureInfo[1].time = list.list[1].time;
pictureInfo.pictureInfo[1].type = list.list[1].type;
pictureInfo.pictureInfo[1].format = list.list[1].format;
pictureInfo.pictureInfoEx[0].direction = list.listEx[0].direction;
pictureInfo.pictureInfoEx[1].weight = list.listEx[1].weight;
pictureInfo.pictureInfoEx[0].direction = list.listEx[0].direction;
pictureInfo.pictureInfoEx[1].weight = list.listEx[1].weight;
IvyIoInteger pictureCount = new IvyIoInteger(0);
PictureFileArrayType0 pictureArray = new PictureFileArrayType0();
rst = IvyIoSdkJni.getPicture(m_handle, pictureInfo, pictureArray, pictureCount, 1000 * 5, 0);
if (Result.OK == rst)
{
// Handle pictureArray
}
}
13. RTSP API (非线程安全)
13.1 打开RTSP
- 描述
打开RTSP
int rtspOpen(String url);
- 参数
url | rtsp地址 |
---|
- 返回值
0:成功 其他值:失败
- 备注
海康的RTSP地址为 rtsp://admin:123456@192.168.1.68:554/Streaming/Channels
- 调用示例
IvyIoSdkJni.rtspOpen("rtsp://admin:123456@192.168.1.68:554/Streaming/Channels");
13.2 关闭RTSP
- 描述
关闭RTSP
int rtspClose();
- 返回值
0:成功 其他值:失败
- 调用示例
IvyIoSdkJni.rtspClose();
13.3 获取RTSP流(原始视频+pcm音频)
- 描述
获取RTSP流,包含视频和音频,视频为原始视频,音频为解码后的PCM数据
int rtspGetRawFrameAndPCM(byte[] frame, IvyIoInteger frameSize, RtspVideoInfo videoInfo, RtspAudioInfo audioInfo, IvyIoInteger audioOrVideo)
- 参数
frame | 流数据字节数组 |
---|---|
frameSize | 流数据大小 |
videoInfo | 视频流信息 参考 RtspVideoInfo |
audioInfo | 音频流信息 参考 RtspAudioInfo |
audioOrVideo | 音频或者视频 参考 RtspFrameType |
- 返回值
0:成功 其他值:失败
- 引用
public class RtspVideoInfo {
public int w;
public int h;
public int key;
public int codecId; // see IVYIO_RTSP_CODEC_ID
}
public class RtspAudioInfo {
public int codecId;
public int sampleRate;
public int sampleFmt; // see IVYIO_RTSP_SAMPLE_FMT
public int channels;
public int channelLayout;
}
public class RtspCodecId {
public static final int UNKNOWN = -1;
public static final int H264 = 0;
public static final int HEVC = 1;
public static final int AAC = 2;
public static final int PCM = 3;
public static final int PCM_MULOW = 4;
public static final int PCM_ALOW = 5;
}
public class RtspFrameType {
public static final int VIDEO = 0;
public static final int AUDIO = 1;
}
public class RtspSampleFmt {
public static final int UNKNOWN = -1;
public static final int S16 = 1;
}
- 调用示例
byte[] frame = new byte[1024 * 1024];
IvyIoInteger frameSize = new IvyIoInteger(-1);
IvyIoInteger audioOrVideo = new IvyIoInteger(-1);
RtspVideoInfo videoInfo = new RtspVideoInfo;
RtspAudioInfo audioInfo = new RtspAudioInfo;
if (0 == IvyIoSdkJni.rtspGetRawFrameAndPCM(frame, frameSize, videoInfo, audioInfo, audioOrVideo))
{
// get data ok!
}
13.4 获取RTSP流(解码视频+pcm音频)
- 描述
获取RTSP流,包含视频和音频,视频为解码后的视频,音频为解码后的PCM数据
int rtspGetFrame(byte[] frame, IvyIoInteger frameSize, RtspVideoInfo videoInfo, RtspAudioInfo audioInfo, IvyIoInteger audioOrVideo, int videoDecodeFmt);
- 参数
frame | 流数据字节数组 |
---|---|
frameSize | 流数据大小 |
videoInfo | 视频流信息 参考 RtspVideoInfo |
audioInfo | 音频流信息 参考 RtspAudioInfo |
audioOrVideo | 音频或者视频 参考 RtspFrameType |
videoDecodeFmt | 解码格式 参考 DecodeFormat |
- 返回值
0:成功 其他值:失败
- 引用
public class RtspVideoInfo {
public int w;
public int h;
public int key;
public int codecId; // see IVYIO_RTSP_CODEC_ID
}
public class RtspAudioInfo {
public int codecId;
public int sampleRate;
public int sampleFmt; // see IVYIO_RTSP_SAMPLE_FMT
public int channels;
public int channelLayout;
}
public class RtspCodecId {
public static final int UNKNOWN = -1;
public static final int H264 = 0;
public static final int HEVC = 1;
public static final int AAC = 2;
public static final int PCM = 3;
public static final int PCM_MULOW = 4;
public static final int PCM_ALOW = 5;
}
public class RtspFrameType {
public static final int VIDEO = 0;
public static final int AUDIO = 1;
}
public class RtspSampleFmt {
public static final int UNKNOWN = -1;
public static final int S16 = 1;
}
public class DecodeFormat {
public static final int VIDEORAW = 0;
public static final int ARGB32 = 1; //packed ARGB 8:8:8:8, 32bpp, ARGBARGB...
public static final int RGBA32 = 2; //packed RGBA 8:8:8:8, 32bpp, RGBARGBA...
public static final int ABGR32 = 3; //packed ABGR 8:8:8:8, 32bpp, ABGRABGR...
public static final int BGRA32 = 4; //packed BGRA 8:8:8:8, 32bpp, BGRABGRA...
public static final int RGB24 = 5; //packed RGB 8:8:8, 24bpp, RGBRGB...
public static final int BGR24 = 6; //packed RGB 8:8:8, 24bpp, BGRBGR...
public static final int RGB565BE = 7; //packed RGB 5:6:5, 16bpp, (msb) 5R 6G 5B(lsb), big-endian
public static final int RGB565LE = 8; //packed RGB 5:6:5, 16bpp, (msb) 5R 6G 5B(lsb), little-endian
public static final int BGR565BE = 9; //packed BGR 5:6:5, 16bpp, (msb) 5B 6G 5R(lsb), big-endian
public static final int BGR565LE = 10; //packed BGR 5:6:5, 16bpp, (msb) 5B 6G 5R(lsb), little-endian
public static final int YUV420 = 11;
public static final int YUYV422 = 12;
public static final int UYVY422 = 13;
public static final int H264 = 14;
public static final int MJPEG = 15;
public static final int MJPEG_BASE64 = 16;
public static final int H264_BASE64 = 17;
public static final int AUDIORAW = 18;
public static final int G726 = 19;
public static final int G711U = 20;
public static final int PCM = 21;
public static final int ADPCM = 22;
public static final int G711A = 23;
public static final int AAC = 24;
public static final int HEVC = 25;
}
- 调用示例
byte[] frame = new byte[1024 * 1024];
IvyIoInteger frameSize = new IvyIoInteger(-1);
IvyIoInteger audioOrVideo = new IvyIoInteger(-1);
RtspVideoInfo videoInfo = new RtspVideoInfo;
RtspAudioInfo audioInfo = new RtspAudioInfo;
if (0 == IvyIoSdkJni.rtspGetFrame(frame, frameSize, videoInfo, audioInfo, audioOrVideo,DecodeFormat.UYVY422))
{
// get data ok!
}
14. 双向视频
14.1 打开双向视频
- 描述
打开双向视频,告诉设备将要发音频视频数据给它
int openSendLive(int handle, int op, int timeout)
- 参数
handle | SDK句柄 |
---|---|
op | 将要发送的媒体类型。按位表示 bit0:video bit1:audio |
timeout | 超时,单位ms |
- 返回值
参考 Result
- 备注
- 调用示例
// Create SDK handle for IVY two-way-video IPC with main stream video
Url myUrl = new Url();
myUrl.url = "192.168.1.102";
myUrl.port = 8888;
int handle = IvyIoSdkJni.createEx1(url, "ABCDABCDABCDABCDABCD2222", "", username", "password", P2PMode.P2P_MODE_UDP, DevType.IVY_TWO_WAY_VIDEO_CAMERA, VideoStreamType.mainVideoStream);
int rst = IvyIoSdkJni.openSendLive(handle, SendLiveOp.video | SendLiveOp.audio, 1000 * 20);
14.2 关闭双向视频
- 描述
关闭双向视频,告诉设备将要关闭发音频视频数据
int closeSendLive(int handle, int op, int timeout);
- 参数
handle | SDK句柄 |
---|---|
op | 将要发送的媒体类型。按位表示 bit0:video bit1:audio |
timeout | 超时,单位ms |
- 返回值
参考 Result
- 调用示例
// ......
int rst = IvyIoSdkJni.closeSendLive(handle, SendLiveOp.video | SendLiveOp.audio, 1000 * 20);
// ......
14.3 发送视频
- 描述
发送视频,将视频放到SDK缓冲区内,SDK会自动发送
int sendVideo(int handle, FrameData frame);
- 参数
handle | SDK句柄 |
---|---|
frame | FRAME_DATA |
- 返回值
参考 Result
- 备注
如果缓冲区放不下视频数据,SDK会丢弃视频。缓冲区大小为 3M
- 调用示例
FrameData videoFrame = new FrameData();
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;
// mallco memory for videoFrame.data
// copy data to videoFrame.data
// videoFrame.data = new byte[];
rst = IvyIoSdkJni.sendVideo(handle, videoFrame);
14.4 发送音频
- 描述
发送音频,将音频放到SDK缓冲区内,SDK会自动发送
int sendAudio(int handle, FrameData frame);
- 参数
handle | SDK句柄 |
---|---|
frame | FRAME_DATA |
- 返回值
参考 Result
- 备注
如果缓冲区放不下音频数据,SDK会丢弃音频。缓冲区大小为 128KB
- 调用示例
// audiodata is one package
FrameData audioFrame = new FrameData();
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;
// mallco memory for videoFrame.data
// copy data to videoFrame.data
// audioFrame.data = new byte[];
rst = IvyIoSdkJni.sendVideo(handle, audioFrame);
14.5 拒绝视频
- 描述
拒绝IPC发来的视频请求
int rejectVideoCall(int handle, int timeout);
- 参数
handle | SDK句柄 |
---|---|
timeout | 超时,单位ms |
- 返回值
参考 Result
- 调用示例
// ......
int rst = IvyIoSdkJni.rejectVideoCall(handle, 1000 * 20);
// ......
14.6 获取摄像机双向视频状态
- 描述
获取摄像机双向视频状态
int getVideoCallState(int handle, IvyIoInteger state, int timeout);
- 参数
handle | SDK句柄 |
---|---|
state | 通话状态:0-空闲,1-呼叫中,2-通话中 |
timeout | 超时,单位ms |
- 返回值
参考 Result
- 调用示例
// ......
IvyInteger state = new IvyInteger(-1);
int rst = IvyIoSdkJni.getVideoCallState(handle, state, 1000 * 20);
// ......