整体方案
接入流程与所需信息
设备连接信息
| 字段名 | 类型 | 说明 |
|---|---|---|
| AppId | string | 项目唯一标识,声网生成 |
| license | string | 一机一码,声网生成 |
| channel | string | 频道,每设备唯一,服务端生成 |
| crypto_enable | bool | 是否加密,服务端配置 |
| crypto_mode | int | 加密方式,服务端配置 |
| crypto_key | string | 密钥,用于加密音视频数据,服务端生成 |
| device_uid | int | 设备端用户id,对应声网uid,服务端生成 |
| token | string | 动态密钥,声网用 Token 对用户加入频道进行鉴权,服务端生成 |
| area_code | int | 访问区域,限定SDK访问指定区域声网服务器,服务端配置 |
APP连接信息
| 字段名 | 说明 |
|---|---|
| AppId | 项目唯一标识,声网生成 |
| channel | 频道,每设备唯一,服务端生成 |
| crypto_enable | 是否加密,服务端配置 |
| crypto_mode | 加密方式,服务端配置 |
| crypto_key | 密钥,用于加密音视频数据,服务端生成 |
| device_uid | 设备端用户id,对应声网uid,服务端生成,用于APP端区分设备是否加入/离开频道 |
| app_uid | 应用端用户id,对应声网uid,服务端配置或生成 |
| token | 动态密钥,声网用 Token 对用户加入频道进行鉴权,服务端生成 |
| area_code | 访问区域,限定SDK访问指定区域声网服务器,服务端配置 |
设计技术方案
因声网 SDK有自已的业务规则,部分业务场景不支持或不适合于我们产品品类,为了满足业务与产品化需求,需要制定属于我们业务的流程与信令;同时针对安全、未来多摄、接入Alexa等业务需求,以下事项需要设计与讨论
- 音视频业务场景(指定清晰度,自适应视频质量,EMCC回放,EMCC下载,多摄多路流,多摄单路流,Alexa)流程设计(接口与信令)
- 音视频业务场景(指定清晰度,自适应视频质量,EMCC回放,EMCC下载,多摄多路流,多摄单路流,Alexa)自定义信令定义
- 设备推流策略,连接后是自动,还是通过开流信令启动(自研是通过信令,根据业务需要启动直播/回放推流/指定推流清晰度)
- license与token有效期(当前声网定义的最长是24小时),及更新机制
- channel 名称规则:设备did_类型_类型参数
-
- 类型取值:defualt(缺省),live(直播),playback(回放)。缺省通道用于创建数据流,接收控制信令,APP与设备端初始化后,缺省加入;直播通道用于直播音视频数据据收发;回放通道,用于回放音视频数据收发
- defualt类型参数,当前缺省为0
- live直播类型参数:当前缺省为0,未来扩展多摄多路流时,取值0/1/2/3区分
- playback回放类型参数:取值为app uid,用于隔离不同用户同时查看回放与直播
- channel名称示例:000001_default_0,000001_live_0,000001_playback_1001
- 服务器端需以设备did,作为channel前缀,生成设备与应用的token
- 设备端与应用端,自行拼接缺省通道,如000001_default_0
- 直播通道与回放通道,由应用端生成,通过控制信令(开始实时音视频播放/点播)发给设备端
-
- 主要通道:(如000001_default_0),用于创建数据流,接收控制信令,APP与设备端初始化后,缺省加入
- device/app uid 规则,(对设备与用户uid进行分段,如10000,10001为设备uid,20000,20001为用户uid)
- 加密方式
- 考虑未来产品,支持多摄多路流设备,需确定是采用多频道还是单频道传输,返回多个channel或多个设备的uid,及多channel对应的token
服务端开发事项
- 新增声网视频方案元数据,产品关联
- license导入与激活
- 设备绑定:配置与绑定声网连接信息(license/channel/uid/token等)
- 设备连接信息接口(原P2PInfo信息接口)
- token生成与接口
设备端开发事项
- 集成RTSA Lite SDK
- 获取连接信息
- 实现自定义信令
- 实现音视频业务场景功能
应用端开发事项
- 集成RTC SDK
- 获取连接信息
- 实现自定义信令
- 实现音视频业务场景功能
- 视频SDK(KIotVideo) 封装声网方案(原生/ReactNative)
- 视频业务模块开发(原生/ReactNative)
数据流自定义数据帧格式
通过声网SDK连接与加入频道成功后,创建数据流,使用其功能,实现实时状态同步、发送控制信令
根据以下特点与需求定义数据格式:
- 数据流数据包发送与接收是一发一收,提供可靠有序
- 每个数据包,最大 1 KB
- IPC 产品EMMC 回放当天数据有可能超过1 KB大小
- 数据流已加密数据
综上信令的数据包,超过1KB,需要进行分片传输,无需加密
数据帧格式方案
原自研的音视频传输协议,增加分包字段,数据包超过1000字节,进行分包
0 1 2 3
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| headerTag |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| payloadLen |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| version | signCode | dataType | isResponse |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| paddingCount | fin | |
+-+-+-+-+-+-+-+-+ +
| reserve |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
其中各个字段的含义如下:
- headTag:标记头,占用 4 个字节,采用小端模式,固定值为 0x68999999,用于标识消息的起始位置。
- payloadLen:数据载荷长度,占用 4 个字节,采用小端模式,表示消息体的长度,不包括头部的长度。
- version:通信协议版本,占用 1 个字节,目前版本为 2。
- signCode:加密标识码,占用 1 个字节,取值为 1 或 0,表示消息是否需要进行解密。目前为 0,表示消息不需要进行解密。
- dataType:数据类型,占用 1 个字节,表示消息体中数据的类型。取值为 0 时表示控制信令,取值为 1 时表示音频数据,取值为 2 时表示视频数据,取值为 3 时表示 flv 数据。
- isResponse:是否是应答,占用 1 个字节,取值为 1 或 0。当值为 1 时,表示该消息是应答消息;当值为 0 时,表示该消息不是应答消息。
- paddingCount: 填充计数,占用 1 个字节,取值为 0~255。当加密标识码取值为 1 时,使用AES加密算法,当数据明文长度不足块长度时,需要使用填充字节将其补齐,指示填充的字节数。
- fin: 分包标识,占用 1 个字节,取值为 1 或 0。值为 0 时,数据最后一包;值为 1 时,还有后续数据包;如分包需顺序发送
- reserve:预留字段,占用 6 个字节,目前为 0,用于扩展协议的功能。
数据流自定义控制信令
数据帧头+Payload data(JSON),除了无需发起会话信令外,同原自研音视频信令
信令协议拓展字定义
{
//...信令数据结构
"extra":{ //可选
"did": "000001", //设备did
}
}
例如
{
"cmdType": 1001,
"seq": 1,
"p2pSessionId": "087813f90d",
"data": {
"cameraIndex": 0,
"videoQuality": 1,
"channel": "000001_live_0",
}
"extra":{
"did": "000001", //设备did,用于基站(区分子设备)
}
}
开始实时音视频播放(cmdType:1001)
APP 可选设置音视频播放参数,请求设备使用对应参数
设备应答本次实时播放音视频参数,如果 APP 有设置相关参数,设备检查是否支持:如支持,设置相关参数;不支持或 APP 未设置,使用设备端缺省参数
请求消息样例
{
"cmdType": 1001, // 命令类型,必选
"seq": 1, // 消息序号,必选
"p2pSessionId": "087813f90d", //p2p 会话 Id,用于设备端区分、关联MQTT信令与p2p连接,APP生成
"data": {
"cameraIndex": 0, //摄像头序号,取值 0:默认 1:主摄像头 2:副摄像头 3:后摄
"videoQuality": 1, //视频质量,取值 0:设备自动 取值 1:流畅 2:标清 3:超高清,必选
"channel": "000001_live_0", //通道
}
"extra":{ //可选
"did": "000001", //设备did,用于基站(区分子设备)
}
}
参数说明
| 参数名称 | 参数类型 | 说明 | 是否可选 |
|---|---|---|---|
| cmdType | int | 命令类型 | 否 |
| seq | int | 消息序号 | 否 |
| cameraIndex | int | 摄像头序号,取值 0:默认 1:主摄像头 2:副摄像头 3:后摄 | 是 |
| videoQuality | int | 视频质量,取值 0:设备自动 1:流畅 2:标清 3:超高清 | 否 |
| p2pSessionId | string | p2p 会话 Id,每次 p2p 连接后随机生成,用于设备端区分 APP | 否 |
| channel | string | 通道(直播)名称,详见channel 名称规则 | 否 |
应答消息样例
{
"cmdType": 1001, // 命令类型,必选
"seq": 1, // 消息序号,必选
"data": {
"ack": "OK", // 应答状态消息,必选
"errorCode": 0, // 应答错误码,取值 0:成功 1:失败,详见错误码定义,必选
"cameraIndex": 0, //摄像头序号,取值 0:默认 1:主摄像头 2:副摄像头 3:后摄,必选
"videoCodecId": 0, // 视频编码格式,视频编码格式,取值 0:设备默认 1:H264 2:H265 3:MJPEG,必选
"videoWidth": 1280, // 视频像素宽度,取值 640/960/1280/1920/2560,必选
"videoHeight": 720, // 视频像素高度,取值 360/540/720/1080/1440,必选
"videoFrameRate": 15, // 视频帧率,取值 15/20/30,必选
"videoQuality": 1, // 视频质量,取值 1:流畅 2:标清 3:超高清,必选
"videoBitrate": 500, // 视频码率,单位bps,必选
"audioCodecId": 0, // 音频编码格式,取值 0:AAC 1:PCM 2:g711u,可选
"audioSampleRate": 16000, // 音频采样率,取值 8000/16000/44100/48000,必选
"audioNumberOfChannels": 1, // 音频声道数目,取值1/2,必选
"audioSampleBit": 16, //音频采样位数,取值 8/16,必选
}
}
参数说明
| 参数名称 | 参数类型 | 说明 | 是否可选 |
|---|---|---|---|
| cmdType | int | 命令类型 | 否 |
| seq | int | 消息序号 | 否 |
| ack | string | 应答状态消息 | 否 |
| errorCode | int | 应答错误码,取值 0:成功 1:失败,详见错误码定义 | 否 |
| cameraIndex | int | 摄像头序号,取值 0:默认 1:主摄像头 2:副摄像头 3:后摄 | 否 |
| videoCodecId | int | 视频编码格式,取值 0:设备默认 1:H264 2:H265 3:MJPEG | 否 |
| videoWidth | int | 视频像素宽度,取值 640/960/1280/1920/2560 | 否 |
| videoHeight | int | 视频像素高度,取值 360/540/720/1080/1440 | 否 |
| videoFrameRate | int | 视频帧率,取值 15/20/30 | 否 |
| videoQuality | int | 视频质量,取值 1:流畅 2:标清 3:超高清 | 否 |
| videoBitrate | int | 视频码率,单位 bps | 否 |
| audioCodecId | int | 音频编码格式,取值 0:AAC 1:PCM 2:g711u | 否 |
| audioSampleRate | int | 音频采样率,取值 8000/16000/44100/48000 | 否 |
| audioNumberOfChannels | int | 音频声道数目,取值 1/2 | 否 |
| audioSampleBit | int | 音频采样位数,取值 8/16 | 否 |
停止实时音视频播放 (cmdType:1002)
请求消息样例
{
"cmdType": 1002,
"seq": 2,
"p2pSessionId": "087813f90d",
"data":{
"cameraIndex": 0,
"channel": "通道名"
}
"extra":{ //可选
"did": "000001", //设备did
}
}
参数说明
| 参数名称 | 参数类型 | 说明 | 是否可选 |
|---|---|---|---|
| cmdType | int | 命令类型 | 否 |
| seq | int | 消息序号 | 否 |
| cameraIndex | int | 摄像头序号,取值 0:默认 1:主摄像头 2:副摄像头 3:后摄 | 否 |
| p2pSessionId | string | p2p 会话 Id,每次 p2p 连接后随机生成,用于设备端区分 APP | 否 |
应答消息样例
{
"cmdType": 1002,
"seq": 2,
"data": {
"ack": "OK",
"errorCode": 0,
"cameraIndex": 0
}
}
参数说明
| 参数名称 | 参数类型 | 说明 | 是否可选 |
|---|---|---|---|
| cmdType | int | 命令类型 | 否 |
| seq | int | 消息序号 | 否 |
| ack | string | 应答状态消息 | 否 |
| errorCode | int | 应答错误码,取值 0:成功 1:失败,详见错误码定义 | 否 |
| cameraIndex | int | 摄像头序号,取值 0:默认 1:主摄像头 2:副摄像头 3:后摄 |
开始语音对讲 (cmdType:1003)
APP 可选设置语音对讲参数,请求设备使用对应参数
设备应答本次语音对讲参数,如果 APP 有设置相关参数,设备检查是否支持:如支持,设置相关参数;不支持或 APP 未设置,使用设备端缺省参数
请求消息样例
{
"cmdType": 1003,
"seq": 4,
"p2pSessionId": "087813f90d",
"data": {
"channel": "000001_live_0", //通道
},
"extra":{ //可选
"did": "000001", //设备did
}
}
应答消息样例
{
"cmdType": 1003,
"seq": 4,
"data": {
"ack": "OK",
"errorCode": 0,
"audioCodecId": 0, // 音频编码格式,取值 0:AAC 1:PCM 2:g711u
"audioSampleRate": 16000, // 音频采样率,取值 8000/16000/44100/48000
"audioNumberOfChannels": 1, // 音频声道数目,取值1/2
"audioSampleBit": 16, //音频采样位数,取值 8/16
}
}
参数说明
| 参数名称 | 参数类型 | 说明 | 是否可选 |
|---|---|---|---|
| audioCodecId | int | 音频编码格式,取值 0:AAC 1:PCM 2:g711u | 是 |
| audioSampleRate | int | 音频采样率,取值 8000/16000/44100/48000 | 是 |
| audioNumberOfChannels | int | 音频声道数目,取值 1/2 | 是 |
| audioSampleBit | int | 音频采样位数,取值 8/16 | 是 |
停止语音对讲 (cmdType:1004)
请求消息样例
{
"cmdType": 1004,
"seq": 5,
"p2pSessionId": "087813f90d" //p2p 会话 Id,用于设备端区分、关联MQTT信令与p2p连接,APP生成
"data": {
"channel": "000001_live_0", //通道
},
"extra":{ //可选
"did": "000001", //设备did
}
}
应答消息样例
{
"cmdType": 1004,
"seq": 5,
"data": {
"ack": "OK",
"errorCode": 0
}
}
开始点播 (cmdType:1005)
APP 点播设备本地视频文件
请求消息样例
{
"cmdType": 1005,
"seq": 6,
"p2pSessionId": "087813f90d",
"data": {
"cameraIndex": 0, //摄像头序号,取值 0:默认 1:主摄像头 2:副摄像头 ,可选
"startTime": 1614847697, //起始时间,Unix 时间戳,必选
"endTime": 1614847697, //结束时间,Unix 时间戳,可选
"sendMode": 0, //发送方式,0:播放模式(默认)1:下载模式(最快速度以flv格式传输视频文件)
"channel": "000001_playback_1001", //通道(回放)
},
"extra":{ //可选
"did": "000001", //设备did
}
}
参数说明
| 参数名称 | 参数类型 | 说明 | 是否可选 |
|---|---|---|---|
| cameraIndex | int | 摄像头序号,取值 0:默认 1:主摄像头 2:副摄像头 | 是 |
| startTime | int | 起始时间,Unix 时间戳 | 否 |
| endTime | int | 结束时间,Unix 时间戳 | 是 |
| sendMode | int | 发送方式,0:播放模式(默认)1:下载模式(最快速度以flv格式传输视频文件) | 是 |
| channel | string | 通道名称(回放),详见channel 名称规则 | 否 |
应答消息样例
{
"cmdType": 1005, // 命令类型,必选
"seq": 6, // 消息序号,必选
"data": {
"ack": "OK", // 应答状态消息,必选
"errorCode": 0, // 应答错误码,取值 0:成功 1:失败 -1008:文件不存在,详见错误码定义,必选
"sendMode": 0, //发送方式,0:播放模式(默认)1:下载模式(最快速度以flv格式传输视频文件)
"videoFileSize": 0, //视频文件大小,可选
"videoCodecId": 0, // 视频编码格式,视频编码格式,取值 0:设备默认 1:H264 2:H265 3:MJPEG,必选
"videoWidth": 1280, // 视频像素宽度,取值 640/960/1280/1920/2560,必选
"videoHeight": 720, // 视频像素高度,取值 360/540/720/1080/1440,必选
"videoFrameRate": 15, // 视频帧率,取值 15/20/30,必选
"videoBitrate": 500, // 视频码率,单位bps,必选
"audioCodecId": 0, // 音频编码格式,取值 0:AAC 1:PCM 2:g711u,可选
"audioSampleRate": 16000, // 音频采样率,取值 8000/16000/44100/48000,必选
"audioNumberOfChannels": 1, // 音频声道数目,取值1/2,必选
"audioSampleBit": 16, //音频采样位数,取值 8/16,必选
}
}
参数说明
| 参数名称 | 参数类型 | 说明 | 是否可选 |
|---|---|---|---|
| cmdType | int | 命令类型 | 否 |
| seq | int | 消息序号 | 否 |
| ack | string | 应答状态消息 | 否 |
| errorCode | int | 应答错误码,0:成功 1:失败 -1008:文件不存在,详见错误码定义 | 否 |
| sendMode | int | 发送方式,0:播放模式(默认)1:下载模式(最快速度以flv格式传输视频文件) | |
| videoFileSize | long | 下载模式下,视频文件大小 | 是 |
| videoCodecId | int | 视频编码格式,取值 0:设备默认 1:H264 2:H265 3:MJPEG | 否 |
| videoWidth | int | 视频像素宽度,取值 640/960/1280/1920/2560 | 否 |
| videoHeight | int | 视频像素高度,取值 360/540/720/1080/1440 | 否 |
| videoFrameRate | int | 视频帧率,取值 15/20/30 | 否 |
| videoBitrate | int | 视频码率,单位 bps | 否 |
| audioCodecId | int | 音频编码格式,取值 0:AAC 1:PCM 2:g711u | 否 |
| audioSampleRate | int | 音频采样率,取值 8000/16000/44100/48000 | 否 |
| audioNumberOfChannels | int | 音频声道数目,取值 1/2 | 否 |
| audioSampleBit | int | 音频采样位数,取值 8/16 | 否 |
停止点播 (cmdType:1006)
点播开始后,APP主动停止/设备点播播放完成/设备点播意外停止发送此信令
请求消息样例
{
"cmdType": 1006,
"seq": 7,
"p2pSessionId": "087813f90d",
"data": {
"cameraIndex": 0, //摄像头序号,取值 0:默认 1:主摄像头 2:副摄像头,可选
"sendMode": 0, //发送方式,0:播放模式(默认) 1:下载模式(最快速度以flv格式传输视频文件)
"reasonCode": 0, // 停止原因,取值 0: 点播完成 1: 意外停止 -1008: 点播文件不存在, 必选
"channel": "000001_playback_1001", //通道
},
"extra":{ //可选
"did": "000001", //设备did
}
}
参数说明
| 参数名称 | 参数类型 | 说明 | 是否可选 |
|---|---|---|---|
| cameraIndex | int | 摄像头序号,取值 0:默认 1:主摄像头 2:副摄像头 | 是 |
| sendMode | int | 发送方式,0:播放模式(默认) 1:下载模式(最快速度以flv格式传输视频文件) | 是 |
| reasonCode | int | 停止原因,取值 0: 点播完成 1: 意外停止 -1008: 点播文件不存在 | 否 |
应答消息样例
{
"cmdType": 1006, // 命令类型,必选
"seq": 7, // 消息序号,必选,
"p2pSessionId": "087813f90d",
"data": {
"ack": "OK", // 应答状态消息,必选
"errorCode": 0, // 应答错误码,取值 0:成功 1:失败 ,详见错误码定义,必选
}
}
参数说明
| 参数名称 | 参数类型 | 说明 | 是否可选 |
|---|---|---|---|
| cmdType | int | 命令类型 | 否 |
| seq | int | 消息序号 | 否 |
| ack | string | 应答状态消息 | 否 |
| errorCode | int | 应答错误码,0:成功 1:失败 ,详见错误码定义 | 否 |
查询多摄当前画面模式 (cmdType:1007)
多摄单路流,查询多摄当前画面模式
请求消息样例
{
"cmdType": 1007, // 命令类型,必选
"seq": 7, // 消息序号,必选
"p2pSessionId": "087813f90d",
"data":{},
"extra":{ //可选
"did": "000001", //设备did
}
}
应答消息样例
{
"cmdType": 1007, // 命令类型,必选
"seq": 7, // 消息序号,必选
"data": {
"ack": "OK", // 应答状态消息,必选
"errorCode": 0, // 应答错误码,取值 0:成功 1:失败
"pictureMode": 0, // /画面模式,取值 0:主摄像头,1:副摄像头,2: 主副摄像头合并(副摄像头在小框),3:主副摄像头合并(主摄像头在小框),必选
}
}
参数说明
| 参数名称 | 参数类型 | 说明 | 是否可选 |
|---|---|---|---|
| pictureMode | int | 画面模式,取值 0:主摄像头,1:副摄像头,2: 主副摄像头合并(副摄像头在小框),3:主副摄像头合并(主摄像头在小框) | 否 |
设置多摄当前画面模式 (cmdType:1008)
多摄单路流,设置多摄当前画面模式
请求消息样例
{
"cmdType": 1008, // 命令类型,必选
"seq": 8, // 消息序号,必选
"p2pSessionId": "087813f90d",
"data": {
"pictureMode": 0, //画面模式,取值 0:主摄像头,1:副摄像头,2: 主副摄像头合并(副摄像头在小框),3:主副摄像头合并(主摄像头在小框)
},
"extra":{ //可选
"did": "000001", //设备did
}
}
参数说明
| 参数名称 | 参数类型 | 说明 | 是否可选 |
|---|---|---|---|
| pictureMode | int | 画面模式,取值 0:主摄像头,1:副摄像头,2: 主副摄像头合并(副摄像头在小框),3:主副摄像头合并(主摄像头在小框) | 否 |
应答消息样例
{
"cmdType": 1008, // 命令类型,必选
"seq": 8, // 消息序号,必选
"data": {
"ack": "OK", // 应答状态消息,必选
"errorCode": 0, // 应答错误码,取值 0:成功 1:失败 ,必选
}
}
操作云台 (cmdType:1009)
云台机,操作云台
- 设备上下左右操作过程中到顶,设备需再次应答到顶错误码(-1009)
- APP 上、下、左、右操作结束,需再次发送停止
- APP 360环视操作,退出直播页面,需再次发送停止
请求消息样例
{
"cmdType": 1009, // 命令类型,必选
"seq": 9, // 消息序号,必选
"p2pSessionId": "087813f90d",
"data": {
"ptzAction": 0, //操作云台类型,取值 0:停止,1:上,2:下,3:左,4:右,5:360环视,6:云台矫正
},
"extra":{ //可选
"did": "000001", //设备did
}
}
参数说明
| 参数名称 | 参数类型 | 说明 | 是否可选 |
|---|---|---|---|
| ptzAction | int | 操作类型,取值 0: 停止,1:上,2:下,3:左,4:右,5:360环视,6:云台矫正 | 否 |
应答消息样例
{
"cmdType": 1009, // 命令类型,必选
"seq": 8, // 消息序号,必选
"data": {
"ack": "OK", // 应答状态消息,必选
"errorCode": 0, // 应答错误码,取值 0:成功, 1:失败,-1009: 云台操作到顶,必选
"ptzAction": 0 //操作云台类型,取值 0:停止,1:上,2:下,3:左,4:右,5:360环视,6:云台矫正
}
}
本地录像按月查询 (cmdType:1010)
云台机回放,按月查询录像情况,返回每天是否有录像
请求消息样例
{
"cmdType": 1010, // 命令类型,必选
"seq": 10, // 消息序号,必选
"p2pSessionId": "087813f90d",
"data": {
"year": 2025, //年
"month": 6, //月
},
"extra":{ //可选
"did": "000001", //设备did
}
}
参数说明
| 参数名称 | 参数类型 | 说明 | 是否可选 |
|---|---|---|---|
| year | int | 年 | 否 |
| month | int | 月 | 否 |
应答消息样例
{
"cmdType": 1010, // 命令类型,必选
"seq": 10, // 消息序号,必选
"data": {
"ack": "OK", // 应答状态消息,必选
"errorCode": 0, // 应答错误码,取值 0:成功, 1:失败,必选
"dayList": 10 // 从低位到高位每一比特代表月份的第几天是否有录像,如 10(1010)表示2号与4号有录像
}
}
参数说明
| 参数名称 | 参数类型 | 说明 | 是否可选 |
|---|---|---|---|
| dayList | int | 从低位到高位每一比特代表月份的第几天是否有录像,如 10(1010)表示2号与4号有录像 | 否 |
本地录像按起止时间查询 (cmdType:1011)
云台机回放,按起止时间查询录像,返回录像索引与报警索引列表
请求消息样例
{
"cmdType": 1011, // 命令类型,必选
"seq": 10, // 消息序号,必选
"p2pSessionId": "087813f90d",
"data": {
"startTime": 1614847697, //起始时间,UTC时间戳 ,必选
"endTime": 1614847697, //结束时间,UTC时间戳,可选
},
"extra":{ //可选
"did": "000001", //设备did
}
}
参数说明
| 参数名称 | 参数类型 | 说明 | 是否可选 |
|---|---|---|---|
| startTime | long | 起始时间,UTC时间戳 | 否 |
| endTime | long | 结束时间,UTC时间戳 | 是 |
应答消息样例
{
"cmdType": 1011, // 命令类型,必选
"seq": 10, // 消息序号,必选
"data": {
"ack": "OK", // 应答状态消息,必选
"errorCode": 0, // 应答错误码,取值 0:成功, 1:失败,必选
"videoList": [
[1614847697,1614847697], //每个录像片段用一个长度为2的数组表示,格式为:
[startTime, endTime]
], //录像索引列表
"alarmList": [
[1614847697,1614847697, 1], //每个报警事件用一个长度为3的数组表示,格式为:
[startTime, endTime, alarmType]
] //报警索引列表
}
}
参数说明
| 参数名称 | 参数类型 | 说明 | 是否可选 |
|---|---|---|---|
| videoList | array | 录像索引列表,每个录像片段用一个长度为2的数组表示,格式为: [startTime, endTime] | 是 |
| alarmList | array | 报警索引列表,每个报警事件用一个长度为3的数组表示,格式为: [startTime, endTime, alarmType] | 是 |
| startTime | long | 起始时间,UTC时间戳 | 否 |
| endTime | long | 结束时间,UTC时间戳 | 否 |
| alarmType | int | 报警类型, 0b01:运动检测md,0b010:音频检测, 0b100: 人形检测human,0b1000:哭声检测,0b10000: 宠物检测pet,0b100000 视频通话,0b1000000:车辆检测vehicle, 0b10000000:人形越界, 0b100000000:车辆越界, 0b1000000000:包裹送达, 0b10000000000:包裹取走, 如果同一时间段触发多种报警(如同时检测到人和车),可用位掩码组合 | 否 |
暂停回放 (cmdType:1012)
云台机回放,暂停回放
请求消息样例
{
"cmdType": 1012, // 命令类型,必选
"seq": 10, // 消息序号,必选
"p2pSessionId": "087813f90d",
"data": {
"channel": "000001_playback_1001", //回放通道
},
"extra":{ //可选
"did": "000001", //设备did
}
}
应答消息样例
{
"cmdType": 1012, // 命令类型,必选
"seq": 10, // 消息序号,必选
"data": {
"ack": "OK", // 应答状态消息,必选
"errorCode": 0, // 应答错误码,取值 0:成功, 1:失败,必选
}
}
继续回放 (cmdType:1013)
云台机回放,继续回放
请求消息样例
{
"cmdType": 1013, // 命令类型,必选
"seq": 10, // 消息序号,必选
"p2pSessionId": "087813f90d",
"data": {
"channel": "000001_playback_1001", //回放通道
},
"extra":{ //可选
"did": "000001", //设备did
}
}
应答消息样例
{
"cmdType": 1013, // 命令类型,必选
"seq": 10, // 消息序号,必选
"data": {
"ack": "OK", // 应答状态消息,必选
"errorCode": 0, // 应答错误码,取值 0:成功 1:失败 -1008:文件不存在,详见错误码定义,必选
}
}
回放跳转播放 (cmdType:1014)
云台机回放,跳转播放
请求消息样例
{
"cmdType": 1014, // 命令类型,必选
"seq": 10, // 消息序号,必选
"p2pSessionId": "087813f90d",
"data": {
"seekTime":1614847697, //跳转播放时间,UTC时间戳
"channel": "000001_playback_1001", //回放通道
},
"extra":{ //可选
"did": "000001", //设备did
}
}
参数说明
| 参数名称 | 参数类型 | 说明 | 是否可选 |
|---|---|---|---|
| seekTime | long | 跳转播放时间,UTC时间戳 | 否 |
应答消息样例
{
"cmdType": 1014, // 命令类型,必选
"seq": 10, // 消息序号,必选
"data": {
"ack": "OK", // 应答状态消息,必选
"errorCode": 0, // 应答错误码,取值 0:成功 1:失败 -1008:文件不存在,详见错误码定义,必选
}
}
回放进度 (cmdType:1015)
云台机回放,APP查询点播进度,设备主动上报回放进度
以下情况设备主动上报:
- 回放切换录像文件时上报点播进度
- 设备每播放I帧上报点播进度
- 回放完成
请求(APP)或上报(设备)消息样例
{
"cmdType": 1015, // 命令类型,必选
"seq": 10, // 消息序号,必选
"p2pSessionId": "087813f90d",
"data": {
"progressTime": 1614847697, //当前播放时间,UTC时间戳;APP查询时可选,设备应答必选;设备上报时progressTime必选,APP应答可选
"playbackFinish": 0, //是否播放完成,取值 0:未完成 1:已完成
"channel": "000001_playback_1001", //回放通道
},
"extra":{ //可选
"did": "000001", //设备did
}
}
应答消息样例
{
"cmdType": 1015, // 命令类型,必选
"seq": 10, // 消息序号,必选
"data": {
"ack": "OK", // 应答状态消息,必选
"errorCode": 0, // 应答错误码,取值 0:成功 1:失败 -1008:文件不存在,详见错误码定义,必选
"progressTime": 1614847697, //当前播放时间,UTC时间戳;APP查询时可选,设备应答必选;设备上报时progressTime必选,APP应答可选
}
}
参数说明
| 参数名称 | 参数类型 | 说明 | 是否可选 | |
|---|---|---|---|---|
| progressTime | long | 当前播放时间,UTC时间戳 | APP请求是,设备上报与应答否 | |
| playbackFinish | int | 是否播放完成,取值 0:未完成 1:已完成 | APP请求是,设备上报与应答否 |
本地录像指定日期查询 (cmdType:1016)
云台机回放,指定日期查询录像,返回录像索引与报警索引列表
请求消息样例
{
"cmdType": 1011, // 命令类型,必选
"seq": 10, // 消息序号,必选
"p2pSessionId": "087813f90d",
"data": {
"year": 2025, //年
"month": 6, //月
"day": 1, //日
},
"extra":{ //可选
"did": "000001", //设备did
}
}
参数说明
| 参数名称 | 参数类型 | 说明 | 是否可选 |
|---|---|---|---|
| year | int | 年 | 否 |
| month | int | 月 | 否 |
| day | int | 天 | 否 |
应答消息样例
{
"cmdType": 1011, // 命令类型,必选
"seq": 10, // 消息序号,必选
"data": {
"ack": "OK", // 应答状态消息,必选
"errorCode": 0, // 应答错误码,取值 0:成功, 1:失败,必选
"videoList": [
[1614847697,1614847697], //每个录像片段用一个长度为2的数组表示,格式为:
[startTime, endTime]
], //录像索引列表
"alarmList": [
[1614847697,1614847697, 1], //每个报警事件用一个长度为3的数组表示,格式为:
[startTime, endTime, alarmType]
] //报警索引列表
}
}
参数说明
| 参数名称 | 参数类型 | 说明 | 是否可选 |
|---|---|---|---|
| videoList | array | 录像索引列表,每个录像片段用一个长度为2的数组表示,格式为: [startTime, endTime] | 是 |
| alarmList | array | 报警索引列表,每个报警事件用一个长度为3的数组表示,格式为: [startTime, endTime, alarmType] | 是 |
| startTime | long | 起始时间,UTC时间戳 | 否 |
| endTime | long | 结束时间,UTC时间戳 | 否 |
| alarmType | int | 报警类型, 0b01:运动检测md,0b010:音频检测, 0b100: 人形检测human,0b1000:哭声检测,0b10000: 宠物检测pet,0b100000 视频通话,0b1000000:车辆检测vehicle, 0b10000000:人形越界, 0b100000000:车辆越界, 0b1000000000:包裹送达, 0b10000000000:包裹取走, 如果同一时间段触发多种报警(如同时检测到人和车),可用位掩码组合 | 否 |
音视频业务场景流程
APP查看实时实频
自定义信令通过RTC/RTSA SDK数据流功能进行传输
设备端收到开始实时音视频播放信令后才进行推流操作
@startuml
participant "APP" as APP
participant "RTC/RTSA SDK" as RTCSDK
participant "服务端" as SERVER
participant "MQTT" as MQTT
participant "设备" as DEVICE
alt 唤醒设备
APP -> SERVER: HTTP 唤醒设备
SERVER -> MQTT: 唤醒设备
MQTT -> DEVICE: 唤醒设备
DEVICE --> MQTT: 应答唤醒设备
MQTT --> SERVER: 应答唤醒设备
SERVER --> APP: 应答唤醒设备
end
opt 获取TOKEN(示例),以服务端方案流程为准
APP -> SERVER: HTTP 获取APP连接设备连接信息
SERVER --> APP: 应答APP连接设备连接信息
end
opt 获取TOKEN(示例),以服务端方案流程为准
DEVICE -> SERVER: HTTP 获取设备连接信息
SERVER --> DEVICE: 应答设备连接信息
end
== 连接初始化 ==
APP-> RTCSDK: 创建并初始化引擎
DEVICE -> RTCSDK: 初始化
RTCSDK --> DEVICE: 回调license验证结果
APP-> RTCSDK: 设置视频属性
DEVICE -> RTCSDK: 连接
DEVICE-> RTCSDK: 加入缺省频道
RTCSDK --> DEVICE: 回调加入频道结果
APP-> RTCSDK: 加入缺省频道
RTCSDK--> APP: 回调加入频道结果
APP -> RTCSDK: 创建数据流(用于自定义信令)
DEVICE -> RTCSDK: 创建数据流(用于自定义信令)
alt 检查设备端是否加入频道
APP->APP: 启动超时检查设备端是否加入频道
RTCSDK--> APP: 通知设备端用户(含其它APP用户)加入频道
end
RTCSDK --> DEVICE: 通知APP用户加入频道
== 发送和接收音视频流 ==
alt 加入直播频道与自定义控制信令
APP-> RTCSDK: 加入直播频道
RTCSDK--> APP: 回调加入频道结果
APP -> RTCSDK: 开始实时音视频播放
RTCSDK --> DEVICE: 开始实时音视频播放
DEVICE-> RTCSDK: 加入直播频道
RTCSDK --> DEVICE: 回调加入频道结果
DEVICE -> RTCSDK: 应答开始实时音视频播放
RTCSDK --> APP: 应答开始实时音视频播放
end
DEVICE -> RTCSDK: 发送音视频数据(直播通道)
RTCSDK --> APP: 接收音视频数据
APP -> RTCSDK: 发送音频数据
RTCSDK --> DEVICE: 接收APP音频数据
alt 自定义控制信令
APP -> RTCSDK: 停止实时音视频播放
RTCSDK --> DEVICE: 停止实时音视频播放
DEVICE -> RTCSDK: 应答停止实时音视频播放
RTCSDK --> APP: 应答停止实时音视频播放
end
== 结束 ==
alt 应用
APP -> RTCSDK: 离开频道(缺省/直播/回放)
RTCSDK --> DEVICE: 通知用户离开频道
DEVICE -> DEVICE: 检查当前APP连接数,如果为0,结束本次视频业务
APP -> RTCSDK: 销毁引擎
end
alt 设备
DEVICE -> RTCSDK: 离开频道(缺省/直播/回放)
RTCSDK --> APP: 通知设备离开频道
DEVICE -> RTCSDK: 销毁引擎
end
@enduml
APP语音对讲
RTCSDK 支持同时多个用户对讲
APP查看EMMC回放视频
相关链接
门铃声网方案-APP预研
kaadasrd.yuque.com/kaxmf9/cyux…
申请和使用 License
使用 Token 鉴权
生成 Token
#include <cstdlib>
#include <iostream>
#include "../src/RtcTokenBuilder2.h"
using namespace agora::tools;
int main(int argc, char const *argv[]) {
(void)argc;
(void)argv;
// 获取环境变量 AGORA_APP_ID 的值。请确保你将该变量设为你在声网控制台获取的 App ID
const char *env_app_id = getenv("AGORA_APP_ID");
std::string app_id = env_app_id ? env_app_id : "";
// 获取环境变量 AGORA_APP_CERTIFICATE 的值。请确保你将该变量设为你在声网控制台获取的 App 证书
const char *env_app_certificate = getenv("AGORA_APP_CERTIFICATE");
std::string app_certificate = env_app_certificate ? env_app_certificate : "";
// 将 channelName 替换为需要加入的频道名
std::string channel_name = "channelName";
// 填入你实际的用户 ID
uint32_t uid = "uid";
// Token 的有效时间,单位秒
uint32_t token_expiration_in_seconds = 3600;
// 所有的权限的有效时间,单位秒,声网建议你将该参数和 Token 的有效时间设为一致
uint32_t privilege_expiration_in_seconds = 3600;
std::string result;
std::cout << "App Id:" << app_id << std::endl;
std::cout << "App Certificate:" << app_certificate << std::endl;
if (app_id == "" || app_certificate == "") {
std::cout << "Need to set environment variable AGORA_APP_ID and "
"AGORA_APP_CERTIFICATE"
<< std::endl;
return -1;
}
// 生成 Token
result = RtcTokenBuilder2::BuildTokenWithUid(
app_id, app_certificate, channel_name, uid, UserRole::kRolePublisher,
token_expiration_in_seconds, privilege_expiration_in_seconds);
std::cout << "Token With Int Uid:" << result << std::endl;
return 0;
}
多频道发流和单频道多路发流
发送和接收数据流 (Data Stream)