有奖捉虫:办公协同&微信生态&物联网文档专题 HOT
本模块用于设备端音视频数据存储在云端,需要观看时,由观看端从云端拉取数据。

功能介绍

本模块主要包含云存储模块初始化,开通,数据存储等功能,设备端需要此功能时调用此模块。

流程指引

云存储主流程

注册开始推流、停止推流回调 > 云存储模块初始化 > 云存储模块去初始化。

推流流程

收到推流通知回调 > 推送音视频流 > 收到停止推流通知停止推流。

接口参考

该功能模块提供以下接口:
iv_cs_init:云存储模块初始化。
iv_cs_exit:云存储模块去初始化。
iv_cs_push_stream_start_cb:开始推流通知回调。
iv_cs_push_stream_stop_cb:停止推流通知回调。
iv_cs_ai_service_notify_cb:AI 服务通知回调。
iv_cs_push_stream:推送音视频流。
iv_cs_event_happen_notify:事件发生通知。
iv_cs_event_capture_picture_cb: 事件抓图回调。
iv_cs_event_upload_picture_result_cb:事件抓图上传结果回调。

iv_cs_init

接口描述 云存储模块初始化,注册相关回调,申请资源,需要模块时初始化调用。
int iv_cs_exit(unsigned int force_exit);
参数说明
参数名称
类型
描述
输入/输出
force_exit
unsigned int
是否强制退出
输入
返回值
返回值
描述
IV_ERR_NONE
成功。
IV_ERR_*
失败,对应相应错误码。

iv_cs_exit

接口描述 云存储模块去初始化,释放资源。
int iv_cs_exit(void);
参数说明
返回值
返回值
描述
IV_ERR_NONE
成功。
IV_ERR_*
失败,对应相应错误码。

iv_cs_push_stream_start_cb

接口描述 开始推流回调,收到此回调后启动相应音视频并开始推流。
int iv_cs_push_stream_start_cb(void);
参数说明
返回值
返回值
描述
IV_ERR_NONE
成功。
IV_ERR_*
失败,对应相应错误码。

iv_cs_push_stream_stop_cb

接口描述 停止推流回调,收到此回调后停止推流。
int iv_cs_push_stream_stop_cb(void);
参数说明
返回值
返回值
描述
IV_ERR_NONE
成功。
IV_ERR_*
失败,对应相应错误码。

iv_cs_push_stream

接口描述 推送音视频流,音频为 AAC 格式,视频为 H.264 或 H.265 格式。
int iv_cs_push_stream(iv_cs_stream_type_e eCsStreamType, iv_cm_venc_type_e eCmVencType, void *pstCsStream);
参数说明
参数名称
类型
描述
输入/输出
eCsStreamType
iv_cs_stream_type_e
云存储推流类型(音频/视频)。
输入
eCmVencType
iv_cm_venc_type_e
云存储视频编码类型(H.264/H.265)。
输入
pstCsStream
void *
云存储推流的数据。
输入
返回值
返回值
描述
IV_ERR_NONE
成功。
IV_ERR_*
失败,对应相应错误码。

iv_cs_event_happen_notify

接口描述 事件触发通知,对于事件类云存储套餐需要事件触发后推流、产生事件消息、触发抓图上报。
说明:
该接口调用无频次限制、支持重入。
该接口在同一事件时间内对于相同的触发源只会产生一次事件消息,相同的触发源只会使事件录像继续下去。
该接口不能一次设置多个事件触发,每次必须调用并保证有且只有一个事件触发源。
该接口调用不是每次调用后都会产生抓图回调。只有下列情况才会产生抓图回调。
更高优先级的事件触发时(有优先级设置)。
不同类型的事件触发(无优先级设置)。
如果没有开通事件云存调用该接口无任何影响,返回错误码为 IV_ERR_CS_EVENT_SERVICE_NOT_RUN
int iv_cs_event_happen_notify(uint32_t iv_cs_event_trigger_type,uint64_t iv_cs_event_time_ms);
参数说明
参数名称
类型
描述
输入/输出
iv_cs_event_trigger_type
uin32_t
事件类型:(总共32位,按每位填写)。
@iv_cs_event_trigger_type_e
输入
iv_cs_event_time_ms
int64_t
本次事件源触发的时间点 (utc0 ms)
输入
返回值
返回值
描述
IV_ERR_NONE
成功。
IV_ERR_*
失败,对应相应错误码。

