ARTICLE DETAIL

资讯详情

深耕编程入门与网站建设的一线实战洞察。

多窗口RTSP拉流方案对比与实战:从ffplay到mediamtx

多窗口RTSP拉流方案对比与实战:从ffplay到mediamtx 简介RTSP拉流工具是一款面向视频监控、网络直播等实时场景的多窗口流媒体播放软件能在单一界面内同时拉取并管理多路RTSP视频流无需为每路流单独分配软件界面适合集中监看多个监控点或并发观看多路直播画面的用户。压缩包共291个文件包含exe启动程序、dll动态链接库、pyd与py脚本模块及qm语言资源文件整体约310MB解压后即可使用已有206人学习下载。工具支持1x1、1x2、1x3、2x3、2x4等多种窗口布局自由组合兼容H.264、H.265HEVC、MPEG-4等主流编码格式并提供播放暂停、画面缩放、全屏、音量调节、静音及画质调节功能。传输层面具备错误检测与恢复、网络自适应机制安全方面支持加密传输、身份验证与权限管理可保障流媒体传输稳定和数据访问安全。整体可部署于个人电脑、工业服务器或嵌入式设备在家庭安防、商业监控和公共安全等领域提供实用的多路视频流播放与管理方案。1. 为什么你需要一个多窗口RTSP拉流工具做流媒体、安防监控或者机器人方向的朋友应该都有过这种经历手里握着几十路摄像头或者实验室里有好几台设备都在推RTSP流你想同时盯几路画面却找不到一个顺手的工具。一个个地用VLC打开窗口吧开三五个还能忍十几路一起上机器基本就要卡死了。我自己最早做安防项目调试的时候就是在Windows上硬开VLC窗口一路一路手动输地址三路以上就开始掉帧五路以上直接系统资源吃满别提有多痛苦了。RTSP是Real Time Streaming Protocol也就是实时流协议它本身负责的是“控制”——比如播放、暂停、停止这些操作真正的音视频数据是靠RTP/RTCP在传输。实际使用中我们写rtsp://10.51.25.19:554/xxxx这种地址其实是在向服务器发起一个会话请求服务器再把媒体流推给播放端。现在大量的摄像机、NVR、流媒体服务器都原生支持RTSP所以它成了设备取流的事实标准。但问题在于RTSP不是一个为多窗口设计的协议它本身只管一条流的控制你要同时看多路就得自己在应用层解决这就延伸出了“拉流工具要不要多开几个窗口”“多窗口怎么分配资源”“用什么底层方案去渲染多路画面”这些实际问题。我用过很多方案从最原始的VLC手动拉流到写FFmpeg命令循环播放再到部署mediamtx做RTSP到浏览器的转换跑了不少弯路。这篇文章就想把多窗口RTSP拉流这件事从选型到落地讲透包括地址怎么解析、为什么有的方案卡、怎么让多个窗口稳定运行、遇到断流怎么排查全部是按我实际跑过的经验来写的。新手看完能直接照做老手看完也能补上一些容易忽略的细节。2. 技术选型多窗口拉流的几种主流方案2.1 别急着写代码先把方案选对做多窗口拉流的第一步不是准备工具而是先搞清楚你面对的是什么场景。同样是“同时拉多路流”需求差异其实很大如果你只是临时看一眼三台设备那用VLC手动开窗口就够了如果你要长期盯着十几路画面那么你需要轻量级渲染器比如ffplay配合脚本来批量启动窗口如果你的需求是要把画面分享给其他人比如要给客户或同事开个网页看监控那你需要的是RTSP转Web的方案——目前比较好用的工具我认为是mediamtx。我自己当时的场景就属于第二种加第三种调试RK3588板子上的多个摄像头先是本地开窗口看后面又要出个页面给同事远程看现场画面。所以我在选型时主要考虑了三类工具VLC、ffplay、mediamtx。VLC适合偶尔用用ffplay适合自己机器上批量开窗mediamtx则适合把RTSP流转出去给浏览器播放。2.2 三类方案实测对比下面这张表是我基于自己的实际体验做的总结你可以根据自己的项目情况对号入座方案适用场景多窗口支持资源占用延迟典型值扩展性VLC三五路以内手动查看手动逐个开窗口窗口多后管理混乱偏高每个窗口都会拉起完整GUI和音频管线500ms~1s差没有批量管理能力ffplay 脚本自己机器上批量拉流适合调试通过循环脚本批量开窗窗口数量视机器性能低纯SDL渲染比VLC省很多300ms~500ms中容易扩展成定时重拉、自动退出mediamtx 浏览器远程分享画面、跨平台访问网页端多窗口分屏由前端控制后端只需转流一次后端正压力随路数线性增长前端看机器性能HLS产生1~3秒延迟WebRTC可到300ms以下强支持RTSP/RTMP/WebRTC/HLS多协议VLC不是不能用它的GUI很成熟一些新手拿过来说说“这个我熟”直接把rtsp地址拖进“网络串流”里就能看。但我在实际用的时候发现它开第三路之后画面延迟会明显加大。你排查之后会发现问题往往不是网络而是VLC默认会为每个窗口创建独立的音频队列和视频处理管线。为了这个去翻VLC的底层参数费劲且收益不大。我的建议是VLC只用来做快速验证不适合长期多路观看。ffplay是我现在本地拉流的主力。它是FFmpeg自带的播放器命令行的方式看起来很老派但胜在轻巧、可控、好扩展。我可以写一个for循环把一堆RTSP地址扔进去每个地址用一个独立进程播放再配合窗口参数控制位置。最棒的是ffplay崩溃了不会影响其他窗口因为每个进程都是独立的。mediamtx前身是rtsp-simple-server负责的则是另一类需求把RTSP流转成浏览器能直接播放的格式。它内部用的是Go语言写的高性能服务器支持RTSP输入后同时输出RTMP、HLS、WebRTC还不需要你自己去编译一堆依赖单文件就能跑。文章后面我会给一个实际转换步骤。2.3 为什么我不建议你直接上浏览器看RTSP这里有个核心认知很关键现代浏览器是不支持原生播放RTSP协议的无论是Chrome还是Firefox都不行。你拿rtsp://admin:xx192.168.1.13:554/streaming/channels/101这样的地址直接粘贴到浏览器地址栏只会得到一个打不开的错误页面。这是因为RTSP不是HTTP协议Web浏览器本身没有实现RTSP解复用和RTP拆包能力。网上搜“在线RTSP播放器”出来一堆工具但实际都是要做一层转码或转封装。所以你在浏览器里需要的是转流方案而不是“拉流”本身。把RTSP转成HLS或者WebRTC浏览器才能基于HTTP/WebSocket去读取数据并播放。我们后面演示的mediamtx就是干这个的。3. 核心细节RTSP地址格式与参数拆解3.1 一条RTSP地址到底包含什么我见过很多人在RTSP地址上栽跟头。拿一条典型的设备地址举例rtsp://admin:password123192.168.1.13:554/streaming/channels/101它的拆解是这样的rtsp://协议头固定格式admin:password123用户名和密码用于设备认证中间用冒号分隔192.168.1.13:554设备IP和RTSP服务端口默认是554/streaming/channels/101应用路径在前端设备中101通常代表主码流通道1102代表子码流通道1海康的默认路径比较标准就是/streaming/channels/101。如果是大华路径一般是/cam/realmonitor?channel1subtype0。其他牌子的摄像头路径五花八门最好先查设备文档不要猜。还有那种rtsp://10.51.25.19:554/openurl/vsig252ch4y638ccc19edc541939a996这种路径看起来像是一个随机生成的会话ID通常是由某个流媒体服务生成的动态拉流地址有效期可能只有一段时间这种地址没法长期用只能现取现用。3.2 多窗口场景下必调的三个参数在很多工具里你可以在RTSP地址后追加参数来改变传输策略和延迟表现这在多窗口同时拉流的时候非常关键。第一个是传输协议。RTSP底层可以用UDP传输也可以用TCP传输还可以用UDP多播。默认很多工具会优先尝试UDP因为它延迟低。但在实际网络环境下UDP丢包会导致画面花屏、马赛克。尤其是多个窗口同时通过Wi-Fi拉流的时候UDP丢包的概率相当高。 我建议多窗口环境下优先改用TCP虽然理论上延迟会略大几毫秒但稳定性的提升非常明显。ffplay里可以这样写ffplay -rtsp_transport tcp rtsp://...。第二个是缓冲大小。VLC默认缓冲时长比较大导致画面切换时延迟变高。ffplay可以加-fflags nobuffer -flags low_delay来关掉额外缓冲多窗口下用这个组合延迟会低很多。我测试里没加参数的ffplay延迟大概800ms加了之后能压到300ms左右。第三个是超时时间。多窗口拉流最常见的问题就是某一路突然断流没有自动重连整个脚本就卡在那里了。你可以设置-timeout 3000000这类参数来控制底层socket超时也可以用外层脚本做自动重试。这个后面在实操部分我会给一段现成的脚本。3.3 主码流还是子码流这是一个重要选择很多人在多窗口拉流时忽略了一个选择同一台摄像头可以输出主码流和子码流。主码流分辨率高、码率高清晰度好适合录像和需要看清细节的窗口子码流分辨率低、码率低适合多画面预览和移动端播放。如果你要在同一个屏幕上开16个窗口全用主码流那么就算是你那台i7电脑也会很吃力网络传输压力也不小。我的经验是多窗口总览的时候用子码流重点单窗口放大查看的时候才去切主码流。海康的子码流就是channel/102这样的路径。如果你遇到多窗口卡顿先别急着换电脑把码流换到子码流再说。4. 实操过程从ffplay批量拉流到mediamtx转Web播放4.1 环境准备按这个清单折腾就够了我习惯在Windows和Linux上各有一份环境因为很多项目调试机器是Windows但部署机器是Linux。这里的核心依赖是FFmpeg因为ffplay就是随FFmpeg一起发布的。Windows上最省事的方法是下载FFmpeg官方编译版解压之后把bin目录加入系统PATH。打开命令行执行ffplay -version能输出版本号就说明环境OK。Linux上更简单Ubuntu/Debian系执行sudo apt update sudo apt install ffmpeg这里有个坑很多发行版仓库里的FFmpeg版本偏低老版本ffplay对某些RTSP流兼容性不佳经常会提示Method DESCRIBE failed。遇到这种情况建议自己下载静态编译版覆盖系统自带版本。mediamtx也是单文件工具去GitHub下载对应平台的可执行文件就行。解压后是一个mediamtx可执行文件加一个mediamtx.yml配置文件。Windows下双击exe就能跑起来Linux下记得先chmod x mediamtx然后./mediamtx。4.2 用ffplay跑起多窗口拉流本地多窗口拉流我自己写过一个最简单的脚本Windows下是.batLinux下是.sh。核心逻辑其实就是一个循环加一个启动后台进程。假设我有三路流地址分别存到三个变量里#!/bin/bash STREAMS( rtsp://admin:password192.168.1.101:554/streaming/channels/101 rtsp://admin:password192.168.1.102:554/streaming/channels/101 rtsp://admin:password192.168.1.103:554/streaming/channels/101 ) for url in ${STREAMS[]}; do ffplay -fflags nobuffer -flags low_delay \ -rtsp_transport tcp \ -window_title $url \ -x 640 -y 360 \ $url done wait这段脚本里几个参数我解释一下-fflags nobuffer告诉FFmpeg不要额外缓存减少延迟-flags low_delay进一步降低缓冲区延迟适合实况流-rtsp_transport tcp强制走TCP避免UDP丢包花屏-window_title把RTSP地址显示在窗口标题上窗口多了以后一眼就能知道哪个窗口对应哪路设备-x 640 -y 360强制窗口分辨率避免所有窗口默认铺满屏幕这段脚本跑起来之后每个ffplay窗口都是独立进程。好处是单路卡死不影响其他路坏处是想一次性关掉所有窗口的时候不够方便。我的处理办法是在脚本最后加一行提示按CtrlC能一次性杀掉所有后台任务Windows下也可以用taskkill /IM ffplay.exe /F强制清掉所有ffplay进程。4.3 用mediamtx把RTSP转成浏览器可播放的格式当你有同事或者客户需要通过浏览器看多路画面时ffplay那种本地窗口就不好用了毕竟不能让人家也装一个FFmpeg。这时候我一般用mediamtx做协议转换。默认启动mediamtx后它会监听RTSP的8554端口默认不是554因为554需要管理员权限HTTP的888端口。它读取摄像头RTSP流后可以通过HLS或WebRTC方式输出到浏览器。第一步让mediamtx拉取摄像头的RTSP流在配置文件的paths段添加paths: cam1: source: rtsp://admin:password192.168.1.101:554/streaming/channels/101 cam2: source: rtsp://admin:password192.168.1.102:554/streaming/channels/101也就是说你在外部通过rtsp://本机IP:8554/cam1访问mediamtx会自动去源头地址取流。第二步浏览器播放。因为浏览器不能直接播放RTSP所以要用HLS的地址http://本机IP:888/cam1/index.m3u8。你直接在浏览器里用hls.js、video.js这类库就能播放。但要注意HLS切片会产生1~3秒的延迟如果是远程查看这个延迟可以接受如果要毫秒级实时预览那就得切到WebRTCmediamtx也支持WebRTC接入demo页面在http://本机IP:888/可以直接体验。我实际部署中用mediamtx同时转8路RTSP到WebRTC延迟大概在200到400毫秒画面稳定HTTP端口还能顺手做个简单的视频墙页面。不过要提醒一下HLS切片延迟大如果追求低延迟建议优先用WebRTC同时注意浏览器的连接数限制有的浏览器同时拉太多个WebRTC流也会卡。4.4 多窗口分屏布局怎么控制使用ffplay逐窗口启动的方式默认窗口是平铺层叠的用户体验不太好。你手动拖窗口又很烦。我的办法是用一个小工具Windows下可以用AutoHotkey或者直接用PowerShell脚本按坐标定位窗口。这里给一个简单思路按屏幕宽高计算网格位置然后通过窗口管理器移动窗口。Linux桌面环境下更简单可以用wmctrlwmctrl -r rtsp://admin -e 0,0,0,960,540这个命令效果是把标题包含指定字符串的窗口移动到坐标(0,0)尺寸改成960x540。多路窗口就按网格坐标算出来后循环执行。实际效果虽然比不上专业监控软件的电子墙但调试和临时用已经足够了。5. 常见问题与排查技巧实录5.1 多窗口拉流最常见的6个问题我把从论坛和实际工作中收集到的多窗口拉流问题整理成了一张表你可以直接当速查手册用现象根本原因解决方法窗口画面花屏、马赛克UDP传输丢包加参数-rtsp_transport tcp强制TCP传输延迟越来越大播放器缓冲堆积加-fflags nobuffer -flags low_delay关闭缓存显示“Unauthorized”地址里的用户名密码不对检查摄像头管理页面的账号密码注意特殊字符要URL编码Describes failed设备协议不兼容或路径不对用官方客户端或者ONVIF测试工具先验证地址能否播放窗口开多了CPU占满全部软解加-hwaccel auto或-hwaccel cuda开启硬件解码某一路中途断流设备主动断开或网络抖动脚本里加循环重试重试间隔3~5秒第2个问题是很多人的困惑点明明刚打开的时候一切正常看了一会儿延迟却越来越大看起来像网络问题。实际上大多数情况下是播放器把数据存在内部缓冲区里解码速度跟不上接收速度缓冲区越堆越多。加nobuffer参数后这种问题基本就消失了。第4个问题也很典型。海康的地址我们常用/streaming/channels/101但其他品牌不一定一样比如大华就是/cam/realmonitor?channel1subtype0。建议用工具验证一下。我常用的验证手段是打开VLC按CtrlN输入RTSP地址看能否正常播放。VLC能播说明地址本身没问题VLC都不能播那就是地址或网络的问题先解决这个再说。5.2 硬件解码多窗口不卡的关键多窗口拉流的性能瓶颈往往在解码环节。ffplay默认会用软解也就是CPU解码当同时打开十路1080p的RTSP流CPU基本就要满负荷了。就算机器扛得住画面也会开始掉帧。解决办法是开启硬件解码。注意使用不同硬件平台的参数有差别我给一些常见的方式NVIDIA显卡CUDAffplay -hwaccel cuda -hwaccel_output_format cuda ...Intel核显QSVffplay -hwaccel qsv ...RK3588这类ARM板子海思平台类似ffplay -hwaccel drm ...这条要看你的FFmpeg编译版本是否带对应加速器。官方编译版通常带cuda和qsvARM板子则需要自己编译或找板厂提供的预编译版。我自己在RK3588上调多路摄像头时软解三路就吃力切到硬件解码后轻松同时看八路。如果你的项目是在嵌入式设备上做这条经验非常值得参考。5.3 断流重连与长时间运行多窗口拉流的另一个大坑是长跑稳定性。摄像头设备端出于节能或资源考虑经常在空闲一段时间后主动断掉RTSP会话。还有一些设备路由做了NAT映射一段时间没有流量中间网络设备就会把映射表项踢掉导致RTSP连接中断。ffplay本身没有自动重连功能所以我的做法是在外层脚本里写循环检测到进程退出后自动重启。一个简化版的自动重连脚本while true; do ffplay -fflags nobuffer -flags low_delay \ -rtsp_transport tcp -autoexit \ $url echo 拉流进程退出3秒后重连... sleep 3 done-autoexit的关键作用是当流结束或网络断开时ffplay会自己退出而不是卡在黑窗口假死。脚本检测到进程结束后等待3秒再拉起新进程。这样每路流都有一个守护循环跑几天几夜几乎不会出现画面空缺。脚本写成nohup ./loop_play.sh /dev/null 21 就能在Linux后台跑。5.4 怎么避免端口冲突和认证失败还有一个我经常遇到的问题就是RTSP服务默认端口554与其他服务冲突。比如刚启动mediamtx发现端口被占了然后又发现设备输出的地址里写的却是554。设备是摄像机内嵌的RTSP服务器端口固定554不会因为我们的服务端口变就跟着变。而mediamtx默认用8554反过来又导致从rtsp://本机IP:8554/...取流没问题但如果你把摄像头的地址直接塞给浏览器无论如何都连不上。这种问题排查方法很简单先用本地网络工具验证一下RTSP端口是否通比如Linux下执行nc -zv 192.168.1.101 554如果显示open说明端口可达。然后再去检查认证。设备出厂默认账号密码经常在项目里被人改掉拿默认的admin/12345去连当然失败。更麻烦的是密码里有特殊字符比如、:这种字符在URL里会破坏地址解析。例如一个密码是abc123完整地址写出来是rtsp://admin:abc123192.168.1.13:554/...那这个地址就一定是错的因为会把IP段分割。正确的做法是把密码中的特殊字符做URL编码编码为%40也就是写成admin:abc%40123192.168.1.13。5.5 在线播放器与安防客户端的选择市面上也有不少在线RTSP播放器站点它们解决的其实是同样的问题浏览器不原生支持RTSP。这类在线工具通常提供一个后端服务器帮你把RTSP流转成HLS或HTTP-FLV然后网页端播放。但是要小心两个问题如果摄像头在内网公网部署的在线播放器根本连不上你的RTSP地址如果你把RTSP地址明文交给第三方平台本质上是把视频流交给了外部服务在未授权场景下风险很大。所以我强烈建议涉及内网或隐私场景一定要自建转流服务mediamtx就是非常合适的轻量级选择。至于海康、大华自家的安防客户端如果项目里全是同一品牌的设备那建议直接用它们官方客户端很多功能做得比我上面写的脚本强大很多。但如果是混合品牌设备或者需要在自定义软件里嵌入多路视频那自己搭一套基于RTSP的方案会更灵活也更容易和你现有的业务系统打通。6. 写在最后的几点经验多窗口RTSP拉流本质上不是一个“装个软件就完事”的问题而是一整套工程权衡设备端用什么码流传输层走TCP还是UDP播放端用不用硬解要不要转Web分发每层选型都会影响最终体验。我在实际项目里最常用的组合是内网调试时直接用ffplay脚本多窗口开起来快重启快需要对外分享或者做集中监控时用mediamtx做转流网页端看实时画面。这样一个本地一个远程基本上是性价比最高的组合。最后分享一个小技巧无论你用哪个方案都建议先拿一两条标准RTSP地址做连通性测试确认网络、端口、认证都没问题再开始批量拉流。不要一次性把几十路流都端上来否则一旦出问题你根本分不清是网络瓶颈还是设备认证失败。先把一路调通再逐步加窗口这样排查起来会轻松很多。本文还有配套的精品资源点击获取
返回列表