适用场景:在 Windows 开发/测试环境部署 MediaMTX 和 FFmpeg 模拟 RTSP 视频流,并部署 ZLMediaKit 将 RTSP 视频源接入后输出 HTTP-FLV,供 Web 前端通过
flv.js播放。本文结合当前测试链路整理:本地 MP4 → FFmpeg → MediaMTX(RTSP Server)→ ZLMediaKit(RTSP 拉流/转发)→ HTTP-FLV → 播放客户端。
注意: 配置项、API 参数和播放 URL 可能随 ZLMediaKit 版本变化。遇到差异时,以实际发行包的
config.ini、该版本 API 文档及启动日志为准。
1. 目标架构与组件职责
1.1 测试链路
text
本地 MP4
│
▼
FFmpeg(按实时速度读取/推送)
│ RTSP 发布
▼
MediaMTX(提供 RTSP 服务,模拟摄像头)
│ RTSP 拉流
▼
ZLMediaKit(流代理、协议输出)
│ HTTP-FLV
▼
ffplay / VLC / flv.js
1.2 组件职责
| 组件 | 职责 | 是否为最终现场必需 |
|---|---|---|
| FFmpeg | 测试时读取 MP4 并推流 | 否,现场通常由摄像头提供码流 |
| MediaMTX(模拟摄像头) | 测试时充当 RTSP Server、模拟摄像头 | 否,现场摄像头通常直接提供 RTSP |
| ZLMediaKit | 接入、代理、分发媒体流 | 是,若采用该视频网关方案 |
| Vue + flv.js | 浏览器实时视频播放 | 是,若前端选用 HTTP-FLV |
建议: MediaMTX 与 ZLMediaKit 不必长期串联。当前保留 MediaMTX 是为了模拟 RTSP 摄像头、验证 ZLMediaKit 的 RTSP 拉流能力。
2. 端口与网络规划
以下为常见示例端口,实际以 config.ini 为准:
| 用途 | 示例端口 | 说明 |
|---|---|---|
| ZLMediaKit HTTP/HTTP-FLV | 8080 | 浏览器播放及 HTTP API(常见部署) |
| ZLMediaKit HTTP API | 通常与 HTTP 监听端口相同 | 本项目此前测试 API 使用过 8090,请核对配置 |
| ZLMediaKit RTSP | 554 | 若启用,用于 RTSP 服务 |
| ZLMediaKit RTMP | 1935 | 若启用,用于 RTMP 推流/播放 |
| MediaMTX RTSP | 8554 | 当前模拟源示例 |
| MediaMTX WebRTC/HLS 等 | 取决于配置 | 本测试可暂不关注 |
不要仅凭 API 请求中的
Host: 127.0.0.1:8090推断 HTTP-FLV 端口。API 端口与媒体 HTTP 端口应以实际配置为准;某些部署将它们设置为同一个端口。
跨机器测试时,需要:
- 用运行 ZLMediaKit 的机器的局域网 IP ,不能使用另一台机器上的
127.0.0.1。 - Windows 防火墙放行实际使用的 TCP 端口。
- 若 RTSP 使用 UDP RTP,还要处理相应 UDP 端口范围;测试时可优先采用双方兼容的 TCP 传输。
3. Windows 部署 ZLMediaKit
3.1 获取发行包
ZLMediaKit 的 GitHub 仓库并没有专门的 Releases 页面发布预编译二进制包,因此"进入 Releases 找安装包"这一常规方式在本项目上不成立。预编译包实际由作者长期维护在一个固定的 Issue 帖中,按以下步骤获取:
- 打开项目主页
https://github.com/ZLMediaKit/ZLMediaKit。 - 切换到 Issues 标签页。
- 找到编号 #483 的帖子(也可直接访问
https://github.com/ZLMediaKit/ZLMediaKit/issues/483)。 - 在帖内按操作系统与 CPU 架构挑选对应的预编译包;Windows 环境选择 Windows x64 的压缩包。
- 下载压缩包,解压至固定目录,例如
D:\Media\ZLMediaKit\,并保持目录结构完整。
解压后的目录层级应大致如下(实际内容以所下载的包为准):
text
D:\Media\ZLMediaKit\
MediaServer.exe
config.ini
*.dll(配套依赖库)
www\
...
MediaServer.exe 必须与配套 DLL、config.ini 保持在同一目录层级,不要单独把 exe 拷出使用。
下载完成后,记录包内版本号与下载日期;不要将来源不明的二进制用于生产环境,使用前先做安全软件扫描。不同构建包的配置项与默认端口可能不同,后续步骤一律以包内 config.ini 和启动日志为准。
若该 Issue 链接失效或帖子结构发生变化,可在 Issues 中搜索"编译包""binary"等关键词定位新的下载页,或按官方文档自行编译。跨平台包不可混用:Linux 包无法在 Windows 上运行,同时注意区分 x64 与 arm64 架构。
3.2 首次启动
在解压目录打开 cmd 命令行终端并运行:
cmd
MediaServer.exe
观察启动日志,确认服务监听端口、配置文件加载情况及是否有端口占用错误。
若双击窗口一闪而过,建议从 cmd/PowerShell 启动以保留日志。
3.3 确认配置文件
检查发行包中的 config.ini,重点查看以下区段(字段名称以当前版本为准):
ini
[api]
# API 密钥;实际值以本机配置为准
secret=请使用本机配置中的值
[http]
# HTTP 监听端口示例
port=8080
# 跨域选项以当前版本配置为准
allow_cross_domains=1
[protocol]
# 核对 FLV 输出是否启用;字段以当前版本为准
enable_flv=1
说明:
- 上面是核对示意,不要把示例密钥或不被当前版本识别的字段直接照抄。
allow_cross_domains不是解决所有浏览器播放问题的万能开关。若前端跨域请求受限,应结合实际响应头、浏览器控制台和部署方式确认。- 修改配置后按该版本要求重启服务,确保新配置已加载。
- 管理 API 的
secret属于敏感凭据,不要写入前端代码、公开日志或提交到代码仓库。
4. 准备 RTSP 测试源
本指引采用 FFmpeg → MediaMTX → RTSP 的方式,避免 VLC RTSP Server 在 RTSP SETUP 阶段出现 461 Unsupported transport 等兼容性问题。
4.1 Windows 下部署 FFmpeg
FFmpeg 在本链路中承担两个角色:向 MediaMTX 发布测试流,以及作为独立客户端验证源与 ZLMediaKit 输出。Windows 下推荐使用预编译包,无需自行编译。
1. 获取预编译包
从可信构建源下载静态构建版本:
- gyan.dev 提供的 Windows Release 构建(通常分为 essentials 与 full 两档,测试用途 essentials 即可满足推流与转码需求)。地址:
https://www.gyan.dev/ffmpeg/builds/#release-builds
下载时核对架构(x64 与当前系统一致)、版本号与发布日期,记录构建来源以便复现。不要使用来源不明的二进制文件。
2. 解压到固定目录
将压缩包解压至固定路径,例如:
text
D:\Media\ffmpeg\
bin\
ffmpeg.exe
ffplay.exe
ffprobe.exe
...
后续配置以 bin 目录为准,不要把整个解压目录混入环境变量。路径中尽量避免中文与空格,减少命令行解析与脚本调用问题。
3. 加入系统环境变量 Path
操作路径:
- 右键「此电脑」→「属性」→「高级系统设置」→「环境变量」。
- 在「系统变量」区域选中
Path,点击「编辑」。 - 点击「新建」,填入
bin目录的绝对路径,例如:
text
D:\Media\ffmpeg\bin
- 逐级点击「确定」保存。仅关闭对话框未保存时,变更不会生效。
4. 重新打开终端
环境变量在终端启动时读取,已打开的 cmd/PowerShell 不会自动感知变更。必须关闭并重新打开终端,再执行后续命令。
5. 验证
cmd
ffmpeg -version
ffplay -version
两条命令均应输出版本信息与构建配置。若 ffmpeg 可用而 ffplay 不可用,说明 bin 目录不完整或 Path 指向了错误位置。
6. 多版本共存与冲突排查
机器上存在多个 FFmpeg 副本时,实际生效的版本由 Path 中的顺序决定。排查方式:
cmd
where ffmpeg
该命令按 Path 顺序列出所有匹配项,第一条即为实际执行路径。若结果指向旧版本或其他目录,调整 Path 顺序或移除冗余条目。
7. 常见错误
'ffmpeg' 不是内部或外部命令:Path 未包含bin目录,或修改后未重新打开终端。- Path 中含中文或空格路径:部分脚本与旧版工具解析异常,建议改用纯英文、无空格路径。
- 误把整个解压目录而非
bin加入 Path:命令行无法直接定位可执行文件,必须指向bin。
4.2 Windows 下载与安装 MediaMTX
- 打开下载页:
text
https://github.com/bluenviron/mediamtx/releases
- 在最新版本的 Assets 列表中找到 Windows 平台的压缩包:普通 x64 机器选
windows_amd64.zip,若看不到 Assets 列表,点击展开即可。 - 解压到固定目录,例如
D:\Media\MediaMTX\,目录结构大致如下:
text
D:\Media\MediaMTX\
├── mediamtx.exe
├── mediamtx.yml
├── LICENSE
└── ...(其余文件以所下版本为准)
- MediaMTX 不提供安装程序,解压即可运行,无需加入 Path 环境变量,在自身目录下执行或指定配置路径即可。
mediamtx.exe与mediamtx.yml必须保持在同一目录,不要只把 exe 单独拷走。 - 记录下载的版本号(如 v1.x.x)。不同版本的配置文件字段可能有差异,后续以包内
mediamtx.yml与实际日志为准。
4.3 配置 MediaMTX
结论先行:配置文件必须在启动前改好并保存。MediaMTX 只在启动时读取配置一次,运行中修改不生效,改完需重启。配置文件是同目录下的 mediamtx.yml,最小配置示例:
yaml
rtspAddress: :8554
paths:
stream:
两项配置的作用:
rtspAddress决定 RTSP 监听端口,示例为8554。paths下要预先声明测试路径stream,该名称必须与后面 FFmpeg 推流地址中的路径名完全一致,否则发布会失败或拉流 404。
补充两点:YAML 缩进必须用空格,不能用 Tab;默认配置通常不启用鉴权,仅适用于本机或隔离测试网络。
4.4 启动 MediaMTX 并确认就绪
Windows 下推荐在 cmd 中前台运行,便于直接看到日志:
- 打开
cmd。 - 切换到 MediaMTX 所在目录:
bat
cd /d D:\Media\MediaMTX
- 执行:
bat
mediamtx.exe
- 保持窗口不关闭,关闭窗口即停止服务。
日志出现监听就绪记录,例如 listener started 或 [RTSP] listener opened on :8554,且窗口持续运行,即表示服务已就绪;此时还没有任何流属于正常现象。
后续步骤使用的示例 RTSP 地址:
text
rtsp://127.0.0.1:8554/stream
4.5 FFmpeg 推送 MP4
1. 准备并核对素材
示例文件:
text
D:\video\sample.mp4
先用 ffprobe 核对编码、分辨率与帧率:
cmd
ffprobe -v error -show_entries stream=codec_name,width,height,r_frame_rate -of default=noprint_wrappers=1 "D:\video\sample.mp4"
若视频为 H.264、音频为 AAC,且封装与 MediaMTX 兼容,可直接使用 -c copy 免转码推送。源编码不兼容或像素格式不受支持时,保留转码参数更稳妥。
- 起推命令
向 MediaMTX 发布(发布 URL 应与 paths 及鉴权配置一致)。以下命令已经实际测试通过:
cmd
ffmpeg -re -stream_loop -1 -i "D:\soft\RTSP_Server\sample.mp4" ^
-c:v libx264 -preset ultrafast -tune zerolatency ^
-g 30 -r 25 ^
-b:v 1000k -maxrate 1000k -bufsize 2000k ^
-c:a aac ^
-f rtsp -rtsp_transport tcp -muxdelay 0.1 ^
rtsp://127.0.0.1:8554/stream
等价的一行写法如下(去掉 ^ 后与原命令等效):
cmd
ffmpeg -re -stream_loop -1 -i "D:\soft\RTSP_Server\sample.mp4" -c:v libx264 -preset ultrafast -tune zerolatency -g 30 -r 25 -b:v 1000k -maxrate 1000k -bufsize 2000k -c:a aac -f rtsp -rtsp_transport tcp -muxdelay 0.1 rtsp://127.0.0.1:8554/stream
注意:^ 只在 cmd 中有效;在 PowerShell 中应改用反引号,或直接写成一行执行。输入路径务必用双引号包裹------路径含空格时是必需的,即使不含空格也建议始终加引号,以免特殊字符导致解析错误。
- 参数解释
| 参数 | 作用 | 使用要点 |
|---|---|---|
-re |
按接近实时的速度读取文件 | 避免瞬时推完;文件推流时必加 |
-stream_loop -1 |
无限循环输入 | 不需要循环时删除 |
-i |
指定输入文件路径 | 路径用双引号包裹,含空格时必需 |
-c:v libx264 |
视频转码为 H.264 | 兼容性通常更易控制,但增加 CPU 消耗 |
-preset ultrafast |
使用最快的编码预设 | 压缩率换速度,明显降低编码延迟 |
-tune zerolatency |
面向低延迟场景调优 | 关闭前瞻与 B 帧,进一步缩短编码延迟 |
-g 30 |
设置关键帧间隔 | 配合 25fps 即约 1.2 秒一个关键帧;求更低延迟可减小该值,但码率会上升 |
-r 25 |
固定输出帧率 | 会强制帧率,源若为 30fps 会出现丢帧或重复帧 |
-b:v 1000k |
设置视频目标码率 | 画面波动时码率仍向该值靠拢 |
-maxrate 1000k |
限制视频码率上限 | 与 -bufsize 配合约束瞬时峰值 |
-bufsize 2000k |
设置码率控制缓冲 | 2000k 相当于 2 秒缓冲上限 |
-c:a aac |
音频转码为 AAC | 未指定码率时使用默认值,需控制带宽可补 -b:a 128k |
-f rtsp |
指定输出封装为 RTSP | 与输出 URL 协议保持一致 |
-rtsp_transport tcp |
FFmpeg 与 RTSP 服务之间的传输方式 | 不代表拉流端也使用同一方式 |
-muxdelay 0.1 |
缩短 RTSP 输出侧封装缓冲 | 只影响输出侧封装,不改变编码延迟 |
| 输出 URL | 发布地址 | 路径名 stream 对应 MediaMTX paths 中的条目,须一致 |
可选补充
当前命令未指定 -pix_fmt yuv420p。若源本身是 yuv420p 且播放正常,可省略;一旦出现花屏、黑屏或播放器不兼容,优先补上该参数。
另外,若源已是 H.264 + AAC 且只需转发,可评估用 -c copy 降低 CPU 占用,但该方式无法通过 -g、-r 控制关键帧与帧率。
4. 推流成功的判定依据
- FFmpeg 控制台持续输出
frame=、fps=,且speed≈1x,说明按实时节奏稳定推送。 - 无 4xx/5xx 报错与连接中断日志。
- MediaMTX 日志出现 publish/publisher 就绪记录。
- 用
ffprobe或ffplay从另一端拉流成功:
bat
ffprobe -rtsp_transport tcp rtsp://127.0.0.1:8554/stream
5. 常见失败原因
Connection refused:MediaMTX 未启动或端口未监听。- 404/路径未配置:发布的路径名与
paths中的条目不一致。 461 Unsupported transport:传输方式协商不兼容,优先改用 TCP 并核对服务端支持情况。- 断流后 MediaMTX 侧流消失:源输入结束或循环参数缺失。
- 编码不受支持:源编码或像素格式与播放链路不兼容,需转码。
- 防火墙拦截:跨机器推流时端口未放行。
6. 后台长期运行的两种方式
- 另开一个终端窗口保持前台运行,便于随时观察日志与中断排查。
- 启动时追加
-report,FFmpeg 会在工作目录生成诊断报告,便于事后分析失败原因。
4.6 先验证 RTSP 源
在源机器执行:
bat
ffplay -rtsp_transport tcp rtsp://127.0.0.1:8554/stream
也可以在 VLC 中选择"媒体 → 打开网络串流",输入 RTSP 地址。
跨机器测试时,将 127.0.0.1 换成 MediaMTX 所在机器的局域网 IP,例如:
text
rtsp://192.168.1.100:8554/stream
验证时应确认画面持续、无花屏,且推流端与拉流端同时存在。必须先确认源 RTSP 可以稳定播放,再接入 ZLMediaKit。
5. 让 ZLMediaKit 拉取 RTSP 源
5.1 使用 addStreamProxy
ZLMediaKit 的 addStreamProxy API 可创建拉流代理。常见参数包括:
secret:API 密钥vhost:虚拟主机,常见为 __defaultVhost__app:应用名,例如livestream:代理流名,例如testurl:源 RTSP 地址
在浏览器、Postman 或其他 HTTP 工具中调用。为避免 URL 特殊字符导致解析问题,建议在 Postman 中使用 Params 参数表或正确进行 URL 编码,不要把凭据暴露给无关人员。
示例(仅演示参数结构,请替换地址、端口和密钥后直接在浏览器访问):
text
http://127.0.0.1:8090/index/api/addStreamProxy?secret=YOUR_SECRET&vhost=__defaultVhost__&app=live&stream=test&url=rtsp%3A%2F%2F127.0.0.1%3A8554%2Fstream&enable_rtsp=1&enable_rtmp=1&enable_hls=1
把该地址粘贴到浏览器地址栏回车,即可发起请求。浏览器会自动处理编码,也可手写未编码形式(url=rtsp://127.0.0.1:8554/stream),但部分工具不编码会截断参数。返回 JSON 中 code 为 0 表示代理创建成功。
若不想处理编码或参数较多,可改用 POST 并在 body 中以 JSON 传参(Content-Type: application/json)。
| 参数 | 示例值 | 说明 |
|---|---|---|
secret |
YOUR_SECRET |
API 密钥,取自本机 config.ini,勿提交到代码库 |
vhost |
__ defaultVhost__ |
虚拟主机,默认值即可 |
app |
live |
应用名,与后续播放地址中的 app 一致 |
stream |
test |
代理流名,与播放地址中的 stream 一致 |
url |
rtsp://127.0.0.1:8554/stream |
源 RTSP 地址,跨机器时填源主机可达的局域网 IP |
enable_rtsp |
1 |
是否输出 RTSP 协议 |
enable_rtmp |
1 |
是否输出 RTMP 协议 |
enable_hls |
1 |
是否输出 HLS;FLV 输出不依赖这几项,测试 HTTP-FLV 时无需为它单独开启无关协议 |
若当前版本不识别其中某个参数,接口通常会忽略而非报错,因此创建成功后应通过 listStreamProxy 核对实际生效的 app/stream 与源地址(见 7.1)。
注意:
8090 只是当前示例中使用过的 API 端口。请先核对本机监听配置。enable_rtsp、enable_rtmp、enable_hls等参数是否有效及其含义,需核对当前发行版 API 文档。测试 HTTP-FLV 时不必为了 FLV 特意开启无关协议。- RTSP 源位于另一台机器时,
url应填写源机器可达的局域网地址。 - API 请求的
url参数中若包含&、?、#、用户名密码等特殊字符,应正确编码;不要随意把rtsp_transport=udp追加进源 URL。拉流传输模式的控制方式应按所用版本支持的配置/API 处理。 - 如果需要取消代理,使用当前版本对应的关闭/删除代理 API,并先核验参数。
5.2 成功标准
成功响应通常包含 code: 0。随后在 ZLMediaKit 控制台观察代理拉流成功、轨道就绪或媒体注册日志。
此前测试中出现过类似日志:
text
play rtsp://127.0.0.1:8554/stream success
All track ready
媒体注册:fmp4://__defaultVhost__/live/test
这说明 ZLMediaKit 已经成功拉到源流并识别到轨道。**日志注册为 fmp4 不代表只能播放 fMP4,也不代表 HTTP-FLV 已经完成端到端验证。**还需实际请求 FLV 播放地址。
6. 确定 HTTP-FLV 播放地址
addStreamProxy 返回成功后,先按规则拼出播放地址;地址是否正确看 6.1,取错地址是 404 与空响应的常见原因。
6.1 地址构成与参数来源
text
http://<ZLM主机IP>:<HTTP端口>/<app>/<stream>.live.flv
| 组成部分 | 取值来源 | 注意 |
|---|---|---|
| ZLM 主机 IP | 运行 ZLMediaKit 的机器地址 | 本机测试用 127.0.0.1,跨机器用局域网 IP |
| HTTP 端口 | config.ini 中 [http] 段的 port |
不要用 API 端口(如 8090)推断媒体端口,二者可能不同 |
| app / stream | 调用 addStreamProxy 时传入的参数 |
逐字一致、含大小写;不能用源 RTSP 路径名代替代理流名 |
| 后缀 | 固定写法 | 常见为 .live.flv,部分版本也接受 .flv,以当前版本实际行为为准 |
本机示例地址:
text
http://127.0.0.1:8080/live/test.live.flv
跨机器访问时把 127.0.0.1 替换为运行 ZLMediaKit 机器的局域网 IP,其余不变。此外还需确认 [protocol] 段 enable_flv 已开启,否则地址正确也不会输出 FLV。
6.2 常见取错地址的情形
- 用 API 端口拼接 FLV 地址。
- 用源 RTSP 路径名代替代理的
stream。 - 大小写不一致,或
app与stream位置颠倒。 - 漏写或错写
.live.flv后缀。 - 跨机器测试仍使用
127.0.0.1。 - FLV 未启用或代理已被删除。
7. 验证与测试 HTTP-FLV
地址拼好后有两条互补的验证路径------API 查状态,播放器看画面。
7.1 用 API 验证
除播放器外也可直接调管理 API,便于脚本化与远程确认。排查前先分清:listStreamProxy 与 getMediaList 查的是两张不同的表。
| 维度 | listStreamProxy | getMediaList |
|---|---|---|
| 对应对象 | addStreamProxy 创建的拉流代理任务 | 已发布的 MediaSource |
| 存在条件 | 注册成功即存在,与是否拉到数据无关 | 只有真正建立媒体源才存在,源断/重连时消失 |
| 粒度 | 一路一条 | 同一路按 schema(ts/fmp4/rtsp/rtmp)多条 |
| 用途 | 判断代理是否注册成功、ZLM 是否正在自重连 | 判断输出是否就绪、观看数、码率、存活时长 |
请求方式很直接:两个接口路径 GET /index/api/listStreamProxy 与 GET /index/api/getMediaList,参数放 URL 查询串(也可 POST + JSON),secret 必填,端口用 API 端口。示例地址:
text
http://127.0.0.1:8090/index/api/listStreamProxy?secret=YOUR_SECRET
http://127.0.0.1:8090/index/api/getMediaList?secret=YOUR_SECRET&app=live&stream=test&schema=flv
判断口径按三条走:无记录说明代理未创建或已删除;有记录但 status_str 异常或 rePullCount 持续增长说明拉流失败或在重连,回到第 9 章排查;媒体源在但 readerCount 为 0 说明无人观看,用 ffplay 主动拉流验证。
7.2 ffplay(首选)
在安装了 FFmpeg 的机器执行:
cmd
ffplay http://127.0.0.1:8080/live/test.live.flv
跨机器时把 127.0.0.1 换成运行 ZLMediaKit 机器的局域网 IP。预期出现播放窗口且画面持续更新,即视为通过。
7.3 其他方式
VLC 的路径是:媒体 → 打开网络串流 → 输入 FLV 地址 → 播放。其支持情况受版本与 FLV 封装影响,VLC 失败而 ffplay 成功时不要判定 ZLMediaKit 故障。浏览器直接打开 URL 只能作 HTTP 层观察;Chrome 原生 <video> 通常不支持 FLV,浏览器播放需用 flv.js 等方案。
7.4 验证顺序
建议按 API → ffplay → VLC → 前端 推进,跳步容易误判。
8. Vue + Element Plus 前端接入检查
当命令行/VLC 已经验证通过后,再接前端。
8.1 安装依赖
bash
npm install flv.js
8.2 前端播放逻辑要点
在 Vue 组件中:
- 判断
flvjs.isSupported()。 - 创建
flvjs.createPlayer({ type: 'flv', isLive: true, url })。 attachMediaElement(videoElement)。load()后按浏览器自动播放策略调用play()。- 组件卸载时执行
pause()、unload()、detachMediaElement()、destroy(),清理监听器和实例。 - 处理
error、断流重连、页面切换和重复创建播放器等情况。 - 直播播放通常设置
muted更容易满足浏览器自动播放限制;需要声音时提供用户交互开启声音。 - 多摄像头场景为每路流管理独立播放器实例,避免共享实例和资源泄漏。
8.3 前端跨域与混合内容
如果 Vue 与 ZLMediaKit 的协议、域名或端口不同,浏览器会按跨源规则处理请求。
排查顺序:
- 打开浏览器开发者工具 → Network,查看 FLV 请求是否发出、状态码和响应头。
- 查看 Console 是否报 CORS、Mixed Content、MIME 或解码错误。
- 核实 ZLMediaKit 当前版本的跨域配置与响应头行为。
- 若页面使用 HTTPS,而媒体地址为 HTTP,浏览器可能阻止混合内容。生产环境应考虑 HTTPS 反向代理或统一入口。
- CORS 不是身份认证机制;不要把开放跨域当作访问控制。
9. 常见故障排查
9.1 DESCRIBE 500 Internal Server Error
含义:ZLMediaKit 发起 RTSP DESCRIBE 时失败,未取得可用 SDP。
检查:
- VLC/MediaMTX 的 RTSP 源是否仍在推流,文件是否已播放结束。
- 直接用
ffplay或 VLC 验证源 RTSP。 - 核对路径、端口、认证和源服务日志。
- 确认源服务在代理建立期间没有退出。
9.2 SETUP 461 Unsupported Transport
含义:RTSP 服务端拒绝了客户端请求的传输方式,常见于客户端与服务端的 RTP 传输协商不兼容。
排查:
- 确认源服务是否支持 RTP over TCP、UDP 或两者。
- 用 ffplay 分别验证服务端实际支持的方式,例如执行:
bat
ffplay -rtsp_transport tcp rtsp://127.0.0.1:8554/stream
若需测试 UDP,可按 FFmpeg 版本语法调整为 -rtsp_transport udp。
- 注意:FFmpeg 播放源时指定的 transport,不会自动改变 ZLMediaKit 代理拉流的 transport。
- 核对 ZLMediaKit 版本支持的拉流传输配置/API;不要未经验证就把
rtsp_transport=udp拼进 RTSP URL。 - VLC 作为 RTSP Server 出现兼容问题时,可用 FFmpeg 发布至 MediaMTX,再由 ZLMediaKit 拉流,便于排除 VLC 服务端差异。
9.3 API 返回成功,但 HTTP-FLV 播放失败
逐项确认:
- 代理流仍在线,未因源停止而注销。
- HTTP-FLV 端口是否正确。
- URL 中
app/stream是否与创建代理时完全一致。 - FLV 输出是否在当前版本中启用。
- 用 ffplay 测试同一个 URL。
- 检查 ZLMediaKit 日志是否收到
.flv请求、是否出现 mux/编码错误。 - 检查视频编码是否为浏览器/播放器支持的格式;FLV 容器并不意味着任意编码都可播放。
9.4 本机可播,局域网其他机器不可播
- 使用 ZLMediaKit 主机的 LAN IP,而不是
127.0.0.1。 - 确认服务监听在可供局域网访问的网卡/地址,而非仅回环接口。
- 检查 Windows 防火墙入站规则。
- 从客户端测试端口连通性,例如 PowerShell:
powershell
Test-NetConnection 192.168.1.100 -Port 8080
- 检查客户端与服务端是否处于可互通网段/VLAN。
- 如使用反向代理,确认代理支持长连接/流式响应,不会缓冲整段内容或过早超时。
9.5 有画面但延迟大、卡顿或音画异常
检查:
- 源端编码参数、帧率、码率和关键帧间隔(GOP)。
- FFmpeg 是否转码、机器 CPU 占用。
- 网络丢包、抖动与客户端缓冲。
- ZLMediaKit 与 flv.js 的延迟/缓冲配置。
- 多个客户端同时播放时的并发带宽与服务资源。
- RTSP 拉流和浏览器播放各环节的时间戳连续性。
10. Windows 防火墙与局域网验证
以管理员身份按需建立入站规则。以下仅为示例,端口按实际情况替换:
powershell
New-NetFirewallRule -DisplayName "ZLMediaKit HTTP" `
-Direction Inbound -Action Allow -Protocol TCP -LocalPort 8080
若 API 与媒体服务分端口,应分别评估是否需要对客户端开放。不建议将管理 API 端口暴露给普通终端或不可信网络。
在客户端执行:
powershell
Test-NetConnection 192.168.1.100 -Port 8080
端口连通只是网络层检查,不代表 FLV 播放链路已成功。
11. 面向工业 AI 视频系统的建议
结合实时视频与模型分类结果的业务目标,建议分层:
text
摄像头 RTSP
├── ZLMediaKit → HTTP-FLV → Vue 播放组件
└── AI 推理服务 → 识别事件/结果 → ASP.NET Core → Vue
历史录像:
录像文件/存储 → ASP.NET Core 或专用媒体服务 → HTTP Range/合适的回放协议 → 前端
建议:
- ZLMediaKit 负责实时流接入和分发,不承担业务识别结果的权威存储。
- ASP.NET Core 管理摄像头、播放授权、业务配置和识别结果查询。
- 实时播放与识别结果叠加,需要先定义时间基准和延迟补偿机制;仅把结果经 WebSocket 推到前端,并不能自动保证与当前画面同步。
- HTTP-FLV 可用于验证/满足一定延迟要求的浏览器播放;若未来要求更低延迟、双向交互或特定网络适应性,再评估 WebRTC,需结合终端、网络和运维成本做实测。
12. 建议的验收清单
12.1 环境与源端
- ZLMediaKit 正常启动,无端口占用/配置错误
- MediaMTX 正常运行(测试阶段)
- FFmpeg 持续发布,源 RTSP 可由另一台机器访问
- RTSP 源地址、认证、传输方式已记录
12.2 ZLMediaKit
- addStreamProxy 返回成功
- 日志确认拉流成功、轨道就绪
- listStreamProxy 能查到该路代理,status_str 正常且 rePullCount 未持续增长
- getMediaList 能查到对应 app/stream 的媒体源,schema 中包含所需输出协议且 aliveSecond 正常增长
- HTTP 端口、FLV 输出配置与播放 URL 已确认
12.3 播放与网络
- ffplay 可播放 HTTP-FLV
- VLC(可选)可播放
- 局域网另一台机器可以访问
- Windows 防火墙规则符合最小开放原则
- Vue + flv.js 播放、销毁、断线重连正常
- 浏览器无 CORS、Mixed Content 或解码错误
12.4 生产准备
- RTSP 凭据和 ZLMediaKit API 密钥未泄露
- 播放权限、网络隔离和访问日志有设计
- 多路流命名、资源上限、断流告警和自动恢复有设计
- 历史录像与识别事件时间轴方案已验证
- 已使用目标现场摄像头完成兼容性、延迟和稳定性测试
13. 快速操作备忘
- 启动 MediaMTX。
- FFmpeg 将 MP4 按实时速度推送到 MediaMTX 的 RTSP 路径。
- 用
ffplay -rtsp_transport tcp rtsp://<源主机>:8554/stream验证源。 - 启动 ZLMediaKit,核对 API 端口、HTTP 端口和 API 密钥。
- 调用
addStreamProxy,设置app=live、stream=test、url=rtsp://<源主机>:8554/stream。 - 确认拉流成功、轨道就绪。
- 使用
ffplay http://<ZLM主机>:<HTTP端口>/live/test.live.flv验证。 - 再用 VLC、局域网客户端和 Vue + flv.js 测试。
- 记录版本、配置、源地址、播放地址、端口和排错结果,便于复现。