Windows 用本地 MP4 文件搭建 RTSP/HTTP-FLV 播放环境指引

9 阅读24分钟

适用场景:在 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 测试链路

本地 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-FLV8080浏览器播放及 HTTP API(常见部署)
ZLMediaKit HTTP API通常与 HTTP 监听端口相同本项目此前测试 API 使用过 8090,请核对配置
ZLMediaKit RTSP554若启用,用于 RTSP 服务
ZLMediaKit RTMP1935若启用,用于 RTMP 推流/播放
MediaMTX RTSP8554当前模拟源示例
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 帖中,按以下步骤获取:

  1. 打开项目主页 https://github.com/ZLMediaKit/ZLMediaKit。
  2. 切换到 Issues 标签页。
  3. 找到编号 #483 的帖子(也可直接访问 https://github.com/ZLMediaKit/ZLMediaKit/issues/483)。
  4. 在帖内按操作系统与 CPU 架构挑选对应的预编译包;Windows 环境选择 Windows x64 的压缩包。
  5. 下载压缩包,解压至固定目录,例如 D:\Media\ZLMediaKit\,并保持目录结构完整。

解压后的目录层级应大致如下(实际内容以所下载的包为准):

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 命令行终端并运行:

MediaServer.exe

观察启动日志,确认服务监听端口、配置文件加载情况及是否有端口占用错误。

若双击窗口一闪而过,建议从 cmd/PowerShell 启动以保留日志。

3.3 确认配置文件

检查发行包中的 config.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. 解压到固定目录

将压缩包解压至固定路径,例如:

D:\Media\ffmpeg\
bin\
ffmpeg.exe
ffplay.exe
ffprobe.exe
...

后续配置以 bin 目录为准,不要把整个解压目录混入环境变量。路径中尽量避免中文与空格,减少命令行解析与脚本调用问题。

3. 加入系统环境变量 Path

操作路径:

  1. 右键「此电脑」→「属性」→「高级系统设置」→「环境变量」。
  2. 在「系统变量」区域选中 Path,点击「编辑」。
  3. 点击「新建」,填入 bin 目录的绝对路径,例如:
D:\Media\ffmpeg\bin
  1. 逐级点击「确定」保存。仅关闭对话框未保存时,变更不会生效。

4. 重新打开终端

环境变量在终端启动时读取,已打开的 cmd/PowerShell 不会自动感知变更。必须关闭并重新打开终端,再执行后续命令。

5. 验证

ffmpeg -version
ffplay -version

两条命令均应输出版本信息与构建配置。若 ffmpeg 可用而 ffplay 不可用,说明 bin 目录不完整或 Path 指向了错误位置。

6. 多版本共存与冲突排查

机器上存在多个 FFmpeg 副本时,实际生效的版本由 Path 中的顺序决定。排查方式:

where ffmpeg

该命令按 Path 顺序列出所有匹配项,第一条即为实际执行路径。若结果指向旧版本或其他目录,调整 Path 顺序或移除冗余条目。

7. 常见错误

  • 'ffmpeg' 不是内部或外部命令:Path 未包含 bin 目录,或修改后未重新打开终端。
  • Path 中含中文或空格路径:部分脚本与旧版工具解析异常,建议改用纯英文、无空格路径。
  • 误把整个解压目录而非 bin 加入 Path:命令行无法直接定位可执行文件,必须指向 bin。

4.2 Windows 下载与安装 MediaMTX

  1. 打开下载页:
https://github.com/bluenviron/mediamtx/releases
  1. 在最新版本的 Assets 列表中找到 Windows 平台的压缩包:普通 x64 机器选 windows_amd64.zip,若看不到 Assets 列表,点击展开即可。
  2. 解压到固定目录,例如 D:\Media\MediaMTX\,目录结构大致如下:
D:\Media\MediaMTX\
├── mediamtx.exe
├── mediamtx.yml
├── LICENSE
└── ...(其余文件以所下版本为准)
  1. MediaMTX 不提供安装程序,解压即可运行,无需加入 Path 环境变量,在自身目录下执行或指定配置路径即可。mediamtx.exe 与 mediamtx.yml 必须保持在同一目录,不要只把 exe 单独拷走。
  2. 记录下载的版本号(如 v1.x.x)。不同版本的配置文件字段可能有差异,后续以包内 mediamtx.yml 与实际日志为准。

4.3 配置 MediaMTX

结论先行:配置文件必须在启动前改好并保存。MediaMTX 只在启动时读取配置一次,运行中修改不生效,改完需重启。配置文件是同目录下的 mediamtx.yml,最小配置示例:

rtspAddress: :8554
paths:
stream:

两项配置的作用:

  • rtspAddress 决定 RTSP 监听端口,示例为 8554。
  • paths 下要预先声明测试路径 stream,该名称必须与后面 FFmpeg 推流地址中的路径名完全一致,否则发布会失败或拉流 404。

补充两点:YAML 缩进必须用空格,不能用 Tab;默认配置通常不启用鉴权,仅适用于本机或隔离测试网络。

4.4 启动 MediaMTX 并确认就绪

