Mediamtx RTSP SETUP 路径问题排查指南:400、401、404 快速定位
【免费下载链接】mediamtxReady-to-use Media-over-QUIC / SRT / WebRTC / RTSP / RTMP / LL-HLS / MPEG-TS / RTP live media server and media proxy that allows to read, publish, proxy, record and playback real-time video and audio streams.项目地址: https://gitcode.com/GitHub_Trending/me/mediamtx
用 Mediamtx 拉取摄像头或转发源的 RTSP 流时,很多新手会卡在 SETUP 这一步:客户端弹出 400、401 或 404,流就是放不出来。Mediamtx 是一款支持 RTSP、RTMP、SRT、WebRTC 等多种协议的多协议媒体服务器,而 SETUP 请求的路径处理正是新手最容易踩坑的环节。下面按"先对照症状、再看原理"的顺序,带你把问题一次排清楚。
症状速查:先对着表格找原因
别急着翻源码。客户端返回什么、日志里写了什么,基本就能定位方向:
| 你看到的现象 | 最可能的原因 | 第一反应动作 |
|---|---|---|
400 Bad Request,日志含invalid path | 请求路径为空,或没以/开头 | 核对完整 URL,确认是rtsp://host:8554/stream名这种形式 |
| 401 Unauthorized | 没带凭证,或用户名/密码错误 | 检查认证配置和客户端填入的凭证是否一致 |
| 403 Forbidden | 凭证正确,但该用户没有这个路径的读取权限 | 查看用户permissions里read对应的path范围 |
| 404 Not Found | 这个路径下当前没有正在发布的流 | 确认发布者正常,且路径名和发布端完全一致 |
| 461 Unsupported Transport | SETUP 要求的传输协议(如 tcp)被禁用了 | 检查 mediamtx.yml 中rtspTransports是否包含tcp |
客户端发出 SETUP 后,服务器依次查了什么
Mediamtx 的 SETUP 处理逻辑在 internal/servers/rtsp/session.go 的onSetup函数里,顺序是这样的:
- 查路径格式:路径不能为空,且必须以
/开头。不满足直接回 400,日志写invalid path:
if len(ctx.Path) == 0 || ctx.Path[0] != '/' { return &base.Response{StatusCode: base.StatusBadRequest}, nil, fmt.Errorf("invalid path") }- 查传输协议:如果 SETUP 里写的是 TCP,而配置里没开 TCP,回 461。UDP、组播被禁用的情况则由底层库提前拦截。
- 查权限:把用户名、密码、来源 IP 交给认证模块校验,不过就回 401/403。
- 查流是否存在:播放场景下如果这个路径没有正在发布的流,回 404(内部对应
PathNoStreamAvailableError)。 - 全部通过,建立 RTP 传输会话,返回 200,后续进入 PLAY。
记住这条顺序,后面每个错误码都能对号入座。
RTSP 返回 400?先核对路径格式
看到 400 时,先检查请求 URL 本身。最常见的情况是路径段为空或粘连,比如rtsp://host:8554(没写路径)和rtsp://host:8554stream1(漏了斜杠)。正确的形态是rtsp://host:8554/stream1,其中stream1会去掉开头的/后与 Mediamtx 配置里的路径名匹配。
再确认路径里有没有奇怪字符(空格、中文、多余的问号)。如果你用了查询参数,问号后面的部分会被当作 Query 单独处理,路径本体要在问号之前闭合。最后看一眼服务器日志里是否有invalid path,有的话就是格式问题无疑;如果日志是其他报错文本,再按 400 的其他分支排查,比如流拉起来时解码或封装出错,那属于流本身的问题而不是路径问题。
401 / 403:按"凭证 → 权限"两步走
看到 401 时,先检查客户端到底有没有把凭证发出去。有些播放器要手动填用户名密码,有些会自动处理 Basic 认证,先确认这一步没漏。再确认用户名和密码和 Mediamtx 配置里的authInternalUsers完全一致,注意区分内部认证、外部 HTTP 认证和 JWT 三种模式,不同模式下凭证的含义不一样,详细规则见 docs/2-features/06-authentication.md。
如果凭证确认无误仍然被拒,就是权限问题(403 的典型场景)。最后去核对用户的permissions配置:action: read下面的path字段如果指定了具体路径,其他路径一律拒绝;留空才表示任意路径。改完配置后等文件监听自动生效,再重连即可。
404 Not Found:流不存在,先查发布端
看到 404 时,先检查发布端是不是真的在推流:发布者连的是不是同一台 Mediamtx、发布用的路径名和你拉流用的路径名是否一字不差(大小写也算)。再确认拉流时机——如果发布者断开了、或者该路径配成了按需启动但命令没跑起来,路径上就没有可用流,SETUP 自然回 404。
最后借助控制面验证:调用 docs/5-references/2-control-api.md 里描述的接口查看该路径的 source 是否为none。如果 API 显示有 source 但客户端还是 404,多半是发布端刚断连的竞态,重连一次即可。
进阶:路径别名与 on-demand 动态发布
两个常用的进阶手段,可以覆盖大部分"路径对不上"的场景。前者是给远程流起一个好记的名字,后者是"没人看就先不推,有人来看再启动":
paths: cam1: source: rtsp://192.168.1.100:554/stream nvr: runOnDemand: "sh start_nvr.sh"cam1就是一个路径别名,客户端用rtsp://host:8554/cam1拉流,实际源在远端摄像头上。nvr则配了runOnDemand,当第一次有读者(包括 RTSP SETUP)请求这个路径时,Mediamtx 先执行脚本把流拉起来,读者在超时时间内等待;没人看时再用runOnDemandCloseAfter自动收尾。完整选项说明见 docs/2-features/14-on-demand-publishing.md。
日志排查:调级别、搜关键词
排路径问题离不开日志。在 mediamtx.yml 里把logLevel从info调到debug,并让logDestinations同时输出到[stdout, file],logFile指定落盘文件,方便事后翻查。
恢复现场后重点搜三类关键词:
invalid path:路径格式问题的铁证;[RTSP session开头的行:每条会话日志都带这个前缀,顺着同一个 session 前缀看完整生命周期(created by ...到destroyed: ...);is reading from path:这行出现说明 SETUP、PLAY 全走通了,流正常读起。
一条典型的成功日志长这样:INF: [RTSP session a1b2c3d4] is reading from path 'cam1', with tcp, H264, MPEG-4 Audio。如果你搜到了 404 对应会话的destroyed: ...,后面那段错误文本就是最终结论。
发布前自查清单
上线前过一遍这五条,绝大多数 SETUP 路径问题都能提前避免:
- 拉流 URL 形如
rtsp://host:8554/路径名,路径以/开头且无多余字符; - 发布端和拉流端的路径名完全一致,且发布者此刻确实在推流(可用控制 API 确认);
rtspTransports里包含客户端要用的传输协议(tcp / udp / 组播);- 开了认证时,凭证已填对,且用户
read权限覆盖目标路径; - 日志级别设为
info以上并落盘,确认能搜到is reading from path这一行。
【免费下载链接】mediamtxReady-to-use Media-over-QUIC / SRT / WebRTC / RTSP / RTMP / LL-HLS / MPEG-TS / RTP live media server and media proxy that allows to read, publish, proxy, record and playback real-time video and audio streams.项目地址: https://gitcode.com/GitHub_Trending/me/mediamtx
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考