You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 

7.5 KiB

海康 NVR 历史录像查询与 RTSP 回放接口设计

目标

com.inspect.nvr.hik 下新增海康 NVR 历史录像查询接口。调用方传入 NVR 登录信息、通道、码流类型以及北京时间范围,服务端通过海康网络 SDK 查询该范围内实际存在的录像,返回实际连续录像区间及每个区间对应的 RTSP 回放地址。

本功能只查询录像并生成回放地址,不代理、转码或下载视频流。

HTTP 接口

  • 方法:POST
  • 路径:/hik/nvr/playback/search
  • Content-Type:application/json
  • Swagger 分组:海康NVR回放

请求体

{
  "nvrIp": "192.168.1.100",
  "sdkPort": 8000,
  "rtspPort": 554,
  "channel": 1,
  "streamType": 1,
  "username": "admin",
  "password": "123456",
  "startTime": "2026-07-13 12:00:00",
  "endTime": "2026-07-13 13:00:00"
}

字段规则:

  • nvrIpusernamepassword 必填。
  • sdkPort 范围为 1~65535,用于 SDK 登录,通常为 8000。
  • rtspPort 范围为 1~65535,通常为 554。
  • channel 必须大于 0,使用海康 NVR 实际 SDK 通道号。
  • streamType 取值 1 或 2;1 表示主码流,2 表示子码流。
  • startTimeendTime 格式固定为 yyyy-MM-dd HH:mm:ss,语义固定为 Asia/Shanghai
  • endTime 必须晚于 startTime

成功响应

有录像:

{
  "code": 0,
  "message": "success",
  "hasRecord": true,
  "records": [
    {
      "timeRange": [
        "20260713123000",
        "20260713130000"
      ],
      "rtspUrl": "rtsp://admin:123456@192.168.1.100:554/Streaming/tracks/101?starttime=20260713T043000Z&endtime=20260713T050000Z"
    }
  ]
}

无录像:

{
  "code": 0,
  "message": "success",
  "hasRecord": false,
  "records": []
}

timeRange 始终包含两个北京时间字符串,顺序为 [开始时间, 结束时间],格式固定为 yyyyMMddHHmmss

组件划分

代码全部位于 src/main/java/com/inspect/nvr/hik

  • controller/HikNvrPlaybackController:接收 HTTP 请求、调用服务并返回响应。
  • domain/HikNvrPlaybackRequest:请求模型和 Swagger 字段说明;密码标记为只写字段。
  • domain/HikNvrPlaybackResponse:查询状态、是否存在录像和录像区间列表。
  • domain/HikNvrPlaybackRecord:单个连续录像区间及 RTSP 地址。
  • service/HikNvrPlaybackService:参数校验、SDK 查询、区间裁剪与合并、SDK 通道到 RTSP 通道的衔接。
  • service/HikPlaybackUrlBuilder:使用已解析的 RTSP 通道号和设备本地北京时间生成回放 URL。
  • com.inspect.nvr.service.HikLoginSession:保存登录句柄及设备返回的模拟/数字通道布局,并提供 SDK 通道到 RTSP 通道的映射。
  • exception/HikNvrPlaybackException:携带 SDK 错误码或参数错误信息。
  • controller/HikNvrPlaybackExceptionHandler:将参数错误转换为 HTTP 400,将 NVR 登录或查询错误转换为 HTTP 502。

服务复用项目现有 HikLoginService 管理海康登录句柄,不重复创建独立登录缓存。登录缓存的值从单独的用户句柄扩展为 HikLoginSession,缓存时长、IP 键和登出策略保持不变。

