拓冰建站拓冰建站
首页 / 资讯中心 / 正文

MediaMTX 代理请求(Proxy Requests)实战:用正则路径将 RTSP 请求转发到 NAT 后的摄像头与服务器

MediaMTX 代理请求Proxy Requests实战用正则路径将 RTSP 请求转发到 NAT 后的摄像头与服务器【免费下载链接】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/mediamtxMediaMTX本仓库即其完整源码不仅可以接收推流、对外提供拉流还能充当媒体代理把客户端发来的请求原样转发给另一台服务器或摄像头从而让处于 NAT 之后、无法被外部直接访问的设备通过一台公网可达的 MediaMTX 间接对外提供服务。本文以官方文档 docs/2-features/12-proxy.md 为核心讲解如何用mediamtx.yml中的正则路径与$G1占位符实现通用转发规则并结合源码解析其底层匹配与替换原理让你能直接落地一条规则代理全部路径的部署方案。一、核心思想把 MediaMTX 当作媒体路由器默认情况下paths中的每个路径都需要单独配置。而代理场景最典型的诉求是外部客户端访问什么路径MediaMTX 就把这个路径原封不动地转发到指定的上游服务器。此时路径名不再是一个固定字符串而是一个任意匹配的正则表达式路径本身成为可捕获的变量。官方文档给出的配置是直接替换mediamtx.yml中paths段落的全部内容paths: ~^(.)$: # If path name is a regular expression, $G1, $G2, etc will be replaced # with regular expression groups. source: rtsp://other-server:8554/$G1 sourceOnDemand: yes替换后所有发往rtsp://mediamtx:8554/a的请求都会被转发到rtsp://other-server:8554/a访问rtsp://mediamtx:8554/b则转发到rtsp://other-server:8554/b依此类推。对客户端而言它看到的只是一个普通的 RTSP 服务地址对上游服务器而言流量来源被收敛到了一台 MediaMTX 上。二、配置语法逐项拆解1. 正则路径以~为前缀paths的键名以~开头时会被当作正则表达式处理。从源码 internal/conf/path.go 可以看到其识别逻辑default: // regular expression-based path regexp, err : regexp.Compile(name[1:]) if err ! nil { return fmt.Errorf(invalid regular expression: %s, name[1:]) } pconf.Regexp regexp即去掉~前缀后剩余部分直接交给 Go 标准库regexp.Compile编译因此支持完整的 Go 正则语法如^、$、()、|、[0-9]等。~^(.)$的含义是匹配任意非空路径并把整条路径捕获为第一个分组。默认配置文件 mediamtx.yml 中还预置了两个特殊路径名all与all_others它们在 internal/conf/path.go 中被等价编译为^.*$用于兜底匹配所有未命中其他配置的路径。2.$G1、$G2占位符正则捕获组回填当路径名是正则表达式时source、forward以及各类 hooks如runOnDemand中都可以使用$G1、$G2等占位符它们会被替换为正则表达式的捕获组内容。真正的替换发生在静态源启动时位于 internal/staticsources/handler.gofunc resolveSource(s string, matches []string, query string) string { for i : len(matches) - 1; i 1; i-- { s strings.ReplaceAll(s, $Gstrconv.FormatInt(int64(i), 10), matches[i]) } s strings.ReplaceAll(s, $MTX_QUERY, query) return s }这里的matches就是FindStringSubmatch的返回值matches[0]是整个路径matches[1]起依次对应第 1、2、3…个捕获组与配置中的$G1、$G2一一对应。因此一条配置可以同时携带多个捕获组例如paths: ~^(.)/(.)$: # 访问 /camera1/live 会被转发到 rtsp://other-server:8554/camera1/live source: rtsp://other-server:8554/$G1/$G2 sourceOnDemand: yes3.sourceOnDemand: yes按需拉流节省带宽在正则代理场景下sourceOnDemand几乎是必须的。其含义是只有当至少一个读者reader连上来时才真正去上游拉流没有任何读者时立即断开。相关校验逻辑在 internal/conf/path.goif pconf.SourceOnDemand { if pconf.Source publisher { return fmt.Errorf(sourceOnDemand is useless when source is publisher) } } else { if pconf.Source ! publisher pconf.Source ! redirect pconf.Regexp ! nil { return fmt.Errorf(a path with a regular expression (or path all_others) and a static source must have sourceOnDemand set to true) } }这里有两层约束值得注意sourceOnDemand只对 URL 类型的静态源有意义source为publisher客户端推流时配置它会被直接拒绝反过来正则路径 静态源URL 源如果不开启sourceOnDemand配置校验会直接报错。原因是正则路径可能被任意名称命中如果每次命中都立即去上游拉流会导致连接泛滥、带宽浪费。配套的参数还有两个见 mediamtx.yml 的pathDefaults段# If sourceOnDemand is yes, readers will be put on hold until the source is # ready or until this amount of time has passed. sourceOnDemandStartTimeout: 10s # If sourceOnDemand is yes, the source will be closed when there are no # readers connected and this amount of time has passed. sourceOnDemandCloseAfter: 10ssourceOnDemandStartTimeout默认 10s表示读者最多等待上游就绪的时间超时则返回失败sourceOnDemandCloseAfter默认 10s表示最后一个读者断开后上游连接还会保留多久才被关闭避免读者频繁进出时反复建连。三、路径匹配与路由的源码链路当一个客户端请求到达时MediaMTX 通过 internal/core/path_manager.go 中的doFindPathConf调用conf.FindPathConf来完成路径名 → 配置项的解析。核心匹配逻辑在 internal/conf/path.go先在paths中按精确字符串查找命中即返回未命中则收集所有正则路径配置排序后逐个执行FindStringSubmatch第一个匹配的配置胜出all/all_others被特意排在最后兜底全部未命中才返回 path is not configured 错误。匹配结果捕获组随后随createPath一并传入 path 对象最终在 internal/core/path.go 中判断source为 URL 时创建staticsources.Handler并把Matches传给它用于$G1替换source为publisher或redirect时则不创建静态源。这条链路说明了两件事代理的本质就是正则路径 → URL 型 source → 静态源拉流的组合与普通拉流如直接配置source: rtsp://camera走的是同一套静态源机制只是 URL 中注入了路径捕获组每个被命中的路径名都会动态创建对应的 path 实例请求结束、无读者后按需回收因此一条正则规则即可覆盖任意数量的上游路径无需逐个枚举。四、可代理的协议与源类型source不仅支持 RTSP还支持仓库中几乎全部的拉流协议。完整清单见 mediamtx.yml 中pathDefaults.source的注释代理场景同样适用协议示例 sourceRTSP / RTSPSrtsp://user:passhost:8554/path、rtsps://host/pathRTSP 隧道rtsphttp://host/path、rtspws://host/pathHTTPS/WSS 同理RTMP / RTMPSrtmp://host:1935/path#streamKeyHLShttp://host/stream.m3u8、https://host/stream.m3u8SRTsrt://host:8890?streamidstreamidMoQmoqt://user:passhost/pathWHEP (WebRTC)whep://host/path、wheps://host/pathMPEG-TS over UDPudpmpegts://ip:port本机监听RTP over UDPudprtp://ip:port需配合rtpSDP此外变量不仅限于$G1还可以使用$MTX_QUERY透传第一个读者携带的查询参数如?tokenxxx。仓库的配置解析测试 internal/conf/conf_test.go 对rtmp://$G1:$G2/live?token$G3、https://$G1/$G2/index.m3u8、srt://$G1:$G2/$G3、whep://$G1:$G2/$G3、moqt://$G1:$G2/$G3、udpmpegts://$G1:$G2等多种含占位符的 source 均做了加载校验测试可作为配置合法性的参考。上游使用 HTTPS/RTSPS 等加密协议且证书为自签名时可通过sourceFingerprint配置证书指纹来放行校验获取指纹的命令在 mediamtx.yml 的对应注释中给出。五、典型部署拓扑与注意事项NAT 穿透代理这是文档点名的首要用途摄像头或流媒体服务器部署在内网NAT 之后外部客户端无法直连。将一台公网 MediaMTX 配置为正则代理后外部客户端rtsp://mediamtx-public:8554/任意路径实际拉流rtsp://other-server:8554/同一路径上游只需能访问 MediaMTM 所在网络或 MediaMTX 能访问上游即可无需在 NAT 上开放端口安全与鉴权提醒正则代理意味着外部可请求任意路径名建议结合认证与路径级权限加以约束。MediaMTX 支持authMethodinternal / HTTP / JWT以及authInternalUsers中按 action path 的权限配置相关说明见 docs/2-features/06-authentication.md。权限中的path字段同样支持~前缀正则。排错与验证启动时若配置不合法MediaMTX 会直接报错退出错误信息中会明确指出问题如must have sourceOnDemand set to true可对照 internal/conf/path.go 的校验逻辑定位运行时可通过logLevel: debug见 mediamtx.yml观察 path 的创建、静态源的启动/停止日志确认$G1替换后的实际拉流 URL 是否符合预期也可用ffplay rtsp://mediamtx:8554/a与ffplay rtsp://mediamtx:8554/b分别验证不同路径是否各自命中上游对应路径。六、小结MediaMTX 的代理能力本质上是正则路径 URL 静态源 按需拉流三者的组合~^(.)$负责任意路径匹配$G1负责把路径名回填进上游 URLsourceOnDemand负责按读者数动态建连/断连。它把一台公网 MediaMTX 变成了上游 NAT 内服务器或摄像头的统一出入口并且天然复用仓库内全部拉流协议实现。理解 internal/conf/path.go 的匹配与校验逻辑、internal/staticsources/handler.go 的占位符替换逻辑就能举一反三地写出更复杂的多捕获组、多协议代理规则。【免费下载链接】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),仅供参考
分享:

看完干货,该让你的企业上线了

免费需求沟通 · 48 小时内出具建站方案 · 河南本地可上门