stream-deploy/reademe/ZLM/ZLM_API_GUIDE.md

562 lines
17 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# ZLMediaKit API 核心概念与使用指南
## 一、核心概念解析
### 1. 流Stream的概念
在 ZLMediaKit 中,**流**是指一个媒体数据源,由四元组唯一标识:
- **schema**: 协议类型rtsp/rtmp/rtc等
- **vhost**: 虚拟主机(通常是 `__defaultVhost__`
- **app**: 应用名(如 live、rtp
- **stream**: 流ID如 test、camera01
**完整流标识**: `schema://vhost/app/stream`
例如: `rtsp://__defaultVhost__/live/test`
### 2. Session会话
**Session** 是指客户端与服务器之间的 **TCP/UDP 连接**
- 每个播放器连接、推流连接都会创建一个 Session
- Session 包含连接ID、本地端口、对端IP、协议类型等信息
- 通过 `getAllSession` 可以查看所有活跃连接
- 通过 `kick_session` 可以断开指定连接
**Session 与 Stream 的关系**
- 一个 Stream 可以有多个 Session多个播放器观看同一个流
- 一个 Session 只对应一个 Stream
### 3. 拉流代理StreamProxy
**拉流代理**是指 ZLMediaKit 作为客户端,从远程服务器拉取流,然后在本地提供服务。
**使用场景**
- 从其他流媒体服务器拉取流到本地
- 协议转换(拉取 RTMP 流,提供 RTSP/HLS 等多协议播放)
- 流的中转和分发
**API**: `addStreamProxy`
```
GET /index/api/addStreamProxy?
secret=xxx&
vhost=__defaultVhost__&
app=live&
stream=test&
url=rtmp://remote.server.com/live/stream
```
**工作原理**
```
远程服务器 --拉流--> ZLMediaKit --提供多协议--> 播放器
(RTMP源) (代理) (RTSP/RTMP/HLS/FLV等)
```
### 4. FFmpeg 拉流代理FFmpegSource
**FFmpeg 代理**是通过调用 FFmpeg 进程来拉取流,支持更多格式和协议。
**与普通拉流代理的区别**
- **StreamProxy**: 使用 ZLMediaKit 内置播放器,性能高,但支持协议有限
- **FFmpegSource**: 使用 FFmpeg支持任意协议/格式,但性能较低,占用资源多
**使用场景**
- 拉取 ZLMediaKit 不支持的协议(如某些特殊 HLS、DASH
- 需要 FFmpeg 的转码能力
- 拉取文件流
**API**: `addFFmpegSource`
```
GET /index/api/addFFmpegSource?
secret=xxx&
src_url=http://example.com/live.m3u8&
dst_url=rtmp://127.0.0.1/live/stream&
timeout_ms=10000
```
### 5. 推流代理StreamPusherProxy
**推流代理**是指将 ZLMediaKit 上的流推送到其他流媒体服务器。
**使用场景**
- 将本地流推送到 CDN
- 多平台分发(同时推送到多个平台)
- 流的备份
**API**: `addStreamPusherProxy`
```
GET /index/api/addStreamPusherProxy?
secret=xxx&
schema=rtmp&
vhost=__defaultVhost__&
app=live&
stream=test&
dst_url=rtmp://cdn.server.com/live/push
```
### 6. 断流close_stream
**断流**是指关闭一个媒体流源,而不是断开客户端连接。
**断流的含义**
- 停止流的源头(推流端或拉流代理)
- 所有观看该流的播放器会断开
- 流从服务器上移除
**与 kick_session 的区别**
- `close_stream`: 关闭流源,影响所有观看者
- `kick_session`: 只断开某个客户端连接,不影响流本身
### 7. RTP 服务器
**RTP 服务器**用于接收 GB28181 设备推送的 RTP 流。
**工作流程**
1. `openRtpServer`: 创建 RTP 接收端口
2. GB28181 设备推送 RTP 流到该端口
3. ZLMediaKit 自动将 RTP 流转换为标准流
4. 可通过 RTSP/RTMP/HLS 等协议播放
---
## 二、完整使用流程示例
### 场景 1: GB28181 设备推流
```bash
# 1. 创建 RTP 服务器(监听端口接收 GB28181 推流)
GET /index/api/openRtpServer?
secret=xxx&
port=10000&
tcp_mode=1&
stream_id=camera01
# 返回: {"code":0, "port":10000}
# 2. GB28181 设备推流到 10000 端口(设备端配置)
# 3. 查看流是否在线
GET /index/api/isMediaOnline?
secret=xxx&
schema=rtsp&
vhost=__defaultVhost__&
app=rtp&
stream=camera01
# 4. 获取流信息(包含所有播放地址)
GET /index/api/getMediaInfo?
secret=xxx&
schema=rtsp&
vhost=__defaultVhost__&
app=rtp&
stream=camera01
# 返回包含:
# - RTSP: rtsp://server:554/rtp/camera01
# - RTMP: rtmp://server:1935/rtp/camera01
# - HTTP-FLV: http://server:80/rtp/camera01.live.flv
# - HLS: http://server:80/rtp/camera01/hls.m3u8
# - WebRTC: webrtc://server/rtp/camera01
```
### 场景 2: RTMP 推流
```bash
# 1. 使用 OBS 或 FFmpeg 推流
ffmpeg -re -i input.mp4 -c copy -f flv rtmp://server:1935/live/mystream
# 推流地址格式: rtmp://服务器IP:端口/app/stream
# - app: 应用名(如 live
# - stream: 流ID如 mystream
# 2. 查看流列表
GET /index/api/getMediaList?secret=xxx
# 返回所有在线流,包含:
# {
# "code": 0,
# "data": [{
# "app": "live",
# "stream": "mystream",
# "vhost": "__defaultVhost__",
# "schema": "rtmp",
# "readerCount": 0, // 观看人数
# "totalReaderCount": 0,
# "originType": 0, // 0=推流1=拉流代理2=点播
# "originUrl": "",
# "createStamp": 1234567890
# }]
# }
# 3. 获取该流的详细信息和播放地址
GET /index/api/getMediaInfo?
secret=xxx&
schema=rtmp&
vhost=__defaultVhost__&
app=live&
stream=mystream
# 4. 播放地址:
# - RTSP: rtsp://server:554/live/mystream
# - RTMP: rtmp://server:1935/live/mystream
# - HTTP-FLV: http://server:80/live/mystream.live.flv
# - HLS: http://server:80/live/mystream/hls.m3u8
# - WebSocket-FLV: ws://server:80/live/mystream.live.flv
```
### 场景 3: 录制流
```bash
# 1. 开始录制MP4 格式)
GET /index/api/startRecord?
secret=xxx&
type=1& # 0=HLS, 1=MP4
vhost=__defaultVhost__&
app=live&
stream=mystream&
max_second=3600 # 每小时切片
# 2. 检查是否正在录制
GET /index/api/isRecording?
secret=xxx&
type=1&
vhost=__defaultVhost__&
app=live&
stream=mystream
# 3. 获取录像文件列表
GET /index/api/getMp4RecordFile?
secret=xxx&
vhost=__defaultVhost__&
app=live&
stream=mystream&
period=2025-12-09 # 指定日期
# 返回:
# {
# "code": 0,
# "data": {
# "paths": [
# "/path/to/record/live/mystream/2025-12-09/10-30-00.mp4",
# "/path/to/record/live/mystream/2025-12-09/11-30-00.mp4"
# ],
# "rootPath": "/path/to/record"
# }
# }
# 4. 停止录制
GET /index/api/stopRecord?
secret=xxx&
type=1&
vhost=__defaultVhost__&
app=live&
stream=mystream
```
### 场景 4: 截图
```bash
# 1. 获取实时截图
GET /index/api/getSnap?
secret=xxx&
url=rtsp://server/live/mystream&
timeout_sec=10&
expire_sec=60 # 缓存时间
# 返回: JPEG 图片数据
# 2. 如果配置了定时截图,查看截图列表
# 截图通常保存在配置的 snap 目录下
# 目录结构: /snap/vhost/app/stream/timestamp.jpg
# 3. 删除截图
GET /index/api/deleteSnapDirectory?
secret=xxx&
vhost=__defaultVhost__&
app=live&
stream=mystream&
file=1234567890.jpg # 可选,不指定则删除整个目录
```
### 场景 5: 下载录像文件
```bash
# 1. 获取录像文件列表见场景3
GET /index/api/getMp4RecordFile?
secret=xxx&
vhost=__defaultVhost__&
app=live&
stream=mystream&
period=2025-12-09
# 2. 下载指定文件
GET /index/api/downloadFile?
file_path=/path/to/record/live/mystream/2025-12-09/10-30-00.mp4&
save_name=mystream_20251209_103000.mp4
# 浏览器会直接下载该文件
```
---
## 三、API 分类与关系图
### 1. 流管理类
```
getMediaList # 获取所有流列表
getMediaInfo # 获取单个流详细信息
isMediaOnline # 检查流是否在线
close_stream # 关闭单个流
close_streams # 批量关闭流
getMediaPlayerList # 获取流的播放者列表
```
### 2. 连接管理类
```
getAllSession # 获取所有TCP/UDP连接
kick_session # 断开单个连接
kick_sessions # 批量断开连接
```
### 3. 代理管理类
```
# 拉流代理
addStreamProxy # 添加拉流代理
delStreamProxy # 删除拉流代理
listStreamProxy # 列出所有拉流代理
getProxyInfo # 获取代理详细信息
# 推流代理
addStreamPusherProxy # 添加推流代理
delStreamPusherProxy # 删除推流代理
listStreamPusherProxy # 列出所有推流代理
getProxyPusherInfo # 获取推流代理信息
# FFmpeg 代理
addFFmpegSource # 添加 FFmpeg 拉流
delFFmpegSource # 删除 FFmpeg 拉流
listFFmpegSource # 列出所有 FFmpeg 拉流
```
### 4. RTP/GB28181 类
```
openRtpServer # 创建 RTP 接收端口
closeRtpServer # 关闭 RTP 端口
connectRtpServer # TCP 主动连接模式
listRtpServer # 列出所有 RTP 服务器
getRtpInfo # 获取 RTP 推流信息
updateRtpServerSSRC # 更新 SSRC 过滤
pauseRtpCheck # 暂停超时检查
resumeRtpCheck # 恢复超时检查
```
### 5. RTP 推流类
```
startSendRtp # 主动模式推送 RTP
startSendRtpPassive # 被动模式推送 RTP
startSendRtpTalk # 双向对讲
stopSendRtp # 停止推送 RTP
listRtpSender # 列出 RTP 发送器
```
### 6. 录制类
```
startRecord # 开始录制
stopRecord # 停止录制
isRecording # 检查录制状态
getMp4RecordFile # 获取录像文件列表
deleteRecordDirectory # 删除录像目录
setRecordSpeed # 设置录像播放速度
seekRecordStamp # 设置录像播放位置
startRecordTask # 事件录制(前后录制)
```
### 7. 截图类
```
getSnap # 获取实时截图
deleteSnapDirectory # 删除截图目录
```
### 8. 文件类
```
loadMP4File # 点播 MP4 文件
downloadFile # 下载文件
```
### 9. 系统管理类
```
getApiList # 获取 API 列表
getServerConfig # 获取服务器配置
setServerConfig # 设置服务器配置
restartServer # 重启服务器
getStatistic # 获取统计信息
getThreadsLoad # 获取网络线程负载
getWorkThreadsLoad # 获取后台线程负载
version # 获取版本信息
```
---
## 四、关键流程图
### 流的生命周期
```
┌─────────────────────────────────────────────────────────┐
│ 流的来源 │
├─────────────────────────────────────────────────────────┤
│ 1. 推流: RTMP/RTSP/WebRTC 推流 │
│ 2. 拉流代理: addStreamProxy │
│ 3. FFmpeg 代理: addFFmpegSource │
│ 4. GB28181: openRtpServer + 设备推流 │
│ 5. 点播: loadMP4File │
└─────────────────────────────────────────────────────────┘
┌─────────────────────────────────────────────────────────┐
│ 流在 ZLMediaKit 中 │
├─────────────────────────────────────────────────────────┤
│ - 唯一标识: vhost/app/stream │
│ - 自动协议转换: RTSP/RTMP/HLS/FLV/WebRTC 等 │
│ - 可被多个客户端同时播放 │
│ - 可被录制、截图、转推 │
└─────────────────────────────────────────────────────────┘
┌─────────────────────────────────────────────────────────┐
│ 流的消费 │
├─────────────────────────────────────────────────────────┤
│ 1. 播放: 多协议播放地址 │
│ 2. 录制: startRecord │
│ 3. 截图: getSnap │
│ 4. 转推: addStreamPusherProxy │
│ 5. RTP 推送: startSendRtp │
└─────────────────────────────────────────────────────────┘
┌─────────────────────────────────────────────────────────┐
│ 流的结束 │
├─────────────────────────────────────────────────────────┤
│ 1. 推流端断开 │
│ 2. 主动关闭: close_stream │
│ 3. 无人观看超时(配置决定) │
│ 4. 删除代理: delStreamProxy/delFFmpegSource │
└─────────────────────────────────────────────────────────┘
```
### GB28181 完整流程
```
1. 创建 RTP 服务器
openRtpServer(port=10000, stream_id=camera01)
2. 配置 GB28181 设备推流到 10000 端口
3. 流自动注册为: rtsp://__defaultVhost__/rtp/camera01
4. 查看流信息
getMediaInfo(schema=rtsp, app=rtp, stream=camera01)
5. 获取所有播放地址并播放
- RTSP: rtsp://server:554/rtp/camera01
- RTMP: rtmp://server:1935/rtp/camera01
- HTTP-FLV: http://server/rtp/camera01.live.flv
- HLS: http://server/rtp/camera01/hls.m3u8
6. 录制/截图/转推
startRecord(app=rtp, stream=camera01)
getSnap(url=rtsp://server/rtp/camera01)
addStreamPusherProxy(app=rtp, stream=camera01, dst_url=...)
7. 关闭流
closeRtpServer(stream_id=camera01)
```
---
## 五、常见问题
### Q1: 如何知道流的 stream_id
**A**:
- **推流时**: stream_id 由推流端指定(推流地址的最后一部分)
- **GB28181**: 在 `openRtpServer` 时指定
- **拉流代理**: 在 `addStreamProxy` 时指定
- **查询**: 使用 `getMediaList` 查看所有在线流
### Q2: 流的各种播放地址如何获取?
**A**: 使用 `getMediaInfo` 接口,返回结果包含所有协议的播放地址。
### Q3: 录像文件保存在哪里?
**A**:
- 默认路径在配置文件中设置(通常是 `./www/record`
- 目录结构: `record/vhost/app/stream/日期/时间.mp4`
- 可通过 `getMp4RecordFile` 查询
### Q4: 如何实现多平台推流?
**A**: 使用 `addStreamPusherProxy`,同一个流可以添加多个推流代理(不同 dst_url
### Q5: 拉流代理和 FFmpeg 代理如何选择?
**A**:
- **优先使用拉流代理**: 性能高,资源占用少
- **使用 FFmpeg 代理的场景**:
- 源协议 ZLMediaKit 不支持
- 需要转码
- 需要 FFmpeg 的特殊功能
### Q6: 如何实现按需拉流?
**A**: 配置 `on_play` hook当有人播放时才调用 `addStreamProxy` 拉取源流。
---
## 六、最佳实践
### 1. 流命名规范
```
app: 按业务分类live, record, vod, gb28181
stream: 使用有意义的IDcamera_01, user_123_live
```
### 2. 录制策略
```
- 重要流: 实时录制startRecord
- 事件流: 使用 startRecordTask前后录制
- 定时录制: 通过配置文件设置
```
### 3. 性能优化
```
- 使用拉流代理而非 FFmpeg 代理
- 合理设置录制切片时间
- 使用 HLS 时注意切片数量
- 监控 getThreadsLoad 和 getWorkThreadsLoad
```
### 4. 安全建议
```
- 修改默认 secret
- 启用推流鉴权on_publish hook
- 启用播放鉴权on_play hook
- 限制 API 访问 IP
```
---
## 七、快速参考
### 推流地址格式
```
RTMP: rtmp://server:1935/app/stream
RTSP: rtsp://server:554/app/stream (需要服务器支持 RTSP 推流)
```
### 播放地址格式
```
RTSP: rtsp://server:554/app/stream
RTMP: rtmp://server:1935/app/stream
HTTP-FLV: http://server:80/app/stream.live.flv
WebSocket-FLV: ws://server:80/app/stream.live.flv
HLS: http://server:80/app/stream/hls.m3u8
HTTP-TS: http://server:80/app/stream.live.ts
HTTP-fMP4: http://server:80/app/stream.live.mp4
WebRTC: webrtc://server/app/stream
```
### 常用 API 速查
```bash
# 查看所有流
curl "http://server:80/index/api/getMediaList?secret=xxx"
# 查看流信息
curl "http://server:80/index/api/getMediaInfo?secret=xxx&schema=rtsp&vhost=__defaultVhost__&app=live&stream=test"
# 开始录制
curl "http://server:80/index/api/startRecord?secret=xxx&type=1&vhost=__defaultVhost__&app=live&stream=test"
# 获取截图
curl "http://server:80/index/api/getSnap?secret=xxx&url=rtsp://server/live/test&timeout_sec=10" -o snap.jpg
# 关闭流
curl "http://server:80/index/api/close_stream?secret=xxx&schema=rtsp&vhost=__defaultVhost__&app=live&stream=test"
```