iv_cs_event_capture_picture_cb

接口描述 触发事件抓图的回调:
1. 该回调会在 SDK 判断需要抓图时调用,该接口应当返回图片的文件名(包含路径) pic_name。
2. 回调函数建议非阻塞使用,只需要返回图片完整名即可,SDK 会检测文件大小超过2K后才会进行上传,等待抓图超时时间5秒。
3. 如果回调函数内部阻塞或者抓图过慢会导致事件的处理堆积,影响事件上报实时性。
4. 如果不需要抓图上传则将该接口传出参数 pic_name 用0填充或者初始化时不设置回调即可。
void (*iv_cs_event_capture_picture_cb)(uint8_t pic_name[IV_SYS_FILE_PATH_MAX_LEN],uint32_t pic_name_max_len);
参数说明
参数名称
类型
描述
输入/输出
pic_name
uint8_t*
抓图文件名(完整路径)
输出
pic_name_max_len
uint32_t
抓图文件名路径最大长度
输入
返回值

iv_cs_event_upload_picture_result_cb

接口描述 事件图片上传结果回调:
1. 该回调会在 SDK 上传图片结束后回调,可根据该接口进行图片资源的回收处理。
2. 该回调会携带图片的全名和图片此时的处理状态,上层可根据图片名和状态进行处理。
3. 每张抓图都会回调一次,在对应图片回调前不应删除对应的图片资源,防止 SDK 使用图片资源失败。
void (*iv_cs_event_upload_picture_result_cb)(uint8_t pic_name[IV_SYS_FILE_PATH_MAX_LEN],iv_cs_event_pic_upload_res_e result_code);
参数说明
参数名称
类型
描述
输入/输出
pic_name
uint8_t*
抓图文件名(完整路径)
输入
result_code
iv_cs_event_pic_upload_res_e
使用结果枚举
输入
返回值

数据结构

该模块提供以下数据结构:
iv_cs_init_parm_s:云存储模块初始化参数结构体。
iv_cs_data_type_e:云存储数据类型枚举。
iv_cs_event_trigger_type_e:事件触发源类型枚举。
iv_cs_running_status:云存储各业务的运行状态。
iv_cs_event_pic_upload_res_e: 云存储告警图片使用结果枚举。
iv_cs_service_chn_e: 云存储服务通道枚举。
音视频结构参考公共模块音视频结构

iv_cs_init_parm_s

