# 海康威视 ISAPI PTZ 云台控制协议

> 基于实际抓包分析整理，适用于海康威视网络摄像头

## 1. 概述

### 1.1 ISAPI 简介

ISAPI（IP Surveillance API）是海康威视设备的标准 HTTP API 接口，用于设备配置、实时预览、PTZ 控制等功能。

### 1.2 PTZ 功能

PTZ（Pan-Tilt-Zoom）云台控制，支持：

- **Pan**：水平转动（左右）
- **Tilt**：垂直转动（上下）
- **Zoom**：变焦（放大缩小）

---

## 2. 认证机制

### 2.1 Session 认证（Web 界面使用）

海康摄像头 Web 界面使用 **Session 认证**，而非 Basic Auth。

认证流程：

1. 访问摄像头 Web 界面：`http://{ip}/doc/page/preview.asp`
2. 输入用户名密码登录
3. 登录成功后获取：
   - **Cookie**: `WebSession_{id}={token}`
   - **SessionTag**: 用于请求验证的 hash 值

### 2.2 认证 Header

| Header     | 格式                      | 说明          |
| ---------- | ------------------------- | ------------- |
| Cookie     | `WebSession_{id}={token}` | Session Token |
| SessionTag | `{hash}`                  | 请求验证标识  |

### 2.3 获取认证信息

登录后，可以从浏览器开发者工具中获取：

1. 打开摄像头 Web 界面并登录
2. F12 打开开发者工具
3. 在 Network 标签中找到任意请求
4. 复制 `Cookie` 和 `SessionTag` Header

---

## 3. PTZ 控制 API

### 3.1 连续移动（Continuous）

持续向某个方向移动，直到发送停止命令。

**端点**

```
PUT /ISAPI/PTZCtrl/channels/{channel}/continuous
```

**参数**

- `channel`: 通道号，通常为 `1`

**请求头**

```http
Content-Type: application/x-www-form-urlencoded; charset=UTF-8
Cookie: WebSession_{id}={token}
SessionTag: {hash}
X-Requested-With: XMLHttpRequest
If-Modified-Since: 0
```

**请求体（XML）**

```xml
<?xml version="1.0" encoding="UTF-8"?>
<PTZData>
  <pan>{pan_value}</pan>
  <tilt>{tilt_value}</tilt>
</PTZData>
```

---

## 4. 参数说明

### 4.1 PTZ 参数范围

| 参数 | 范围       | 说明                             |
| ---- | ---------- | -------------------------------- |
| pan  | -100 ~ 100 | 水平转动速度，负值向左，正值向右 |
| tilt | -100 ~ 100 | 垂直转动速度，负值向下，正值向上 |
| zoom | -100 ~ 100 | 变焦速度，负值缩小，正值放大     |

### 4.2 方向控制对照表

| 方向     | pan | tilt | 说明     |
| -------- | --- | ---- | -------- |
| 上       | 0   | 60   | 向上转动 |
| 下       | 0   | -60  | 向下转动 |
| 左       | -60 | 0    | 向左转动 |
| 右       | 60  | 0    | 向右转动 |
| 左上     | -60 | 60   | 斜向左上 |
| 右上     | 60  | 60   | 斜向右上 |
| 左下     | -60 | -60  | 斜向左下 |
| 右下     | 60  | -60  | 斜向右下 |
| **停止** | 0   | 0    | 停止移动 |

> 注：数值 60 是推荐的移动速度，可根据需要调整（1-100）

---

## 5. curl 示例

### 5.1 向右转动

```bash
curl 'http://192.168.0.64/ISAPI/PTZCtrl/channels/1/continuous' \
  -X 'PUT' \
  -H 'Content-Type: application/x-www-form-urlencoded; charset=UTF-8' \
  -H 'Cookie: WebSession_8febb54dd5=1ca674cedc0b6ffddacf1eb4ecfa3016127c90104527f1ecf8ef88ca09bd2ef1' \
  -H 'SessionTag: 7615ce65f40480305568ed02726ac67e89452590e58244976c836b22daeff522' \
  -H 'X-Requested-With: XMLHttpRequest' \
  -H 'If-Modified-Since: 0' \
  --data-raw '<?xml version="1.0" encoding="UTF-8"?><PTZData><pan>60</pan><tilt>0</tilt></PTZData>'
```

### 5.2 向上转动

```bash
curl 'http://192.168.0.64/ISAPI/PTZCtrl/channels/1/continuous' \
  -X 'PUT' \
  -H 'Content-Type: application/x-www-form-urlencoded; charset=UTF-8' \
  -H 'Cookie: WebSession_xxx=xxx' \
  -H 'SessionTag: xxx' \
  --data-raw '<?xml version="1.0" encoding="UTF-8"?><PTZData><pan>0</pan><tilt>60</tilt></PTZData>'
```

### 5.3 停止移动

```bash
curl 'http://192.168.0.64/ISAPI/PTZCtrl/channels/1/continuous' \
  -X 'PUT' \
  -H 'Content-Type: application/x-www-form-urlencoded; charset=UTF-8' \
  -H 'Cookie: WebSession_xxx=xxx' \
  -H 'SessionTag: xxx' \
  --data-raw '<?xml version="1.0" encoding="UTF-8"?><PTZData><pan>0</pan><tilt>0</tilt></PTZData>'
```

---

## 6. 完整请求头参考

基于实际抓包的完整请求头：

```http
PUT /ISAPI/PTZCtrl/channels/1/continuous HTTP/1.1
Host: 192.168.0.64
Accept: */*
Accept-Language: zh-CN,zh;q=0.9,en;q=0.8
Cache-Control: no-cache
Connection: keep-alive
Content-Type: application/x-www-form-urlencoded; charset=UTF-8
Cookie: language=en; WebSession_8febb54dd5=1ca674cedc0b6ffddacf1eb4ecfa3016127c90104527f1ecf8ef88ca09bd2ef1
If-Modified-Since: 0
Origin: http://192.168.0.64
Pragma: no-cache
Referer: http://192.168.0.64/doc/page/preview.asp
SessionTag: 7615ce65f40480305568ed02726ac67e89452590e58244976c836b22daeff522
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36
X-Requested-With: XMLHttpRequest

<?xml version="1.0" encoding="UTF-8"?><PTZData><pan>60</pan><tilt>0</tilt></PTZData>
```

---

## 7. 注意事项

### 7.1 认证问题

- **Session 过期**：登录 Session 会过期，需要重新登录获取新的 Cookie 和 SessionTag
- **401 错误**：如果返回 401 Unauthorized，说明认证信息无效或已过期
- **Basic Auth 无效**：直接使用 Basic Auth 认证无法控制 PTZ

### 7.2 CORS 问题

浏览器前端直接请求摄像头会遇到跨域问题（CORS），解决方案：

1. **开发环境**：使用 Vite/Webpack 代理
2. **生产环境**：通过后端 API 转发请求

### 7.3 网络环境

- 摄像头通常在内网，外网无法直接访问
- 生产环境需要通过后端服务代理

### 7.4 速度控制

- pan/tilt 值越大，移动速度越快
- 推荐使用 50-60 作为默认速度
- 停止命令必须发送 `pan=0, tilt=0`

---

## 8. 相关资源

- 摄像头 Web 界面：`http://{ip}/doc/page/preview.asp`
- 海康 ISAPI 官方文档：联系海康技术支持获取

---

## 更新日志

| 日期       | 内容                       |
| ---------- | -------------------------- |
| 2026-01-09 | 初始版本，基于实际抓包整理 |
