视频监控RTSP拉流与Token访问控制拆包实战指南

📅 发布时间:2026/9/8 2:29:42
视频监控RTSP拉流与Token访问控制拆包实战指南
简介CameraVideoAC.rar是一份基于Qt框架的摄像头视频录制示例工程适合需要集成QCamera功能的中高级Qt开发者。工程重点演示了双摄像头的检测、切换与同时录制借助QCamera的enumerateDevices方法遍历可用设备可满足多角度拍摄或前后视角同时记录的需求循环录制则通过QMediaRecorder设定时长并监听状态变化实现便于监控、延时摄影等定时分段录像场景。摄像头热插拔场景下程序会动态响应设备连接与断开自动切换或恢复录制。压缩包共54个文件以cpp/h源码、ui界面、pro工程配置为主同时包含bmp/ico/gif/jpg界面素材、qrc资源索引、ts翻译文件及wav提示音目录结构清晰整体仅313KB篇幅紧凑便于研读。已有931人学习适合希望借助完整示例理解Qt多媒体模块、摄像头设备管理与录制状态机的开发者也可作为二次开发的基础框架。 开头先说一句这个CameraVideoAC.rar我拿到手的时候连注释文档都没有文件名也够让人猜半天的。拆开之后才确认这就是一套视频监控项目的“访问控制拉流播放”核心包负责把摄像头 RTSP 流统一接进来再通过 Token 鉴权、临时播放地址、流媒体转发让不同角色的人只能看到自己有权限的通道。我整理这篇内容就是给后面要接手类似包的同事留一份实操手册也给做安防监控、视频接入项目的朋友一个可参考的拆包和落地思路。AC我理解就是 Access Control访问控制。整包解决的核心问题其实很朴素摄像头能力千奇百怪不能把 ONVIF 和 RTSP 地址直接甩给前端也不可能让几十上百路视频流裸奔在内网和公网之间。它适合所有正在做视频中台、安防平台、连锁门店监控整合的人参考。下面我从包结构、访问控制设计、实操部署、问题排查四个维度展开说最后再补几条交付前的经验。1. 这个压缩包里装的到底是什么1.1 一次现场交付的“半成品”——我的拆包经历我拿到CameraVideoAC.rar的时候第一反应是这名字起得太“工程化”了一看就是做交付的人在打包仓促之间顺手写的。真正解压之后里面的文件结构倒是比文件名正式得多整体分成配置、服务、脚本、文档四层典型的视频接入项目交付形态。这里要说一个比较重要的经验.rar格式在 Windows 现场机器上很常见因为现场工程师基本都装了 WinRAR 或 360 压缩随身 U 盘传起来方便。但它到了 Linux 服务器上就有坑尤其是文件名带中文或编码不一致时解压出来全是乱码。所以后面凡是正经做交付的包我建议要么压成.tar.gz要么在包里放一个 UTF-8 编码的 README别让大家先在解压这一步折腾半小时。从包里文件布局来看这是一套相当标准的“鉴权 API 流媒体转发 通道管理”三层结构API 层管登录、签发 Token、校验权限流媒体层负责拉取摄像头的 RTSP 流并转成直播格式通道配置层维护摄像头分组、地址映射、清晰度对应关系。你把它理解成一个小型视频中台也完全没有问题。1.2 核心模块与文件布局说明解压开之后的目录结构没有原样保留下来但根据现场经验这类包通常逃不出下面这张骨架CameraVideoAC/ ├── config/ │ ├── channel_list.conf # 摄像头通道配置通道号、RTSP地址、分组 │ ├── user_policy.json # 用户/角色/通道权限映射 │ └── media_profile.ini # 码率、分辨率、子码流参数 ├── server/ │ ├── auth_server/ # 访问控制服务发放 Token、校验权限 │ └── media_gateway/ # 媒体网关对接 FFmpeg 或流媒体服务 ├── sql/ │ └── init.sql # 初始化用户表、角色表、通道权限表 ├── deploy/ │ ├── install.sh # 一键部署脚本 │ └── nginx_server.conf # 反向代理与 HTTPS 配置模板 ├── docs/ │ └── README.txt └── CameraVideoAC_manual.pdf这里面的核心是user_policy.json和channel_list.conf不是代码文件。因为访问控制的本质是“谁在什么条件下能看哪一路”通道和策略配置才是决定业务能不能转起来的关键。代码只是执行配置的载体很多团队拿到这种包以后只顾着把服务跑起来结果用户、通道、角色之间的关系没有理清楚后面上线排查权限问题的时候会非常痛苦。2. 牵一发动全身的访问控制设计2.1 为什么不能把 RTSP 地址直接给前端早期很多监控项目图省事前端直接拿rtsp://admin:password192.168.1.64:554/Streaming/Channels/101去拉流浏览器里装个 VLC 插件就能看。这样做短平快但问题也很明显一是账号密码全暴露在页面前端代码和浏览器历史记录里等于把摄像头管理员的凭据挂在墙上二是 RTSP 协议在浏览器原生环境里根本不支持现在主流浏览器早就默认禁用了 VLC、Flash 这类插件三是 554 端口一旦暴露到公网摄像头本身就成为突破口。这就是AC层的价值所在所有用户不与摄像头直接对话统一走 API 拿临时播放地址播放地址由后端签名生成限制了有效期、客户端的 IP 范围降级之后即使地址被截图转发过一会儿就会失效。摄像头真正的 RTSP 地址永远只出现在后端配置文件和内网流媒体服务之间前端、第三方、普通管理员都看不到。我实际用下来直接暴露 RTSP 地址的项目几乎都遇到过内部账号被盗用、视频流被第三方播放器拉走的情况。而走了访问控制代理的项目哪怕前端页面被人扒了最多也只是拿到一串 15 分钟就过期的临时播放链接影响面小很多。2.2 Token 签名与临时播放地址的计算思路CameraVideoAC这类包里访问控制的常规做法是 HMAC-SHA256 签名换取一次性播放地址。整个流程大致是用户登录后拿到身份 Token再请求某个通道的播放地址时后端不直接返回播放 URL而是把通道号、用户标识、过期时间等参数拼成一个字符串用服务器私钥做签名最后生成一个带token、exp、sign的 URL。签名逻辑核心代码如下思路比代码本身更重要import hashlib import hmac import time def generate_play_url(user_id, channel_id, secret_key, expire_seconds900): expire int(time.time()) expire_seconds message f{user_id}:{channel_id}:{expire}.encode(utf-8) sign hmac.new(secret_key.encode(utf-8), message, hashlib.sha256).hexdigest() return f/live/{channel_id}?user{user_id}exp{expire}sign{sign}校验的时候服务端拿到exp先看时间是否过期再重新计算签名与 URL 里的sign做比对。注意一点过期时间不能写死得太短我记得有一次现场反馈“画面看半分钟就断”查了半天是 Token 有效期只配了 30 秒。合理的默认值一般取 15 分钟如果是长时间开着的电子地图轮询窗口可以单独使用长时 Token不要一刀切。2.3 几组值得抄下来的容量估算公式做视频访问控制绕不开容量规划。包里的media_profile.ini里可以配置码率但真正要拍板用主码流还是子码流得靠估算。几组我常用的经验公式直接用就行参数计算公式例子单路存储空间每小时GB码率(Mbps) × 3600 ÷ 8 ÷ 10244Mbps 主码流1 小时约 1.76GB单路存储空间每天GB每小时容量 × 244Mbps 码流1 天约 42GB预览占用的下行带宽Mbps码率(Mbps) × 并发预览路数10 路主码流预览约 40Mbps并发播放服务器压力路数服务器可用带宽 ÷ 单路码率千兆内网跑 4Mbps 码流理论约 200 路很多现场只在白天预览晚上录像那主码流可以只用于录像预览全部走子码流通常 512Kbps 到 1Mbps这样 10 路同时预览只占 5-10Mbps带宽压力小很多。这个取舍直接决定你要不要在这个包里额外加一级“自动切码流”的规则。3. 从解压到跑通全链路一次完整实操3.1 环境准备与解压避坑在我建议的交付流程里CameraVideoAC.rar解压只是第一步真正的坑在解压编码。Windows 机器压出来的包文件名往往带 GBK 编码Linux 默认 UTF-8 解压会出现乱码。推荐用unar替代unrar它能自动识别编码sudo apt install unar unar -e gbk CameraVideoAC.rar解压完先不要急着执行任何脚本花五分钟读docs/README.txt和deploy/install.sh。我见过太多人直接./install.sh一路回车最后跑完才发现脚本里写死了服务器内网 IP、数据库密码为默认值、日志路径不存在等问题。正确做法是先把所有变量列出来逐一确认服务器内网口、公网口分别用哪个 IP数据库是本地 MySQL 还是外部实例流媒体服务端口、代理转发端口是否被占用摄像头 RTSP 地址是否已经完成局域网连通性测试。这一步做扎实后面联调才顺利。3.2 接入设备改通道配置而不是改代码包里的channel_list.conf是所有视频接入的“总台账”。每行对应一路摄像头至少要包含通道号、设备名称、RTSP 地址、分组和清晰度档位。我在实际项目里习惯再加一列“启用状态”现场检修时直接改状态位就行不用删行避免后面重新数通道号对不上。[channel_01] name东门岗亭 group门岗组 enabled1 main_streamrtsp://admin:PASSWORD192.168.20.64:554/Streaming/Channels/101 sub_streamrtsp://admin:PASSWORD192.168.20.64:554/Streaming/Channels/102这里必须强调一个非常容易踩的雷main_stream和sub_stream的地址不是随便填的。海康的 RTSP 路径规则比较成熟大华的路径规则跟海康并不完全一致部分设备还有/cam/realmonitor?channel1subtype0这种年代感很强的格式。手册里只写了“填入设备 RTSP 地址”但没有告诉你怎么去设备页面查。实操时直接用 ONVIF Device Manager 或 VLC 逐个验证地址验证通过的才写进配置不要批量粘贴否则后面 50 路里混进 5 条坏地址排查成本极高。3.3 启动鉴权服务和拉流任务初始化数据库后就到了启动环节。sql/init.sql里通常有用户表、角色权限表、通道分组表执行时注意选择正确的库mysql -uac_user -p ac_db sql/init.sql启动顺序有讲究先启动鉴权服务再启动媒体网关。因为媒体网关启动时一般会向鉴权服务注册或拉取通道权限列表。如果反过来网关可能会因为拿不到策略而不断重启。顺序对了再用systemd守护进程systemctl start ac-auth systemctl start ac-media媒体网关内部其实调用了 FFmpeg 做拉流。它的核心行为是把摄像头 RTSP 流转封装成内网可访问的直播流。手动拉流验证一条通道是否正常可以先用 FFmpeg 单独跑ffmpeg -rtsp_transport tcp -i rtsp://admin:PASSWORD192.168.20.64:554/Streaming/Channels/101 -c copy -f flv rtmp://127.0.0.1:1935/live/channel_01这里-rtsp_transport tcp是必须加的参数。很多坑都是 UDP 传输导致的卡顿、花屏和频繁重连具体原因我后面排障部分细说。3.4 前端播放与反向代理配置服务层跑通之后前端播放用 HLS 或 HTTP-FLV 比较常见。浏览器播放 RTSP 不支持所以媒体网关负责转封装。前端拿到带有签名的 URL 后通过 Nginx 反向代理到媒体服务对外只暴露一个 443 端口server { listen 443 ssl; server_name video.example.com; location /live/ { proxy_pass http://127.0.0.1:8080; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; } }这个配置看起来简单但要注意一个细节不要把流媒体服务原端口直接暴露到公网也不要给前端返回媒体服务内网 IP。我接手过的项目里有人为了省事把8080端口映射到公网结果没两天就被扫到了整夜被人拉流消耗带宽。访问控制的最后一公里必须收紧在反向代理这一层。4. 排障实录我在现场踩过的 5 个坑这一个章节基本就是CameraVideoAC在真实环境里最容易炸的几类问题汇总。先看一张问题速查表再逐条讲排查思路现象直接原因解决思路画面卡顿、马赛克RTSP 走 UDP 丢包拉流强制-rtsp_transport tcp播放 30 秒后 401Token 过期时间太短调大expire_seconds或区分短时/长时 Token设备断线后永不恢复FFmpeg 拉流进程僵死加 Supervisor/systemd 自愈定时探活多路并发后权限串流Token 未绑定用户和通道签名参数里强制加入user_id和channel_id日志报错乱码配置文件带 BOM/编码不对统一 UTF-8去掉 BOM核对 Win 换行符4.1 画面卡顿但 CPU 不高问题出在传输协议第一次在现场遇到 20 路视频同时卡顿我还以为是服务器性能不够加了半天配置后来发现 CPU、内存都稳定在 30% 以下。最后抓包才确认是 FFmpeg 默认用 UDP 拉 RTSP局域网稍有拥塞就开始大批量丢包丢包之后画质直接变成马赛克和碎块。解决办法就是把拉流参数里加上-rtsp_transport tcp强制走 TCP。这个改动对大多数监控场景不会有负面效果尤其是有线局域网环境延迟增加可以忽略不计但稳定性提升非常明显。后来我再写拉流脚本、部署流媒体网关这个参数都是标配。4.2 播放器起播到一半被 401有用户在 PC 端播放是好的换成手机 App 播放30 秒到 1 分钟后就弹 401。排查时发现手机和 PC 的时钟源不一样手机时间快了 1 分钟签名的过期时间戳直接提前“过期”。签名校验里用了绝对时间戳对时间同步要求很高。解决方式是给所有服务器和终端统一 NTP 时间同步同时签名校验时加一个“时间漂移容忍窗口”比如 5 分钟。时间同步看着是运维的基本功但在监控项目里常常被忽略尤其是摄像头、服务器、数据库分布在多个网段时时间偏差很容易积累起来。4.3 设备掉线之后拉流进程僵死摄像头临时断电、网线松动恢复之后画面却不回来这是 FFmpeg 类拉流方案最常见的坑。FFmpeg 进程一旦没等到重连信号会无限期卡在重试状态里既不退出也不恢复。必须要有外部探活机制常见做法是用 systemd 或 Supervisor 守护进程定期检查端口和进程状态发现异常就kill重启拉流任务。我自己的经验是与其写复杂的业务健康检查不如自然保护配合简单心跳。每路通道单独拉流进程之间隔离开——一路挂了不影响其他路然后再对每路进程做状态探测探测失败就重启。这是最简单也最可靠的自愈路径。4.4 多路并发后 token 串流现象是 A 用户登录后能看到 B 用户分组里的通道。查了半天数据库权限没问题最后发现问题出在签名 URL 的生成代码里签名字符串只有channel_id和exp没有把user_id放进签名参数。这样只要签名拿到了任何登录用户都能拼出同样的 URL 去播放。修复方式是签名参与计算时强制带上user_id和角色信息服务端校验时还要再比对一次当前登录人与签名字段里的用户是否一致。这个教训说明访问控制必须做“双重校验”签名只证明 URL 没被篡改用户身份比对才能真正挡住串流。4.5 rar 包在 Linux 下乱码和换行符问题这个坑比较隐蔽。现场反馈“shell 脚本执行报错$\r: command not found”定位下来是.rar解压后的脚本是 Windows 换行符\r被当成了命令的一部分。换行符的问题用dos2unix批量解决即可或者干脆统一用 Linux 服务器上的 Git 拉代码避免这类文件污染。另外中文文件名解压乱码建议直接用unar而不是unrar它内置了编码猜测。如果压缩包是打包交付的我更建议压缩时选 ZIP 并勾选 UTF-8或者直接改成 tar.gz相当于提前帮接手的人省掉了编码问题。5. 打完包再交出去之前建议多做三件事5.1 脱敏与凭据回收有一次我得了一个交接包打开channel_list.conf一看所有摄像头密码都是明文而且全是初始密码。这种做法在内部测试网可以真要交付到生产风险非常大。打包交付前至少要做好三件事一是把摄像头管理密码全部改成随机强密码二是把数据库连接密码从配置文件中抽离出来改用环境变量或密钥管理三是在包内附一份“凭据交接清单”列明哪些账号需要上线后重置。我个人的习惯是交接包交付后 24 小时内主动要求对方做一次密码轮换。这不是不信任而是因为同一个压缩包经手的人太多只要中间有一个人把文件传到了群里、U 盘、网盘账号就等于公开了。5.2 统一时区和时间同步访问控制、录像回放、日志审计都依赖准确时间。很多项目的摄像头工艺靠手动校时几个月后时间偏差越来越大结果就是这个包里的签名访问控制会莫名其妙地失效。建议交付前把所有设备和服务器全部设置成同一个时区并加入同一个 NTP 服务器。这件事听起来小但影响面很大。我见过一个项目就因为录像机时间和服务器差了 8 小时回放定位怎么都不对最后排查了两天才发现是最原始的时间同步问题。5.3 交付格式与备份策略最后是交付物本身。CameraVideoAC.rar这种包内容无非是配置、脚本、文档强烈建议同时保留一份.tar.gz版本和解压后的原始目录。打包时把日志目录、临时目录、含密码的调试文件全部排除掉只保留干净的可部署内容。另外无论用哪种压缩格式包里一定要放一个携带校验信息的发布说明比如每个文件的 SHA256 值。这样做不是给自己找麻烦而是为了让接手的人能够确认文件没有被传输过程损坏也避免中间被替换后大家互相扯皮。这也是我认为一个成熟交付包和随手打包交付之间最核心的差别。本文还有配套的精品资源点击获取