Windows 下推荐在 cmd 中前台运行,便于直接看到日志:

  1. 打开 cmd。
  2. 切换到 MediaMTX 所在目录:
cd /d D:\Media\MediaMTX
  1. 执行:
mediamtx.exe
  1. 保持窗口不关闭,关闭窗口即停止服务。

日志出现监听就绪记录,例如 listener started 或 [RTSP] listener opened on :8554,且窗口持续运行,即表示服务已就绪;此时还没有任何流属于正常现象。

后续步骤使用的示例 RTSP 地址:

rtsp://127.0.0.1:8554/stream

4.5 FFmpeg 推送 MP4

1. 准备并核对素材

示例文件:

D:\video\sample.mp4

先用 ffprobe 核对编码、分辨率与帧率:

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 免转码推送。源编码不兼容或像素格式不受支持时,保留转码参数更稳妥。

2. 起推命令

向 MediaMTX 发布(发布 URL 应与 paths 及鉴权配置一致)。以下命令已经实际测试通过:

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

等价的一行写法如下(去掉 ^ 后与原命令等效):

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 中应改用反引号,或直接写成一行执行。输入路径务必用双引号包裹——路径含空格时是必需的,即使不含空格也建议始终加引号,以免特殊字符导致解析错误。

3. 参数解释

参数作用使用要点
-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 tcpFFmpeg 与 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 从另一端拉流成功:
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 源

在源机器执行:

ffplay -rtsp_transport tcp rtsp://127.0.0.1:8554/stream

也可以在 VLC 中选择“媒体 → 打开网络串流”,输入 RTSP 地址。

跨机器测试时,将 127.0.0.1 换成 MediaMTX 所在机器的局域网 IP,例如:

rtsp://192.168.1.100:8554/stream

验证时应确认画面持续、无花屏,且推流端与拉流端同时存在。必须先确认源 RTSP 可以稳定播放,再接入 ZLMediaKit。


5. 让 ZLMediaKit 拉取 RTSP 源

5.1 使用 addStreamProxy

ZLMediaKit 的 addStreamProxy API 可创建拉流代理。常见参数包括:

  • secret:API 密钥
  • vhost:虚拟主机,常见为 __defaultVhost__
  • app:应用名,例如 live
  • stream:代理流名,例如 test
  • url:源 RTSP 地址

在浏览器、Postman 或其他 HTTP 工具中调用。为避免 URL 特殊字符导致解析问题,建议在 Postman 中使用 Params 参数表或正确进行 URL 编码,不要把凭据暴露给无关人员。

示例(仅演示参数结构,请替换地址、端口和密钥后直接在浏览器访问):

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)。

参数示例值说明
secretYOUR_SECRETAPI 密钥,取自本机 config.ini,勿提交到代码库
vhost__defaultVhost__虚拟主机,默认值即可
applive应用名,与后续播放地址中的 app 一致
streamtest代理流名,与播放地址中的 stream 一致
urlrtsp://127.0.0.1:8554/stream源 RTSP 地址,跨机器时填源主机可达的局域网 IP
enable_rtsp1是否输出 RTSP 协议
enable_rtmp1是否输出 RTMP 协议
enable_hls1是否输出 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 控制台观察代理拉流成功、轨道就绪或媒体注册日志。

此前测试中出现过类似日志:

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 地址构成与参数来源

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,以当前版本实际行为为准

本机示例地址:

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 查的是两张不同的表。

维度listStreamProxygetMediaList
对应对象addStreamProxy 创建的拉流代理任务已发布的 MediaSource
存在条件注册成功即存在,与是否拉到数据无关只有真正建立媒体源才存在,源断/重连时消失
粒度一路一条同一路按 schema(ts/fmp4/rtsp/rtmp)多条
用途判断代理是否注册成功、ZLM 是否正在自重连判断输出是否就绪、观看数、码率、存活时长

请求方式很直接:两个接口路径 GET /index/api/listStreamProxy 与 GET /index/api/getMediaList,参数放 URL 查询串(也可 POST + JSON),secret 必填,端口用 API 端口。示例地址:

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 的机器执行:

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 安装依赖

npm install flv.js

8.2 前端播放逻辑要点

在 Vue 组件中:

  1. 判断 flvjs.isSupported()。
  2. 创建 flvjs.createPlayer({ type: 'flv', isLive: true, url })。
  3. attachMediaElement(videoElement)。
  4. load() 后按浏览器自动播放策略调用 play()。
  5. 组件卸载时执行 pause()、unload()、detachMediaElement()、destroy(),清理监听器和实例。
  6. 处理 error、断流重连、页面切换和重复创建播放器等情况。
  7. 直播播放通常设置 muted 更容易满足浏览器自动播放限制;需要声音时提供用户交互开启声音。
  8. 多摄像头场景为每路流管理独立播放器实例,避免共享实例和资源泄漏。

8.3 前端跨域与混合内容

如果 Vue 与 ZLMediaKit 的协议、域名或端口不同,浏览器会按跨源规则处理请求。