接口描述 云存储模块初始化参数结构体。
typedef struct iv_cs_init_parm_s
{
uint32_t u32MaxSizeInAGop;
int32_t event_trigger_priority[IV_CS_EVENT_MAX_TRIGGER];
int32_t event_list_max_depth;
int32_t event_record_min_time_s;

int32_t (* iv_cs_push_stream_start_cb)(void);
int32_t (* iv_cs_push_stream_stop_cb)(void);

void (*iv_cs_ai_service_notify_cb)(uint32_t ai_server_type, uint64_t utc_expire);

void (*iv_cs_event_capture_picture_cb)(uint8_t pic_name[IV_SYS_FILE_PATH_MAX_LEN],uint32_t pic_name_max_len);
void (*iv_cs_event_upload_picture_result_cb)(uint8_t pic_name[IV_SYS_FILE_PATH_MAX_LEN],iv_cs_event_pic_upload_res_e result_code);
}iv_cs_init_parm_s;
参数说明
成员名称
描述
取值
u32MaxSizeInAGop
4秒音视频流的大小(云存储文件依4秒一个时间单位打包)。
1. 云存储模块会最多容许缓存三个视频文件。
2. 当缓存文件总量大小 > u32MaxSizeInAGop * 3 时则会丢弃最早的一个文件,用于后续音视频的写入。
3. 该值影响写入云存储录像文件的队列 buff 大小。用于同步音视频的 pts,buff 越大可以容许的 pts 误差越大。视频 buff 大小 = u32MaxSizeInAGop / 2;音频 buff 大小= u32MaxSizeInAGop / 10
字节数量,估算值
event_trigger_priority
事件触发源优先级数组。
1. 每个下标代表事件触发源的 1bit,里面存储的值代表对应触发源的优先级。
2. 数值越低触发源优先级越高。
3. 数值设置为IV_CS_EVENT_TRIGGER_HIGHEST_INVALID_PRIORITY(-1) 表示不受优先级限制而是根据时间顺序进行抓图。
-1、[0-31]
event_list_max_depth
事件处理链表最大深度(最大的等待处理事件数量),主要是为了防止发生异常时资源的无限申请。
设置为0表示无限制。
无限制
event_interval_time_s
事件间隔时间(s): 1. 该值定义了两个事件的分割时间; 2. 当首次事件触发时开始计时,当计时超过该值时则会关闭本次事件。下一次触发则定义为下一个事件并开启新一轮的计时。
>= 4秒
event_record_min_time_s
事件录像的最短录像时长(s): 1. 该值定义了事件触发一次最短的录像时长; 2. 如果持续触发则不断向后录像,直到最后一次触发后再录制该值大小的时长后才结束录像。
>=4s, <= event_interval_time_s
iv_cs_event_capture_picture
触发事件抓图的回调
-
iv_cs_event_upload_picture_result
事件图片上传结果回调
-
iv_cs_push_stream_start_cb
开始云存储推流
-
iv_cs_push_stream_stop_cb
停止云存储推流
-

iv_cs_data_type_e

接口描述 云存储数据类型枚举。
typedef enum
{
IV_CS_STREAM_TYPE_AUDIO = 0, /*audio*/
IV_CS_STREAM_TYPE_VIDEO = 1, /*video*/

IV_CS_STREAM_TYPE_BUTT
}iv_cs_stream_type_e;
参数说明
成员名称
描述
取值
IV_CS_STREAM_TYPE_AUDIO
音频
-
IV_CS_STREAM_TYPE_VIDEO
视频
-

iv_cs_event_trigger_type_e

接口描述 事件触发源类型枚举。
typedef enum iv_cs_event_trigger_type_e{
IV_CS_EVENT_TRIGGER_MD = 0,
IV_CS_EVENT_TRIGGER_PD = 1,
IV_CS_EVENT_TRIGGER_SD = 2,
IV_CS_EVENT_TRIGGER_LD = 3,
/*
...
IV_CS_EVENT_TRIGGER_SDK_RESERVE
...
*/
/*
...
IV_CS_EVENT_TRIGGER_CUSTOM
...
*/
IV_CS_EVENT_MAX_TRIGGER = 32,
}iv_cs_event_trigger_type_e;
参数说明
成员名称
描述
取值
IV_CS_EVENT_TRIGGER_MD
bit[0] 移动侦测
0/1
IV_CS_EVENT_TRIGGER_PD
bit [1] 检测到人形
0/1
IV_CS_EVENT_TRIGGER_SD
bit [2] 异常声音
0/1
IV_CS_EVENT_TRIGGER_LD
bit [3] 联动(物模型触发)
0/1
SDK 预留
bit [4:15] reserve
0/1
客户自定义
bit [16:31] 客户自声明扩展
0/1

iv_cs_event_pic_upload_res_e

