# 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: 使用有意义的ID(camera_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" ```