排查顺序:

  1. 打开浏览器开发者工具 → Network,查看 FLV 请求是否发出、状态码和响应头。
  2. 查看 Console 是否报 CORS、Mixed Content、MIME 或解码错误。
  3. 核实 ZLMediaKit 当前版本的跨域配置与响应头行为。
  4. 若页面使用 HTTPS,而媒体地址为 HTTP,浏览器可能阻止混合内容。生产环境应考虑 HTTPS 反向代理或统一入口。
  5. CORS 不是身份认证机制;不要把开放跨域当作访问控制。

9. 常见故障排查

9.1 DESCRIBE 500 Internal Server Error

含义:ZLMediaKit 发起 RTSP DESCRIBE 时失败,未取得可用 SDP。

检查:

  1. VLC/MediaMTX 的 RTSP 源是否仍在推流,文件是否已播放结束。
  2. 直接用 ffplay 或 VLC 验证源 RTSP。
  3. 核对路径、端口、认证和源服务日志。
  4. 确认源服务在代理建立期间没有退出。

9.2 SETUP 461 Unsupported Transport

含义:RTSP 服务端拒绝了客户端请求的传输方式,常见于客户端与服务端的 RTP 传输协商不兼容。

排查:

  1. 确认源服务是否支持 RTP over TCP、UDP 或两者。
  2. 用 ffplay 分别验证服务端实际支持的方式,例如执行:
ffplay -rtsp_transport tcp rtsp://127.0.0.1:8554/stream

若需测试 UDP,可按 FFmpeg 版本语法调整为 -rtsp_transport udp。

  1. 注意:FFmpeg 播放源时指定的 transport,不会自动改变 ZLMediaKit 代理拉流的 transport。
  2. 核对 ZLMediaKit 版本支持的拉流传输配置/API;不要未经验证就把 rtsp_transport=udp 拼进 RTSP URL。
  3. VLC 作为 RTSP Server 出现兼容问题时,可用 FFmpeg 发布至 MediaMTX,再由 ZLMediaKit 拉流,便于排除 VLC 服务端差异。

9.3 API 返回成功,但 HTTP-FLV 播放失败

逐项确认:

  1. 代理流仍在线,未因源停止而注销。
  2. HTTP-FLV 端口是否正确。
  3. URL 中 app/stream 是否与创建代理时完全一致。
  4. FLV 输出是否在当前版本中启用。
  5. 用 ffplay 测试同一个 URL。
  6. 检查 ZLMediaKit 日志是否收到 .flv 请求、是否出现 mux/编码错误。
  7. 检查视频编码是否为浏览器/播放器支持的格式;FLV 容器并不意味着任意编码都可播放。

9.4 本机可播,局域网其他机器不可播

  1. 使用 ZLMediaKit 主机的 LAN IP,而不是 127.0.0.1。
  2. 确认服务监听在可供局域网访问的网卡/地址,而非仅回环接口。
  3. 检查 Windows 防火墙入站规则。
  4. 从客户端测试端口连通性,例如 PowerShell:
Test-NetConnection 192.168.1.100 -Port 8080
  1. 检查客户端与服务端是否处于可互通网段/VLAN。
  2. 如使用反向代理,确认代理支持长连接/流式响应,不会缓冲整段内容或过早超时。

9.5 有画面但延迟大、卡顿或音画异常

检查:

  • 源端编码参数、帧率、码率和关键帧间隔(GOP)。
  • FFmpeg 是否转码、机器 CPU 占用。
  • 网络丢包、抖动与客户端缓冲。
  • ZLMediaKit 与 flv.js 的延迟/缓冲配置。
  • 多个客户端同时播放时的并发带宽与服务资源。
  • RTSP 拉流和浏览器播放各环节的时间戳连续性。

10. Windows 防火墙与局域网验证

以管理员身份按需建立入站规则。以下仅为示例,端口按实际情况替换:

New-NetFirewallRule -DisplayName "ZLMediaKit HTTP" `
-Direction Inbound -Action Allow -Protocol TCP -LocalPort 8080

若 API 与媒体服务分端口,应分别评估是否需要对客户端开放。不建议将管理 API 端口暴露给普通终端或不可信网络。

在客户端执行:

Test-NetConnection 192.168.1.100 -Port 8080

端口连通只是网络层检查,不代表 FLV 播放链路已成功。


11. 面向工业 AI 视频系统的建议

结合实时视频与模型分类结果的业务目标,建议分层:

摄像头 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. 快速操作备忘

  1. 启动 MediaMTX。
  2. FFmpeg 将 MP4 按实时速度推送到 MediaMTX 的 RTSP 路径。
  3. 用 ffplay -rtsp_transport tcp rtsp://<源主机>:8554/stream 验证源。
  4. 启动 ZLMediaKit,核对 API 端口、HTTP 端口和 API 密钥。
  5. 调用 addStreamProxy,设置 app=live、stream=test、url=rtsp://<源主机>:8554/stream。
  6. 确认拉流成功、轨道就绪。
  7. 使用 ffplay http://<ZLM主机>:<HTTP端口>/live/test.live.flv 验证。
  8. 再用 VLC、局域网客户端和 Vue + flv.js 测试。
  9. 记录版本、配置、源地址、播放地址、端口和排错结果,便于复现。