接口描述 云存储事件告警抓图使用结果枚举。
typedef enum iv_cs_event_pic_upload_res_e{
IV_CS_EVENT_PICTURE_UPLOAD_OK = 0,
IV_CS_EVENT_PICTURE_UPLOAD_TIME_OUT = 1,
IV_CS_EVENT_PICTURE_EXPIRED = 2,
IV_CS_EVENT_PICTURE_NOT_EXIST = 3,
}iv_cs_event_pic_upload_res_e;
参数说明
成员名称
描述
取值
IV_CS_EVENT_PICTURE_UPLOAD_OK
上传成功
-
IV_CS_EVENT_PICTURE_UPLOAD_TIME_OUT
上传超时
-
IV_CS_EVENT_PICTURE_EXPIRED
图片过期(有新的图片需要上传,该图片已不再使用)
-
IV_CS_EVENT_PICTURE_NOT_EXIS
图片文件不存在
-

iv_cs_service_chn_e

接口描述
云存储服务通道枚举。
typedef enum iv_cs_service_chn_e{
IV_CS_CHANNEL_FULL_TIME = 0,
IV_CS_CHANNEL_EVENT_VIDEO = 1,
IV_CS_CHANNEL_EVENT_PIC = 2,
IV_CS_CHANNEL_MAX,
IV_CS_CHANNEL_ERR = 0XFF,
}iv_cs_service_chn_e;
参数说明
成员名称
描述
取值
IV_CS_CHANNEL_FULL_TIME
全时录像云存储服务通道
-
IV_CS_CHANNEL_EVENT_VIDEO
事件录像云存储服务通道
-
IV_CS_CHANNEL_EVENT_PIC
事件图片(消息)云存储服务通道
-

iv_cs_running_status

接口描述 云存储各业务运行状态枚举。
typedef enum iv_cs_running_status_e{
IV_CS_EVENT_CREATING = 0,
IV_CS_EVENT_UPLOADING = 1,
IV_CS_FULL_TIME_UPLOADING = 2,
IV_CS_EVENT_DEAL_INIT = 3,
}iv_cs_running_status_e;
参数说明
成员名称
描述
取值
IV_CS_EVENT_CREATING
正在生成事件中(上传图片和事件信息)
-
IV_CS_EVENT_UPLOADING
正在上传事件云录像文件中(待上传列表不为空)
-
IV_CS_FULL_TIME_UPLOADING
正在上传全时云录像文件中(待上传列表不为空)
-

示例代码

1. 云存储初始化

iv_err_code_e eErrCode = 0;
iv_cs_init_parm_s stCsInitParm;
memset(&stCsInitParm, 0, sizeof(iv_cs_init_parm_s));
stCsInitParm.u32MaxSizeInAGop = 512*1024;
stCsInitParm.iv_cs_push_stream_start_cb = cloudStorage_start;
stCsInitParm.iv_cs_push_stream_stop_cb = cloudStorage_stop;
stCsInitParm.iv_cs_ai_service_notify_cb = cloudStorage_ai_service_notify;
stCsInitParm.iv_cs_event_capture_picture = cloudStorage_event_capture_picture;
stCsInitParm.iv_cs_event_upload_picture_result = cloudStorage_event_upload_picture_result;
stCsInitParm.event_list_max_depth = IV_CS_MAX_EVENT_LIST_DEPTH;
stCsInitParm.event_record_min_time_s = 8;
stCsInitParm.event_interval_time_s = 3*60;
for(int i = 0; i < IV_CS_EVENT_MAX_TRIGGER;i++)
{
stCsInitParm.event_trigger_priority[i] = i;
}
eErrCode = iv_cs_init(&stCsInitParm);
if(eErrCode < 0)
{
GDB_ERR("fail:%d\\n", eErrCode);
return eErrCode;
}

2. 云存储去初始化

void* cloudStorage_exit_waiting(void* param)
{
pthread_detach(pthread_self());
unsigned int time_cnt = 0;
while(!cloud_storage_wait_flag)
{
if(time_cnt++ > 500)
{
if(iv_cs_exit(true) == IV_ERR_CS_EXITING)
{
GDB_INFO("exit time too long,set iv_cs_exit force\\n");
}
break;
}
usleep(10*1000);
}
return NULL;
}
int cloudStorage_exit(void)
{
cloudStorage_stop();
iv_err_code_e eErrCode = 0;
pthread_t tid = 0;
cloud_storage_wait_flag = 0;
pthread_create(&tid,NULL,cloudStorage_exit_waiting,NULL);
eErrCode = iv_cs_exit(false);
cloud_storage_wait_flag = 1;
if(eErrCode < 0)
{
GDB_ERR("fail:%d\\n", eErrCode);
return eErrCode;
}

return 0;
}

