Loading... # 把推流、拉流和转推放进自己的控制台  一开始,我只是想做一个自己用着顺手的推拉流平台:平时能把信号推到服务器,再从不同设备拉取;需要向其他地方送直播信号时,也能在同一个页面里配置转推。服务器本来还跑着其他网站,我也希望不用每次打开腾讯云控制台,就能很快知道 CPU、内存和公网带宽现在是什么状态。 真正用起来以后,问题变得具体了。有一次 VLC 正在播放 RTMP,突然退出到了首页,手动重开却立即恢复。后来 OBS 又出现过约每三分钟断连重连、网页仍显示 `NO SIGNAL` 的情况。这些经历让我意识到,平台不能只给出一个笼统的“在线”指示:推流端是否真的接入、观看端是否还连着、没有源流时输出的是什么,都需要分别看。 这篇文章记录的就是 **HDaniel Stream Control System** 从个人工具长成一套轻量播控台的过程。我更想讲清它解决了哪些实际问题,以及几次排查怎样改变了功能设计。 ## 先把控制台放进现有服务器 这台服务器只有 2 核 CPU、2 GB 内存,还同时承载网站和 Docker 服务。新系统得单独运行,不能为了多一个控制台影响已有业务。此前我试着配置过 Prometheus、node_exporter 和 Grafana;它们适合通用监控,却没有完全满足我对播控页面、流状态和操作方式的高度定制需求。正式实施时,这组服务也不是正在运行的现成底座,于是控制台直接读取主机 CPU、内存、磁盘和公网网卡计数器,把服务器状态放在流操作的旁边。  *仪表盘里既能看到服务器资源,也能看到 MediaMTX 和控制服务是否可用。* 架构没有做得很重:MediaMTX 负责接收和分发媒体流;FastAPI 控制服务负责账户、路径、鉴权、事件和页面;SQLite 保存管理数据。整个项目用独立的 Docker Compose 部署,管理页面由现有 Nginx 提供 HTTPS。外观选了黑底荧光绿的终端风格,但操作布局和手机适配比“复古”本身更重要。  *管理请求和视频数据走各自的路径:控制台判断谁有权连接,MediaMTX 承担实际收发。* ## 创建一条流,也要真的管住入口 最早需要解决的不是按钮,而是权限。只在数据库里登记一个路径,并不能阻止有人直接向 MediaMTX 的其他路径推流。因此系统采用默认拒绝:路径必须已经创建、处于启用状态、没有过期,而且推流凭证正确,才允许新的 Publisher 接入。未知路径、错误密码、停用和过期路径都不能发布。观看权限另行判断,一条流可以公开播放,也可以要求私有读取凭证。 我把这套规则接到 MediaMTX 的外部 HTTP 鉴权上。日常创建、编辑和停用流时,不需要每改一条路径就重启媒体服务。页面提供名称、路径、推流账号、播放策略和到期时间设置;自定义到期时间按北京时间填写,不必手算 Unix 秒数。管理端的登录有安全 Cookie、有效期和修改请求校验;密码以哈希形式保存,鉴权接口只对内部网络开放。 ## OBS 显示正在连接,为什么页面仍是“无源”? 排查 OBS 的过程让我对“连接成功”这件事谨慎了很多。OBS 有服务器地址、推流码和独立的身份认证输入框,看起来像是把账号密码填进去就够了。但在当前这套 RTMP 接入配置中,MediaMTX 需要的是地址里的 `user`、`pass` 参数。账号放进 OBS 的独立认证栏,不一定会以服务器期望的方式传过去。 现在流详情中有 **PUBLISH CREDENTIALS / OBS**:核验当前凭证后,临时生成可复制的完整地址,并提示服务器栏、推流码栏和身份认证选项该怎么填。这个地址含有密码,只在操作时显示,不能当作普通播放链接分享。  *同一条流的推流地址与读取地址并列展示,但 Publisher 和 Reader 的状态分别计算。图中的连接地址已遮盖。* 还有一个更隐蔽的误判:路径有待机画面,播放器就能拉到视频,MediaMTX 也可能认为路径已准备好;这不等于 OBS 真正接入了。早期页面把路径的字节计数当成源输入,于是出现“`NO SIGNAL`,输入却有几百 Kbps”的矛盾显示。后来我把**真实源流输入**和**待机输出**拆开:没有 Publisher 时就明确写 `NO SOURCE`,待机画面是否可用单独展示。 OBS 反复重连时,还要看鉴权事件与媒体轨道是否匹配。待机轨道和 OBS 实际送入的 H.264/H.265 格式若不兼容,也会影响接管。仅凭“三分钟断一次”这个现象,不能认定一定是手机热点出了问题。 ## 单路流健康时间线,比整机曲线更能回答问题 首页的 CPU 和公网带宽适合快速扫一眼,却不足以解释“刚才那一路为什么断了”。一台机器可能同时有多个流、多个观众和其他网站;公网 TX 下降,不能直接等同于某个 Reader 掉线,更不能当成某一路流的准确码率。 所以每条流都有自己的详情:真实 Publisher、各协议 Reader 数量、连接时间、路径收发速率,以及 5 分钟、1 小时、24 小时的健康时间线。页面内预览复用已有的 HLS 输出,默认静音。打开预览会多出一个普通 Reader 的网络流量,但不会因此启动持续转码任务。  *这段时间线是单条流的视角。琥珀色表示待机画面。* 诊断断流时,我希望页面先说事实,再说推测:记录 Publisher 或 Reader 的连接和断开时间,然后看前后发生了什么。如果 Reader 断开而 Publisher 一直在线,更像观看端连接中断;如果 Publisher 先断,随后 Reader 也掉线,更像源侧中断。多条流一起断开,则需要再看媒体服务本身。系统把前者列为已观测事件,把“更像什么”标成 **LIKELY CAUSE**;拿不到的明确断开原因就显示 `UNKNOWN`。  *两种相近的“画面没了”,可能对应完全不同的连接变化。时间上的先后只能帮助定位,不能替代网络故障证据。* 日志页面保留了这些事件的查询入口,可以按日期、类型和流筛选。首页只放少量重要事件;普通 Reader 的频繁进出留在单流详情,同类事件短时间重复时会聚合计数。这样一次异常不会淹没在页面轮询和日常连接里。  *截图中的来源 IP、路径详情和地址已遮盖。* ## 无信号的时候,也应该有明确的画面 创建一条流之后,信号源不一定马上接上。我不希望观众看到黑屏,也不希望操作员误以为待机画面就是真实信号。于是给无源状态准备了彩条、持续滚动的 `HDANIEL_STUDIO 流状态正常,源流无信号` 字幕,以及 1 kHz 千周测试音;画面右上角显示流名称和所选的协议、编码、分辨率、帧率。  *这张图是实际生成的待机文件抽帧。右上角写的是这条流配置的待机格式,并非对当前摄像机信号的检测。* 最初 H.264 与 H.265 的待机内容并不一致,后面统一改成按流规格预先编码。文件只在创建或修改待机规格时生成一次,无源时循环播放;真实源接入后接管,断开后回到待机。这样避免为每条无源流常驻一个 FFmpeg 转码进程。预览默认静音,确实要检查千周时再解除静音,并先把音量调低。 ## 从一条 RTMP 路径,走到多协议与转推 随着使用范围扩大,单个 RTMP 地址已经不够。V2.1 把 RTMP、SRT、RTSP 的推流和读取地址放进同一条流详情,发布与私有读取各用各的凭证。**PRIVATE READ / VLC** 与 OBS 辅助入口一样,会在核验后临时生成连接地址,让操作员少猜一次不同客户端的参数写法。 转推管理也是从最初“自己要拉流再送出去”的需求里长出来的。Relay Manager 可以选现有本地流,或接入受限制的外部公开来源,再把信号送往 RTMP 或 SRT 目标。每个输出单独显示运行状态、重连次数、估算码率和错误;转推走流复制,不做默认转码。  *一个来源可以配置多个独立外部输出。截图中的本地流路径已遮盖。* 多协议并不等于所有编码都能在任何客户端正常播放。实际测试里,H.265 的 RTMP 读取曾只得到音频;H.265 观看要优先用验证过的 SRT 或 RTSP 客户端。协议决定怎么传,编码决定视频怎样压缩,两者不能混为一谈;“不转码”也意味着目标端必须支持源流的编码和封装。 ## 做完这套系统,我才真正分清“推”和“拉” 以前我容易把“一条流”想成一根从 OBS 通向播放器的线。几次对话和排查之后,这个想法变了:**Publisher 是向服务器提供信号的连接,Reader 是各自从服务器获取信号的连接**。OBS 仍在推,不代表 VLC 的 TCP 连接不会单独中断;VLC 退出,也不自动证明源端掉线。反过来,路径还能被拉到彩条和千周,也只能说明待机输出可用,不能说明真实 Publisher 在线。 这也解释了为什么我最后坚持做单流时间线,而不只看公网带宽。服务器 RX 可以给源侧提供背景,TX 可以给观看侧提供背景,但一条流可能有多个 Reader,服务器还承担别的业务;网卡曲线只能提供旁证。真正有用的顺序是先看谁连接、谁断开,再看 MediaMTX 是否可用和当时的流量变化,最后才谈可能原因。对那次 VLC 突然返回首页的经历,系统能帮助判断它更像 Reader 侧断开还是源侧中断,却不能凭一条断连记录断言“手机热点不稳”。 推拉流的另一层区别也在转推中变得清晰:服务器既可以作为某条流的 Reader 去拉取,也可以作为另一目标的 Publisher 把相同媒体数据送出去。流复制节省 CPU,但不会自动解决 H.265、RTMP 和播放器之间的兼容问题。把这些角色拆开之后,页面上的“在线”“无源”“待机”“重连”终于各有明确含义。 ## 现在能用,也要记住边界 这套系统已经完成了登录、流的创建与权限控制、未知路径和错误凭证拒绝、待机输出、单流事件、H.265 待机文件和源流接管等验证;部署后原有站点继续可访问,数据库和关键配置也有备份。不过,健康曲线目前保存在内存中,控制服务重启后会重新积累;连接事件依赖轮询,极短的连接可能捕捉不到;断开原因并非总能由 MediaMTX 提供。SRT 的公网使用还要看云平台安全组,真正上影视转播现场前仍需用目标摄像机、编码器和播放器做端到端演练。 回头看,这个项目最有价值的变化,是把原来一个模糊的“流在线吗”,变成几个能实际操作和排查的问题:**谁有权推、源是否真的到了、谁还在看、无源时输出什么、断开事件发生在哪一侧**。它依然是一套给自己日常使用的轻量工具,只是现在面对直播信号传输中的意外,也更有能力把事情说清楚了。 最后修改:2026 年 10 月 15 日 © 允许规范转载 打赏 赞赏作者 支付宝微信 赞 1 如果愿意的话...或许可以请我喝杯奶茶。
1 条评论
要使用chatgpt才能看懂了OωO