SDK 查询流程

  1. 校验请求参数并按北京时间解析查询范围。
  2. 构造 NvrInfo,通过 HikLoginService.loginSession 获取复用的登录句柄和设备通道布局。
  3. 构造 NET_DVR_FILECOND_V40
    • lChannel 使用请求通道号。
    • dwFileType=0xff,查询所有录像类型。
    • dwIsLocked=0xff,查询锁定和未锁定录像。
    • byFindType=0,查询普通录像卷。
    • byQuickSearch=0,获取完整文件信息。
    • 主码流请求映射为 SDK byStreamType=3,子码流请求映射为 SDK byStreamType=1
    • 开始和结束时间按设备本地北京时间填写 NET_DVR_TIME
  4. 调用 NET_DVR_FindFile_V40 获取查询句柄;返回负数时读取 NET_DVR_GetLastError 并报错。
  5. 循环调用 NET_DVR_FindNextFile_V40
    • NET_DVR_FILE_SUCCESS:读取录像文件起止时间。
    • NET_DVR_ISFINDING:短暂等待后继续,整体设置有限等待次数,避免请求无限阻塞。
    • NET_DVR_FILE_NOFINDNET_DVR_NOMOREFILE:正常结束查询。
    • NET_DVR_FILE_EXCEPTION-1:读取 SDK 错误码并报错。
  6. finally 中调用 NET_DVR_FindClose_V30 关闭查询句柄。

时间区间处理

  • 将每个 SDK 录像区间裁剪到用户请求区间内,避免返回请求范围之外的时间。
  • 丢弃裁剪后为空的区间。
  • 按开始时间排序。
  • 仅合并重叠或首尾完全相接的区间;存在真实时间间隔时分别返回,不能掩盖录像缺失。
  • 返回时间使用北京时间 yyyyMMddHHmmss
  • RTSP 参数保留设备本地北京时间数字,格式为 yyyyMMdd'T'HHmmss'Z'。目标 NVR 固件实测把参数数字按设备本地时间解释;将北京时间转换为 UTC 会建立会话但收不到录像数据。

例如用户查询 12:00:00~13:00:00,NVR 只存在 12:30:00~13:00:00,返回:

"timeRange": ["20260713123000", "20260713130000"]

RTSP URL

录像查询继续使用 SDK 通道号。RTSP 轨道使用设备展示通道序号,两者不能直接混用。登录返回的 NET_DVR_DEVICEINFO_V30 提供模拟通道数、模拟起始通道、数字通道数和数字起始通道,映射规则为:

数字通道:rtspChannel = analogChannelCount + (sdkChannel - digitalStartChannel) + 1
模拟通道:rtspChannel = (sdkChannel - analogStartChannel) + 1
trackId = rtspChannel * 100 + streamType

例如纯 NVR 的模拟通道数为 0、数字起始通道为 33,则 SDK 通道 33 映射为 RTSP 通道 1,主码流轨道为 101。如果设备通道元数据无法覆盖请求通道,则保留原通道号作为兼容回退。

地址格式:

rtsp://<编码后的用户名>:<编码后的密码>@<NVR地址>:<RTSP端口>/Streaming/tracks/<trackId>?starttime=<北京时间开始>&endtime=<北京时间结束>

账号和密码按照 URL user-info 规则进行百分号编码。服务端日志禁止输出完整请求对象、密码或最终 RTSP URL。

错误处理

  • 请求字段缺失、端口或通道非法、时间格式错误、结束时间不晚于开始时间:HTTP 400。
  • SDK 登录失败、NVR 离线、通道错误、权限不足、查询失败或查询超时:HTTP 502,响应中包含 SDK 错误码和中文错误信息。
  • 查询成功但没有录像:HTTP 200,hasRecord=falserecords=[]
  • 查询句柄关闭失败只记录不包含敏感信息的警告,不覆盖原始查询结果或异常。

测试

测试先于生产代码编写,覆盖:

  • 北京时间解析及 RTSP 设备本地时间格式化。
  • 纯 NVR 和混合 DVR 的 SDK 通道到 RTSP 通道映射。
  • 主、子码流轨道号和 SDK 码流类型映射。
  • 用户名、密码特殊字符的安全编码。
  • 查询范围内只有部分录像时,返回裁剪后的完整时间戳。
  • 重叠和首尾相接区间被合并,存在时间缺口的区间保持分离。
  • 无录像返回空列表。
  • SDK 查找中状态能够有限重试。
  • 登录、查询和通道错误返回对应错误码。
  • 成功、无录像及异常路径都关闭查询句柄。
  • Swagger 覆盖测试更新为包含新增接口、参数和响应模型。

非目标

  • 不转码为 HLS、FLV 或 MP4。
  • 不在服务端代理 RTSP 码流。
  • 不下载录像文件。
  • 不修改现有海康登录缓存的过期时长、键和登出策略。
  • 不提交或暂存任何文件。