3. 云存推流

pf_audio_stream_s stAudioStream;
iv_cm_aenc_stream_s stIvAencStream;
av_encdec_dst_type_e eEncdecDstType = AV_ENCDEC_DST_TYPE_CS_HD;

pf_venc_stream_s stVencStream;
iv_cm_venc_stream_s *pstIvVencStream;
memset(&stVencStream, 0, sizeof(pf_venc_stream_s));

while(!s32CloudStorageExit)
{
int s32GetAudioStreamRet = 0;
int s32GetVideoStreamRet = 0;

/*audio data*/
s32GetAudioStreamRet = av_encdec_get_audio_stream(eEncdecDstType, &stAudioStream);
if(s32GetAudioStreamRet < 0) goto RECORD_NO_AUDIO_DATA;
if(0 != stAudioStream.u32Len)
{
stIvAencStream.pu8Stream = stAudioStream.pStream;
stIvAencStream.u32Len = stAudioStream.u32Len;
stIvAencStream.u64TimeStamp = stAudioStream.u64TimeStamp;
iv_cs_push_stream(IV_CS_STREAM_TYPE_AUDIO, IV_CM_VENC_TYPE_H264, (void *)&stIvAencStream);
}
RECORD_NO_AUDIO_DATA:

/*video data*/
s32GetVideoStreamRet = av_encdec_get_video_stream(0, eEncdecDstType, &stVencStream);
if(s32GetVideoStreamRet < 0) goto RECORD_NO_VIDEO_DATA;
pstIvVencStream = (iv_cm_venc_stream_s*)&stVencStream;
iv_cs_push_stream(IV_CS_STREAM_TYPE_VIDEO, IV_CM_VENC_TYPE_H264, (void *)pstIvVencStream);
RECORD_NO_VIDEO_DATA:
if(s32GetAudioStreamRet < 0 && s32GetVideoStreamRet < 0)
{
usleep(5000);
continue;
}
}

4. 随机产生事件触发

int event_happen_interval[10] = {1,1,5,5,10,10,20,40,60,200};
int time_cnt = 0;
uint32_t random_index = 0;
int next_event_happen_cnt = 0;
iv_cs_event_trigger_type_e event_type = 0;
while(1)
{
/* 随机生成 */
if(demo_mode == 0 && time_cnt >= next_event_happen_cnt)
{
srand((unsigned)time(NULL));//用当前时间,设置种子
random_index = rand() % sizeof(event_trigger_type) ;
iv_cs_event_happen_notify(event_trigger_type),time(NULL)*1000);
random_index = rand() % 10 ;
next_event_happen_cnt = time_cnt + event_happen_interval[random_index];
GDB_INFO("create new event next:%d\\n",event_happen_interval[random_index]);
}
time_cnt++;
sleep(1);
}

5. 处理抓图回调和处理图片回调

//抓图回调
void cloudStorage_event_capture_picture(uint8_t* pic_name,uint32_t pic_name_max_len)
{
snprintf(pic_name,pic_name_max_len,"/iot_video_raw/alarm_capture.jpg");
GDB_INFO("cloud storage capture picture:%s\\n",pic_name);
if(access(pic_name,F_OK) != 0)
{
memset(pic_name,0,sizeof(pic_name));
}
}

//处理图片上传回调
void cloudStorage_event_upload_picture_result(uint8_t* pic_name,iv_cs_event_pic_upload_res_e err_code)
{
switch(err_code)
{
case IV_CS_EVENT_PICTURE_UPLOAD_OK:
GDB_INFO("upload %s success\\n",pic_name);
break;
default:
GDB_INFO("upload %s fail:%d\\n",pic_name,err_code);
break;
}
remove(pic_name);
}